Eric Whale

Re-Organize folder structure (server)

const asyncHandler = require("express-async-handler");
// @desc Create chatroom
// @route POST /api/chats
// @access Private
const createChatroom = asyncHandler(async (req, res) => {
return;
});
// @desc Delete chatroom
// @route DELETE /api/chats
// @access Private
const delChatroom = asyncHandler(async (req, res) => {
return;
});
module.exports = {
createChatroom,
delChatroom,
};
const mongoose = require("mongoose");
const chatroomSchema = mongoose.Schema(
{
roomName: {
type: String,
required: [true, "Please add chatroom name"],
},
participants: [
{
user: {
type: String,
required: [true, "Please add participants"],
},
},
],
messages: [],
},
{
timestamps: true,
}
);
module.exports = mongoose.model("Chatroom", chatroomSchema);
const express = require("express");
const router = express.Router();
const { createChatroom, delChatroom } = require("../actions/chatroomActions");
const { authHandler } = require("../middleware/authMiddleware");
router.post("/", authHandler, createChatroom);
router.delete("/", authHandler, delChatroom);
// router.post("/message", authHandler, sendMessage);
module.exports = router;
......@@ -11,6 +11,7 @@ app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use("/api/users", require("./routes/userRoutes"));
app.use("/api/chats", require("./routes/chatroomRoutes"));
app.use(errorHandler);
......
MIT License
Copyright (c) 2022 HWANG SUN HYUK
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESSFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
const asyncHandler = require("express-async-handler");
// @desc Create chatroom
// @route POST /api/chats
// @access Private
const createChatroom = asyncHandler(async (req, res) => {
return;
});
// @desc Delete chatroom
// @route DELETE /api/chats
// @access Private
const delChatroom = asyncHandler(async (req, res) => {
return;
});
module.exports = {
createChatroom,
delChatroom,
};
const bcrypt = require("bcryptjs");
// handles "exception" inside of async express routes
const asyncHandler = require("express-async-handler");
const User = require("../models/userModel");
const { jwtGenerator } = require("../config/jwt");
// @desc Signup new user
// @route POST /api/users
// @access Public
const signupUser = asyncHandler(async (req, res) => {
const { username, email, password } = req.body;
if (!username || !email || !password) {
res.status(400);
throw new Error("Please fill in all fields");
}
// Check if user already exists
const userExists = await User.findOne({ email });
if (userExists) {
res.status(400);
throw new Error("User with the email already exists");
}
// Hash password (bcrypt)
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(password, salt);
// Create/Build user
const user = await User.create({
username,
email,
password: hashedPassword,
});
// Send response
if (user) {
// 201: Resource successfully created
res.status(201).json({
_id: user.id,
username: user.username,
email: user.email,
token: jwtGenerator(user._id),
});
} else {
res.status(400);
throw new Error("Invalid user data");
}
});
// @desc Login user
// @route POST /api/users/login
// @access Public
const loginUser = asyncHandler(async (req, res) => {
const { email, password } = req.body;
// Check email & password
const userInDB = await User.findOne({ email });
const validPassword = await bcrypt.compare(password, userInDB.password);
if (userInDB && validPassword) {
res.status(200).json({
_id: userInDB.id,
username: userInDB.username,
email: userInDB.email,
token: jwtGenerator(userInDB._id),
});
} else {
res.status(400);
throw new Error("Invalid credentials");
}
});
// @desc Get all users
// @route GET /api/users/all
// @access Public
const getAllusers = asyncHandler(async (req, res) => {
const users = await User.find()
.select("-password")
.select("-updatedAt")
.select("-createdAt")
.select("-email");
res.status(200).json(users);
});
// @desc Get user
// @route GET /api/users/self
// @access Private
const getSelf = asyncHandler(async (req, res) => {
res.status(200).json(req.user);
});
module.exports = {
signupUser,
loginUser,
getAllusers,
getSelf,
};
const mongoose = require("mongoose");
const colors = require("colors");
const connectDB = async () => {
try {
const conn = await mongoose.connect(process.env.MONGO_URI);
console.log(`MongoDB Connected: ${conn.connection.host}`.cyan.underline);
} catch (error) {
console.log(
`Error occured while connecting to the mongoDB`.magenta.underline
);
console.log(error);
process.exit(1);
}
};
module.exports = connectDB;
const jwt = require("jsonwebtoken");
const jwtGenerator = (id) => {
// https://github.com/auth0/node-jsonwebtoken
const token = jwt.sign({ id }, process.env.JWT_SECRET, {
expiresIn: "2 days",
});
return token;
};
module.exports = { jwtGenerator };
const jwt = require("jsonwebtoken");
const asyncHandler = require("express-async-handler");
const User = require("../models/userModel");
const authHandler = asyncHandler(async (req, res, next) => {
// Check if token exists
if (!req.headers.authorization) {
res.status(401);
throw new Error("Not authorized");
}
// Evaluate the token
const token = req.headers.authorization.split(" ")[1];
const decoded = jwt.verify(
token,
process.env.JWT_SECRET,
function (err, decoded) {
if (err) {
res.status(401);
throw new Error("Not authorized");
}
return decoded;
}
);
const user = await User.findById(decoded.id).select("-password");
req.user = user;
return next();
});
module.exports = { authHandler };
const errorHandler = (err, req, res, next) => {
const statusCode = res.statusCode ? res.statusCode : 500;
res.status(statusCode);
res.json({
message: err.message,
// stack from mongoDB TODO: Check it!
stack: process.env.NODE_ENV === "production" ? null : err.stack,
});
};
module.exports = {
errorHandler,
};
const mongoose = require("mongoose");
const chatSchema = mongoose.Schema({
room: {
type: mongoose.Schema.Types.ObjectId,
require: true,
ref: "Chatroom",
},
conversation: [
{
message: {
type: String,
required: true,
},
},
],
});
module.exports = mongoose.model("Chat", chatSchema);
const mongoose = require("mongoose");
const chatroomSchema = mongoose.Schema(
{
roomName: {
type: String,
required: [true, "Please add chatroom name"],
},
participants: [
{
user: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "User",
},
},
],
},
{
timestamps: true,
}
);
module.exports = mongoose.model("Chatroom", chatroomSchema);
const mongoose = require("mongoose");
const userSchema = mongoose.Schema(
{
username: {
type: String,
required: [true, "Please add a username"],
},
email: {
type: String,
required: [true, "Please add a email"],
},
password: {
type: String,
required: [true, "Please add a password"],
},
},
{
timestamps: true,
}
);
module.exports = mongoose.model("User", userSchema);
This diff could not be displayed because it is too large.
{
"name": "weather_chatbot",
"version": "1.0.0",
"description": "web-app weather chatbot",
"main": "server.js",
"scripts": {
"start": "node server/server.js",
"server": "nodemon server/server.js",
"client": "npm start --prefix ../client",
"dev": "concurrently \"npm run client\" \"npm run server\""
},
"repository": {
"type": "git",
"url": "http://khuhub.khu.ac.kr/2019102244/weather_chatbot.git"
},
"author": "황선혁",
"license": "MIT",
"dependencies": {
"bcryptjs": "^2.4.3",
"colors": "^1.4.0",
"cors": "^2.8.5",
"dotenv": "^16.0.1",
"express": "^4.18.1",
"express-async-handler": "^1.2.0",
"jsonwebtoken": "^8.5.1",
"mongoose": "^6.3.4",
"socket.io": "^4.5.1"
},
"devDependencies": {
"concurrently": "^7.2.1",
"nodemon": "^2.0.16"
}
}
const express = require("express");
const router = express.Router();
const { createChatroom, delChatroom } = require("../actions/chatroomActions");
const { authHandler } = require("../middleware/authMiddleware");
// "/api/rooms/"
router.post("/", authHandler, createChatroom);
router.delete("/", authHandler, delChatroom);
// router.post("/message", authHandler, sendMessage);
module.exports = router;
const express = require("express");
const router = express.Router();
const {
signupUser,
loginUser,
getAllusers,
getSelf,
} = require("../actions/userActions");
const { authHandler } = require("../middleware/authMiddleware");
// "/api/users/"
router.post("/", signupUser);
router.post("/login", loginUser);
router.get("/all", getAllusers);
router.get("/self", authHandler, getSelf);
module.exports = router;
const express = require("express");
const dotenv = require("dotenv").config();
const { errorHandler } = require("./middleware/errorMiddleware");
const { createServer } = require("http");
const { Server } = require("socket.io");
const cors = require("cors");
const connectDB = require("./config/db");
const port = process.env.PORT || 8080;
connectDB();
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use("/api/users", require("./routes/userRoutes"));
app.use("/api/rooms", require("./routes/chatroomRoutes"));
// chatbot
app.use(cors());
const httpServer = createServer(app);
const io = new Server(httpServer, {
cors: {
origin: "http://localhost:3000/",
methods: ["GET", "POST"],
},
});
io.on("connection", (socket) => {
console.log(`User Connected: ${socket.id}`);
socket.on("join_room", (data) => {
socket.join(data);
});
socket.on("send_message", (data) => {
socket.to(data.room).emit("receive_message", data);
});
});
app.use(errorHandler);
app.listen(port, () => {
console.log(`Server started on port ${port}`);
});