diff --git a/backend/controllers/auth.controller.js b/backend/controllers/auth.controller.js
new file mode 100644
index 0000000..ea65de0
--- /dev/null
+++ b/backend/controllers/auth.controller.js
@@ -0,0 +1,87 @@
+import bcrypt from "bcryptjs";
+import User from "../models/user.model.js";
+
+export const signup = async (req, res) => {
+ try {
+ const { name, email, password, mobileNo, role } = req.body;
+
+ //Validators
+ if (password.length < 6) {
+ return res.status(400).json({ error: "Pasword should be atleast 6 characters long" });
+ }
+ if (name.length < 2) {
+ return res.status(400).json({ error: "Name should be atleast 2 characters long" });
+ }
+ if (mobileNo.length != 10) {
+ return res.status(400).json({ error: "Enter a valid Mobile No." });
+ }
+
+ const user = await User.findOne({ email });
+ if (user) {
+ return res.status(400).json({ error: "User with this email already exists. Try logging into your account or signup with another email" });
+ }
+
+ const salt = await bcrypt.genSalt(10);
+ const hashedPassword = await bcrypt.hash(password, salt);
+
+ const newUser = new User({
+ name,
+ email,
+ password: hashedPassword,
+ mobileNo,
+ role,
+ });
+
+ if (newUser) {
+ await newUser.save();
+ return res.status(201).json({
+ _id: newUser._id,
+ name: newUser.name,
+ email: newUser.email,
+ mobileNo: newUser.mobileNo,
+ role: newUser.role
+ });
+ } else {
+ return res.status(400).json({ error: "Invalid User Data" });
+ }
+
+ } catch (error) {
+ console.log("Error in Signup controller", error.message);
+ return res.status(500).json({ error: "Internal Server Error" });
+ }
+}
+
+export const login = async (req, res) => {
+ try {
+ const { email, password } = req.body;
+ const user = await User.findOne({ email });
+ if (!user) {
+ return res.status(400).json({ error: "Cannot find User" });
+ }
+
+ const isPaswordCorrect = await bcrypt.compare(password, user.password || "");
+ if (!isPaswordCorrect) {
+ return res.status(400).json({ error: "Invalid Login Credentials" });
+ }
+
+ res.status(200).json({
+ _id: user._id,
+ name: user.name,
+ email: user.email,
+ mobileNo: user.mobileNo,
+ role: user.role
+ });
+ } catch (error) {
+ console.log("Error in Login controller", error.message);
+ res.status(500).json({ error: "Internal Server Error" });
+ }
+}
+
+export const logout = (req, res) => {
+ try {
+ res.status(200).json({ message: "Logged out Successfully" });
+ } catch (error) {
+ console.log("Error in Logout controller", error.message);
+ res.status(500).json({ error: "Internal Server Error" });
+ }
+}
\ No newline at end of file
diff --git a/backend/db/connectToMongoDB.js b/backend/db/connectToMongoDB.js
new file mode 100644
index 0000000..8299ca3
--- /dev/null
+++ b/backend/db/connectToMongoDB.js
@@ -0,0 +1,12 @@
+import mongoose from "mongoose";
+
+const connectToMongoDB = async () => {
+ try {
+ await mongoose.connect(process.env.MONGODB_URI);
+ console.log("Connected to MongoDB");
+ } catch (error) {
+ console.log("Error in connecting to MongoDB");
+ }
+}
+
+export default connectToMongoDB;
\ No newline at end of file
diff --git a/backend/index.js b/backend/index.js
index b54c8f3..1c73b9f 100644
--- a/backend/index.js
+++ b/backend/index.js
@@ -1,14 +1,47 @@
import express from "express";
import dotenv from "dotenv";
+import bodyParser from "body-parser";
+import morgan from "morgan";
+import helmet from "helmet";
+import cors from "cors";
dotenv.config();
+import connectToMongoDB from "./db/connectToMongoDB.js";
+import authRoutes from "./routes/auth.routes.js";
+
const PORT = process.env.PORT || 5000;
const app = express();
+const corsConfig = {
+ origin: "*",
+ methods: [
+ 'GET',
+ 'POST',
+ 'PATCH',
+ 'DELETE'
+ ],
+ allowHeaders: [
+ 'Content-Type'
+ ],
+ credentials: true
+};
+
+//middlewares
+app.use(express.json());
+app.use(bodyParser.json());
+app.use(bodyParser.urlencoded({ extended: true }));
+app.use(morgan("common"));
+app.use(helmet());
+app.use(helmet.crossOriginResourcePolicy({ policy: "cross-origin" }));
+app.use(cors(corsConfig));
+
app.get("/api/v1", (req, res) => {
res.send("
Test...All Up & Running!
");
});
+app.use("/api/v1/auth", authRoutes);
+
app.listen(PORT, () => {
console.log(`Server Listening on Port ${PORT}`);
+ connectToMongoDB();
});
\ No newline at end of file
diff --git a/backend/models/user.model.js b/backend/models/user.model.js
new file mode 100644
index 0000000..63fb4f5
--- /dev/null
+++ b/backend/models/user.model.js
@@ -0,0 +1,32 @@
+import mongoose from "mongoose";
+
+const userSchema = new mongoose.Schema({
+ name: {
+ type: String,
+ min: 2,
+ required: true
+ },
+ email: {
+ type: String,
+ required: true
+ },
+ password: {
+ type: String,
+ min: 6,
+ required: true
+ },
+ mobileNo: {
+ type: String,
+ max: 10,
+ min: 10,
+ required: true
+ },
+ role: {
+ type: String,
+ enum: ["Coach", "Member", "Parent", "Administrator", "Participant"],
+ required: true
+ }
+}, { timestamps: true });
+
+const User = mongoose.model("User", userSchema);
+export default User;
\ No newline at end of file
diff --git a/backend/package-lock.json b/backend/package-lock.json
index eea05f4..e69d839 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -9,18 +9,41 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
+ "bcryptjs": "^2.4.3",
"body-parser": "^1.20.3",
"cookie-parser": "^1.4.7",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.21.1",
"helmet": "^8.0.0",
+ "mongoose": "^8.8.1",
"morgan": "^1.10.0"
},
"devDependencies": {
"nodemon": "^3.1.7"
}
},
+ "node_modules/@mongodb-js/saslprep": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz",
+ "integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==",
+ "dependencies": {
+ "sparse-bitfield": "^3.0.3"
+ }
+ },
+ "node_modules/@types/webidl-conversions": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
+ "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA=="
+ },
+ "node_modules/@types/whatwg-url": {
+ "version": "11.0.5",
+ "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz",
+ "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==",
+ "dependencies": {
+ "@types/webidl-conversions": "*"
+ }
+ },
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@@ -73,6 +96,11 @@
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
+ "node_modules/bcryptjs": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
+ "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ=="
+ },
"node_modules/binary-extensions": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
@@ -130,6 +158,14 @@
"node": ">=8"
}
},
+ "node_modules/bson": {
+ "version": "6.9.0",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-6.9.0.tgz",
+ "integrity": "sha512-X9hJeyeM0//Fus+0pc5dSUMhhrrmWwQUtdavaQeF3Ta6m69matZkGWV/MrBcnwUeLC8W9kwwc2hfkZgUuCX3Ig==",
+ "engines": {
+ "node": ">=16.20.1"
+ }
+ },
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@@ -644,6 +680,14 @@
"node": ">=0.12.0"
}
},
+ "node_modules/kareem": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz",
+ "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@@ -652,6 +696,11 @@
"node": ">= 0.6"
}
},
+ "node_modules/memory-pager": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
+ "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg=="
+ },
"node_modules/merge-descriptors": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
@@ -710,6 +759,86 @@
"node": "*"
}
},
+ "node_modules/mongodb": {
+ "version": "6.10.0",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.10.0.tgz",
+ "integrity": "sha512-gP9vduuYWb9ZkDM546M+MP2qKVk5ZG2wPF63OvSRuUbqCR+11ZCAE1mOfllhlAG0wcoJY5yDL/rV3OmYEwXIzg==",
+ "dependencies": {
+ "@mongodb-js/saslprep": "^1.1.5",
+ "bson": "^6.7.0",
+ "mongodb-connection-string-url": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16.20.1"
+ },
+ "peerDependencies": {
+ "@aws-sdk/credential-providers": "^3.188.0",
+ "@mongodb-js/zstd": "^1.1.0",
+ "gcp-metadata": "^5.2.0",
+ "kerberos": "^2.0.1",
+ "mongodb-client-encryption": ">=6.0.0 <7",
+ "snappy": "^7.2.2",
+ "socks": "^2.7.1"
+ },
+ "peerDependenciesMeta": {
+ "@aws-sdk/credential-providers": {
+ "optional": true
+ },
+ "@mongodb-js/zstd": {
+ "optional": true
+ },
+ "gcp-metadata": {
+ "optional": true
+ },
+ "kerberos": {
+ "optional": true
+ },
+ "mongodb-client-encryption": {
+ "optional": true
+ },
+ "snappy": {
+ "optional": true
+ },
+ "socks": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/mongodb-connection-string-url": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz",
+ "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==",
+ "dependencies": {
+ "@types/whatwg-url": "^11.0.2",
+ "whatwg-url": "^13.0.0"
+ }
+ },
+ "node_modules/mongoose": {
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.8.1.tgz",
+ "integrity": "sha512-l7DgeY1szT98+EKU8GYnga5WnyatAu+kOQ2VlVX1Mxif6A0Umt0YkSiksCiyGxzx8SPhGe9a53ND1GD4yVDrPA==",
+ "dependencies": {
+ "bson": "^6.7.0",
+ "kareem": "2.6.3",
+ "mongodb": "~6.10.0",
+ "mpath": "0.9.0",
+ "mquery": "5.0.0",
+ "ms": "2.1.3",
+ "sift": "17.1.3"
+ },
+ "engines": {
+ "node": ">=16.20.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mongoose"
+ }
+ },
+ "node_modules/mongoose/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ },
"node_modules/morgan": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
@@ -736,6 +865,46 @@
"node": ">= 0.8"
}
},
+ "node_modules/mpath": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz",
+ "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/mquery": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz",
+ "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==",
+ "dependencies": {
+ "debug": "4.x"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/mquery/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/mquery/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ },
"node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -890,6 +1059,14 @@
"integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
"dev": true
},
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/qs": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
@@ -1062,6 +1239,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/sift": {
+ "version": "17.1.3",
+ "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz",
+ "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ=="
+ },
"node_modules/simple-update-notifier": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
@@ -1074,6 +1256,14 @@
"node": ">=10"
}
},
+ "node_modules/sparse-bitfield": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
+ "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
+ "dependencies": {
+ "memory-pager": "^1.0.2"
+ }
+ },
"node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
@@ -1123,6 +1313,17 @@
"nodetouch": "bin/nodetouch.js"
}
},
+ "node_modules/tr46": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz",
+ "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==",
+ "dependencies": {
+ "punycode": "^2.3.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
@@ -1164,6 +1365,26 @@
"engines": {
"node": ">= 0.8"
}
+ },
+ "node_modules/webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/whatwg-url": {
+ "version": "13.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz",
+ "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==",
+ "dependencies": {
+ "tr46": "^4.1.1",
+ "webidl-conversions": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
}
}
}
diff --git a/backend/package.json b/backend/package.json
index bc94acc..cd0690a 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -11,12 +11,14 @@
"author": "",
"license": "ISC",
"dependencies": {
+ "bcryptjs": "^2.4.3",
"body-parser": "^1.20.3",
"cookie-parser": "^1.4.7",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.21.1",
"helmet": "^8.0.0",
+ "mongoose": "^8.8.1",
"morgan": "^1.10.0"
},
"devDependencies": {
diff --git a/backend/routes/auth.routes.js b/backend/routes/auth.routes.js
new file mode 100644
index 0000000..2920b12
--- /dev/null
+++ b/backend/routes/auth.routes.js
@@ -0,0 +1,10 @@
+import express from "express";
+import { login, logout, signup } from "../controllers/auth.controller.js";
+
+const router = express.Router();
+
+router.post("/signup", signup);
+router.post("/login", login);
+router.post("/logout", logout);
+
+export default router;
\ No newline at end of file