backend integration

This commit is contained in:
Moon Patel
2023-06-27 15:44:29 +05:30
parent 8edd05e020
commit b3fd3ade5c
11 changed files with 1504 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
node_modules
.env
+65
View File
@@ -0,0 +1,65 @@
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const authRoutes = require("./routes/auth");
const mongoose = require("mongoose");
mongoose
.connect("mongodb://127.0.0.1:27017/test")
.then((res) => console.log("Connected to MongoDB"))
.catch((err) => console.log("Error in connecting to database"));
const app = express();
const http = require("http");
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server, { cors: { origin: "*" } });
io.on("connection", (socket) => {
// console.log("Connected: ", socket.data);
socket.broadcast.emit("game", "emitting...");
socket.emit("game", "Welcome");
socket.on("join-room", async (data) => {
if (data?.roomid) await socket.join(roomid);
else socket.emit("error", "Room id not received");
});
socket.on("play", (data) => {
console.log(data)
let { fromRow, fromCol, toRow, toCol, room } = data;
fromRow = 7 - fromRow;
fromCol = 7 - fromCol;
toRow = 7 - toRow;
toCol = 7 - toCol;
socket.to(room).emit("play", { fromCol, fromRow, toCol, toRow });
socket.broadcast.emit("play", { fromCol, fromRow, toCol, toRow });
});
});
app.use(cors({ origin: "*" }));
app.use(bodyParser.json());
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "GET,POST,PATCH,DELETE");
res.setHeader("Access-Control-Allow-Headers", "Content-Type,Authorization");
next();
});
app.use((req, res, next) => {
console.log(req.url);
next();
});
// app.use("/", (req, res, next) => res.send('Hello'));
app.use("/api/auth", authRoutes);
app.use((error, req, res, next) => {
const status = error.status || 500;
const message = error.message || "Something went wrong.";
res.status(status).json({ message: message });
});
server.listen(8080, () => {
console.log("Listening on server 8080");
});
+1
View File
@@ -0,0 +1 @@
{"events":[{"title":"new event","image":"https://images.squarespace-cdn.com/content/v1/56d082a760b5e95c074d11a0/8ce30633-23f2-4dc9-b301-c251cbf26d02/Mercedes+Benz+Oscar+Party?format=2500w","date":"2023-05-03","description":"hello","id":"1f24eb47-5019-4a07-9c3c-1ba18b591800"},{"title":"concert","image":"https://business.twitter.com/content/dam/business-twitter/insights/may-2018/event-targeting.png.twimg.1920.png","date":"2023-05-04","description":"lorem","id":"2035d991-0e72-456c-b6df-1aa9774caaaa"}],"users":[{"email":"m@g.com","password":"$2a$12$.GW99UfbOfISG6mQHN.8MOXtYXePsWH592XudNWU9Df9tYEV.K.QG","id":"2a744c6d-da1a-4938-ab45-144b567d5187"},{"email":"moon@gmails.com","password":"$2a$12$o7p.OS1vA66yBlkOsh.xV.ifDsItbSeBOTaN5VgjYHIUVtDvP3nbu","id":"8f394056-592e-45fc-9808-e923e1a1d60a"},{"email":"moon@gmail.com","password":"$2a$12$3t8sENEvXNvC1XeKhMsJFOsaU0vVh27wnY4hHIPlXzzOIAwMiSSJC","id":"421e3728-ac58-4fc1-86d5-70b618d01f9b"},{"email":"moonpatel2003@gmail.com","password":"$2a$12$QxG6hh0vFudhlsX3MJvXLuVfnFKBAPd15Bei42MNB2v69BwwGT3oq","id":"d77a0a0b-2b82-489e-9782-ccac490db36d"}]}
+40
View File
@@ -0,0 +1,40 @@
const { Schema, default: mongoose } = require("mongoose");
const { String, ObjectId } = Schema.Types;
const userSchema = new Schema(
{
username: {
type: String,
unique: true,
required: true,
},
email: {
type: String,
unique: true,
required: true,
},
password_hash: {
type: String,
required: true,
},
fname: String,
lname: String,
location: String,
country: String,
friends: {
type: [ObjectId],
ref: "User",
},
},
{
virtuals: {
fullName: {
get() {
return this.fname + " " + this.lname;
},
},
},
}
);
module.exports.User = mongoose.model("User", userSchema);
+1203
View File
File diff suppressed because it is too large Load Diff
+23
View File
@@ -0,0 +1,23 @@
{
"name": "backend-api",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node app.js",
"dev": "nodemon app.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"bcryptjs": "^2.4.3",
"body-parser": "^1.20.2",
"cors": "^2.8.5",
"express": "^4.18.2",
"jsonwebtoken": "^8.5.1",
"mongoose": "^7.2.1",
"socket.io": "^4.6.1",
"uuid": "^9.0.0"
}
}
+79
View File
@@ -0,0 +1,79 @@
const express = require("express");
const { createJSONToken, isValidPassword, validateJSONToken, generatePasswordHash } = require("../util/auth");
const { isValidEmail, isValidText } = require("../util/validation");
const { User } = require("../models/user");
const router = express.Router();
router.post("/signup", async (req, res, next) => {
console.log(req.body);
const data = { email: req.body.email, password: req.body.password, username: req.body.username };
let errors = {};
if (!isValidEmail(data.email)) {
errors.email = "Invalid email.";
} else {
try {
let user = await User.findOne({ email: data.email });
if (user) {
errors.email = "Email exists already.";
}
} catch (error) {
throw error;
}
}
if (!isValidText(data.password, 6)) {
errors.password = "Password must be at least 6 characters long.";
}
let user = await User.findOne({ username: data.username });
if (user) errors.username = "Username already exists";
if (Object.keys(errors).length > 0) {
return res.status(422).json({
message: "User signup failed due to validation errors.",
errors,
});
}
try {
let userData = {
email: data.email,
username: data.username,
password_hash: await generatePasswordHash(data.password),
};
userDoc = new User(userData);
await userDoc.save();
const authToken = createJSONToken(userDoc.id);
res.status(201).json({ message: "User created.", user: userDoc, token: authToken });
} catch (error) {
next(error);
}
});
router.post("/login", async (req, res) => {
const username = req.body.username;
const password = req.body.password;
let user;
try {
user = await User.findOne({ username });
if (!user) return res.status(401).json({ message: "User not found" });
} catch (error) {
return res.status(401).json({ message: "AutheFntication failed." });
}
const pwIsValid = await isValidPassword(password, user.password_hash);
if (!pwIsValid) {
return res.status(422).json({
message: "Invalid credentials.",
errors: { credentials: "Invalid email or password entered." },
});
}
const token = createJSONToken(user.id);
return res.json({ token });
});
module.exports = router;
+1
View File
@@ -0,0 +1 @@
const express = require("express").Router();
+53
View File
@@ -0,0 +1,53 @@
const { sign, verify } = require("jsonwebtoken");
const { compare, hash, genSalt } = require("bcryptjs");
const { NotAuthError } = require("./errors");
const KEY = "supersecret";
async function generatePasswordHash(password) {
const password_hash = await hash(password, await genSalt(10));
return password_hash;
}
function createJSONToken(email) {
return sign({ email }, KEY, { expiresIn: "1h" });
}
function validateJSONToken(token) {
return verify(token, KEY);
}
function isValidPassword(password, storedPassword) {
return compare(password, storedPassword);
}
function checkAuthMiddleware(req, res, next) {
if (req.method === "OPTIONS") {
return next();
}
if (!req.headers.authorization) {
console.log("NOT AUTH. AUTH HEADER MISSING.");
return next(new NotAuthError("Not authenticated."));
}
const authFragments = req.headers.authorization.split(" ");
if (authFragments.length !== 2) {
console.log("NOT AUTH. AUTH HEADER INVALID.");
return next(new NotAuthError("Not authenticated."));
}
const authToken = authFragments[1];
try {
const validatedToken = validateJSONToken(authToken);
req.token = validatedToken;
} catch (error) {
console.log("NOT AUTH. TOKEN INVALID.");
return next(new NotAuthError("Not authenticated."));
}
next();
}
exports.createJSONToken = createJSONToken;
exports.validateJSONToken = validateJSONToken;
exports.isValidPassword = isValidPassword;
exports.checkAuth = checkAuthMiddleware;
exports.generatePasswordHash = generatePasswordHash;
+16
View File
@@ -0,0 +1,16 @@
class NotFoundError {
constructor(message) {
this.message = message;
this.status = 404;
}
}
class NotAuthError {
constructor(message) {
this.message = message;
this.status = 401;
}
}
exports.NotFoundError = NotFoundError;
exports.NotAuthError = NotAuthError;
+21
View File
@@ -0,0 +1,21 @@
function isValidText(value, minLength = 1) {
return value && value.trim().length >= minLength;
}
function isValidDate(value) {
const date = new Date(value);
return value && date !== 'Invalid Date';
}
function isValidImageUrl(value) {
return value && value.startsWith('http');
}
function isValidEmail(value) {
return value && value.includes('@');
}
exports.isValidText = isValidText;
exports.isValidDate = isValidDate;
exports.isValidImageUrl = isValidImageUrl;
exports.isValidEmail = isValidEmail;