Skip to content

Instantly share code, notes, and snippets.

@OkoliEvans
Created October 28, 2024 00:00
Show Gist options
  • Save OkoliEvans/68f955e744866107e6964aebb5cb002d to your computer and use it in GitHub Desktop.
Save OkoliEvans/68f955e744866107e6964aebb5cb002d to your computer and use it in GitHub Desktop.
const express = require("express");
const helmet = require("helmet");
const cors = require("cors");
const path = require("path");
require('dotenv').config();
let clientUrl = process.env.CLIENT_URL || 'http://localhost:3000';
const app = express();
app.use(helmet());
let corsOptions = {
origin: clientUrl,
}
app.use(cors(corsOptions));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, "public")));
app.use("/api/v1/auth", require("./Routes/auth.route"));
app.use("/api/v1", require("./Auth/routes.auth"));
app.use((error, req, res, next) => {
const statusCode = error.status || 500;
console.log(error);
res.status(statusCode).json({ error: error.message });
});
module.exports = app;
const crypto = require("crypto");
const bcrypt = require("bcrypt");
const User = require("../Models/user.mongo");
const Token = require("../Models/token.mongo");
const validator = require("email-validator"); // for email validation
const passwordValidator = require("password-validator");
const LocalStrategy = require("passport-local").Strategy;
require("dotenv").config();
const bcryptSaltRounds = parseInt(process.env.BCRYPT_SALT) || 10;
const tokenExpiryTime = 15 * 60 * 1000; // 15 minutes for password reset token
let schema = new passwordValidator();
//define the password schema
schema
.is()
.min(8)
.is()
.max(62)
.has()
.uppercase()
.has()
.lowercase()
.has()
.digits(1)
.has()
.not()
.spaces()
.is()
.not()
.oneOf(["password", "Password", "password123", "Password123"]);
module.exports = function (passport) {
passport.use(
new LocalStrategy(
{ usernameField: "email" },
async (email, password, done) => {
try {
// validate email
const isValid = validator.validate(email);
if (!isValid) {
console.log('email not validated');
return done(null, false, {
message: "Invalid email, please try again",
});
}
//validate password
let validatedPassword = schema.validate(password);
if (!validatedPassword) {
console.log('password not validated');
return done(null, false, {
message: "Invalid password, please try again",
});
}
//match user
let user = await User.findOne({ email });
if (!user) {
return done(null, false, { message: "Email not registered" });
}
// compare password using bcrypt
const isValidPassword = await bcrypt.compare(
password,
user.password
);
console.log('password validated?', isValidPassword);
if (!isValidPassword) {
return done(null, false, {
message: "Incorrect password, please try again",
});
}
// generate a new token and encrypt
let token = crypto.randomBytes(32).toString("hex");
const tokenHash = await bcrypt.hash(token, bcryptSaltRounds);
await new Token({
userId: user._id,
token: tokenHash,
createdAt: Date.now(),
expiresAt: Date.now() + tokenExpiryTime,
}).save();
return done(null, user);
} catch (err) {
console.log('login error', err);
return done(null, false, { message: "Login failed" });
}
}
)
);
passport.serializeUser((user, done) => {
done(null, user._id);
});
passport.deserializeUser(async (_id, done) => {
try {
const user = await User.findById({ _id });
done(null, user);
} catch (err) {
done(err, null);
}
});
};
const express = require("express");
const passport = require("passport");
const { sendOTP } = require("../Controllers/sendOTP.controller");
const { ensureAuthenticated } = require("./authenticate");
const router = express.Router();
// Google OAUTH routes
router.get(
"/google",
passport.authenticate("google", {
scope: ["email"],
})
);
router.get(
"/google/callback",
passport.authenticate("google", {
failureRedirect: "api/v1/user/login",
successRedirect: "/",
}),
(req, res) => {
console.log("Google OAUTH callback");
}
);
// In your route handler for login
router.post("/user/login", (req, res, next) => {
passport.authenticate("local", async (err, user, info) => {
if (err) {
console.log(err);
return next(err);
}
if (!user) return res.status(401).json(info);
req.login(user, async (err) => {
console.log("user logged in:", user);
if (err) return next(err);
// Send OTP after successful login
await sendOTP(req, res, user.email);
});
})(req, res, next);
});
/*
router.post(
"/login",
passport.authenticate("local", { failureRedirect: "/user/login" }),
(req, res) => {
console.log("user", req.body);
if (err) return next(err);
if (!user) return res.redirect("/user/login");
// Establish session
req.logIn(user, (err) => {
if (err) return next(err);
// Set session variables
req.session.user = { email: user.email, isLoggedIn: true };
console.log("Session ID:", req.sessionID);
req.session.save((err) => {
if (err) {
console.error("Error saving session:", err);
return res.status(500).json({ message: "Failed to save session" });
}
console.log("Session saved successfully.");
});
res.redirect("/");
res.json({
status: 200,
success: true,
message: "Login successful",
redirectTo: "/verifyOTP",
});
});
}
)(req, res, next);
}); */
router.get("/test", (req, res) => {
res.send("Login GET route working");
});
// local users route
// router.post("/login", async (req, res, next) => {
// passport.authenticate("local", {
// failureRedirect: "/login",
// }),(req, res) => {
// res.redirect('/auth/verifyOTP');
// }, (req, res, next);
// });
/*
router.get("/logout", (req, res, next) => {
req
.logout()
.then(() => res.redirect("/"))
.catch((err) => next(err));
}); */
router.post("/logout", (req, res, next) => {
if (req.session) {
req.session.destroy((err) => {
console.log(passport.session);
if (err) return next(err);
res.clearCookie("connect.sid"); // Clear the session cookie
req.logout((err) => {
if (err) return next(err);
});
res.redirect("/"); // Redirect after logout
});
} else {
return res.status(500).json({ message: 'no session'});
}
});
module.exports = router;
const fs = require("fs");
const path = require("path");
const app = require("./app");
const https = require("https");
const passport = require('passport');
const cookieParser = require('cookie-parser');
const authRoutes = require("./Auth/routes.auth");
const { mongoConnect } = require('./Services/mongo');
const session = require("express-session");
const MongoStore = require('connect-mongo');
// let router = require('express').Router();
require('./Auth/google.auth')(passport); // to load google oauth strategy
require('./Auth/local.auth')(passport); // to load local users strategy
require("dotenv").config();
require("express-async-errors");
const PORT = process.env.PORT || 3000;
const MONGO_URL = process.env.MONGO_DB_URL;
app.use(cookieParser());
app.use(session({
secret: process.env.JWT_SECRET || 'secret',
resave: false,
saveUninitialized: false,
// store: MongoStore.create({
// mongoUrl: MONGO_URL,
// collectionName: "sessions",
// ttl: 60 * 60 * 12,
// }),
cookie: {
httpOnly: true,
maxAge: 60 * 60 * 12 * 1000,
secure: false,
}
}));
app.use(passport.initialize());
app.use(passport.session());
// app.use(express.static(path.join(__dirname, "public")));
app.use("/user", authRoutes);
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "public", "index.html"), (err) => {
if (err) {
console.log("Error serving file", err);
res.status(500).send("Error serving file");
}
});
});
const server = https.createServer(
{
// key: fs.readFileSync("key.pem"),
// cert: fs.readFileSync("cert.pem"),
},
app
);
async function startServer() {
await mongoConnect();
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}...`);
});
}
startServer();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment