backend integration
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
.env
|
||||
@@ -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");
|
||||
});
|
||||
@@ -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"}]}
|
||||
@@ -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);
|
||||
Generated
+1203
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -0,0 +1 @@
|
||||
const express = require("express").Router();
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
Reference in New Issue
Block a user