-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 2cd6904
Showing
16 changed files
with
3,975 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/node_modules | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import mongoose from "mongoose"; | ||
|
||
const connectDB = async () => { | ||
try { | ||
const conn = await mongoose.connect(process.env.CONNECTION_URL, { | ||
useNewUrlParser: true, | ||
useUnifiedTopology: true, | ||
}); | ||
console.log(`MongoDB connected: ${conn.connection.host}`); | ||
} catch (error) { | ||
console.error(error); | ||
process.exit(1); | ||
} | ||
}; | ||
|
||
export default connectDB; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import mongoose from "mongoose"; | ||
import Questions from "../models/Questions.js"; | ||
|
||
export const postAnswer = async (req, res) => { | ||
const { id: _id } = req.params; | ||
const { noOfAnswers, answerBody, userAnswered } = req.body; | ||
const userId = req.userId; | ||
if (!mongoose.Types.ObjectId.isValid(_id)) { | ||
return res.status(404).send("question unavailable..."); | ||
} | ||
|
||
updateNoOfQuestions(_id, noOfAnswers); | ||
try { | ||
const updatedQuestion = await Questions.findByIdAndUpdate(_id, { | ||
$addToSet: { answer: [{ answerBody, userAnswered, userId }] }, | ||
}); | ||
res.status(200).json(updatedQuestion); | ||
} catch (error) { | ||
res.status(400).json("error in updating"); | ||
} | ||
}; | ||
|
||
const updateNoOfQuestions = async (_id, noOfAnswers) => { | ||
try { | ||
await Questions.findByIdAndUpdate(_id, { | ||
$set: { noOfAnswers: noOfAnswers }, | ||
}); | ||
} catch (error) { | ||
console.log(error); | ||
} | ||
}; | ||
|
||
export const deleteAnswer = async (req, res) => { | ||
const { id: _id } = req.params; | ||
const { answerId, noOfAnswers } = req.body; | ||
|
||
if (!mongoose.Types.ObjectId.isValid(_id)) { | ||
return res.status(404).send("Question unavailable..."); | ||
} | ||
if (!mongoose.Types.ObjectId.isValid(answerId)) { | ||
return res.status(404).send("Answer unavailable..."); | ||
} | ||
updateNoOfQuestions(_id, noOfAnswers); | ||
try { | ||
await Questions.updateOne( | ||
{ _id }, | ||
{ $pull: { answer: { _id: answerId } } } | ||
); | ||
res.status(200).json({ message: "Successfully deleted..." }); | ||
} catch (error) { | ||
res.status(405).json(error); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import Questions from "../models/Questions.js"; | ||
import mongoose from "mongoose"; | ||
|
||
export const AskQuestion = async (req, res) => { | ||
const postQuestionData = req.body; | ||
const userId = req.userId; | ||
const postQuestion = new Questions({ ...postQuestionData, userId }); | ||
try { | ||
await postQuestion.save(); | ||
res.status(200).json("Posted a question successfully"); | ||
} catch (error) { | ||
console.log(error); | ||
res.status(409).json("Couldn't post a new question"); | ||
} | ||
}; | ||
|
||
export const getAllQuestions = async (req, res) => { | ||
try { | ||
const questionList = await Questions.find().sort({ askedOn: -1 }); | ||
res.status(200).json(questionList); | ||
} catch (error) { | ||
res.status(404).json({ message: error.message }); | ||
} | ||
}; | ||
|
||
export const deleteQuestion = async (req, res) => { | ||
const { id: _id } = req.params; | ||
|
||
if (!mongoose.Types.ObjectId.isValid(_id)) { | ||
return res.status(404).send("question unavailable..."); | ||
} | ||
|
||
try { | ||
await Questions.findByIdAndRemove(_id); | ||
res.status(200).json({ message: "successfully deleted..." }); | ||
} catch (error) { | ||
res.status(404).json({ message: error.message }); | ||
} | ||
}; | ||
|
||
export const voteQuestion = async (req, res) => { | ||
const { id: _id } = req.params; | ||
const { value } = req.body; | ||
const userId = req.userId; | ||
|
||
if (!mongoose.Types.ObjectId.isValid(_id)) { | ||
return res.status(404).send("question unavailable..."); | ||
} | ||
|
||
try { | ||
const question = await Questions.findById(_id); | ||
const upIndex = question.upVote.findIndex((id) => id === String(userId)); | ||
const downIndex = question.downVote.findIndex( | ||
(id) => id === String(userId) | ||
); | ||
|
||
if (value === "upVote") { | ||
if (downIndex !== -1) { | ||
question.downVote = question.downVote.filter( | ||
(id) => id !== String(userId) | ||
); | ||
} | ||
if (upIndex === -1) { | ||
question.upVote.push(userId); | ||
} else { | ||
question.upVote = question.upVote.filter((id) => id !== String(userId)); | ||
} | ||
} else if (value === "downVote") { | ||
if (upIndex !== -1) { | ||
question.upVote = question.upVote.filter((id) => id !== String(userId)); | ||
} | ||
if (downIndex === -1) { | ||
question.downVote.push(userId); | ||
} else { | ||
question.downVote = question.downVote.filter( | ||
(id) => id !== String(userId) | ||
); | ||
} | ||
} | ||
await Questions.findByIdAndUpdate(_id, question); | ||
res.status(200).json({ message: "voted successfully..." }); | ||
} catch (error) { | ||
res.status(404).json({ message: "id not found" }); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import jwt from "jsonwebtoken"; | ||
import bcrypt from "bcryptjs"; | ||
|
||
import users from "../models/auth.js"; | ||
|
||
export const signup = async (req, res) => { | ||
const { name, email, password } = req.body; | ||
try { | ||
const existinguser = await users.findOne({ email }); | ||
if (existinguser) { | ||
return res.status(404).json({ message: "User already Exist." }); | ||
} | ||
|
||
const hashedPassword = await bcrypt.hash(password, 12); | ||
const newUser = await users.create({ | ||
name, | ||
email, | ||
password: hashedPassword, | ||
}); | ||
const token = jwt.sign( | ||
{ email: newUser.email, id: newUser._id }, | ||
process.env.JWT_SECRET, | ||
{ expiresIn: "1h" } | ||
); | ||
res.status(200).json({ result: newUser, token }); | ||
} catch (error) { | ||
res.status(500).json("Something went worng..."); | ||
} | ||
}; | ||
|
||
export const login = async (req, res) => { | ||
const { email, password } = req.body; | ||
try { | ||
const existinguser = await users.findOne({ email }); | ||
if (!existinguser) { | ||
return res.status(404).json({ message: "User don't Exist." }); | ||
} | ||
const isPasswordCrt = await bcrypt.compare(password, existinguser.password); | ||
if (!isPasswordCrt) { | ||
return res.status(400).json({ message: "Invalid credentials" }); | ||
} | ||
const token = jwt.sign( | ||
{ email: existinguser.email, id: existinguser._id }, | ||
process.env.JWT_SECRET, | ||
{ expiresIn: "1h" } | ||
); | ||
res.status(200).json({ result: existinguser, token }); | ||
} catch (error) { | ||
res.status(500).json("Something went worng..."); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import mongoose from "mongoose"; | ||
import users from "../models/auth.js"; | ||
|
||
export const getAllUsers = async (req, res) => { | ||
try { | ||
const allUsers = await users.find(); | ||
const allUserDetails = []; | ||
allUsers.forEach((user) => { | ||
allUserDetails.push({ | ||
_id: user._id, | ||
name: user.name, | ||
about: user.about, | ||
tags: user.tags, | ||
joinedOn: user.joinedOn, | ||
}); | ||
}); | ||
res.status(200).json(allUserDetails); | ||
} catch (error) { | ||
res.status(404).json({ message: error.message }); | ||
} | ||
}; | ||
|
||
export const updateProfile = async (req, res) => { | ||
const { id: _id } = req.params; | ||
const { name, about, tags } = req.body; | ||
|
||
if (!mongoose.Types.ObjectId.isValid(_id)) { | ||
return res.status(404).send("question unavailable..."); | ||
} | ||
|
||
try { | ||
const updatedProfile = await users.findByIdAndUpdate( | ||
_id, | ||
{ $set: { name: name, about: about, tags: tags } }, | ||
{ new: true } | ||
); | ||
res.status(200).json(updatedProfile); | ||
} catch (error) { | ||
res.status(405).json({ message: error.message }); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import express from "express"; | ||
import cors from "cors"; | ||
import dotenv from "dotenv"; | ||
|
||
import userRoutes from "./routes/users.js"; | ||
import questionRoutes from "./routes/Questions.js"; | ||
import answerRoutes from "./routes/Answers.js"; | ||
import connectDB from "./connectMongoDb.js"; | ||
|
||
dotenv.config(); | ||
connectDB(); | ||
const app = express(); | ||
app.use(express.json({ limit: "30mb", extended: true })); | ||
app.use(express.urlencoded({ limit: "30mb", extended: true })); | ||
app.use(cors()); | ||
|
||
// app.use('/',(req, res) => { | ||
// res.send("This is a stack overflow clone API") | ||
// }) | ||
|
||
app.use("/user", userRoutes); | ||
app.use("/questions", questionRoutes); | ||
app.use("/answer", answerRoutes); | ||
|
||
const PORT = process.env.PORT || 5000; | ||
|
||
app.listen(PORT, () => { | ||
console.log(`server running on port ${PORT}`); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import jwt from "jsonwebtoken"; | ||
|
||
const auth = (req, res, next) => { | ||
try { | ||
const token = req.headers.authorization.split(" ")[1]; | ||
|
||
let decodeData = jwt.verify(token, process.env.JWT_SECRET); | ||
req.userId = decodeData?.id; | ||
|
||
next(); | ||
} catch (error) { | ||
console.log(error); | ||
} | ||
}; | ||
|
||
export default auth; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import mongoose from "mongoose"; | ||
|
||
const QuestionSchema = mongoose.Schema({ | ||
questionTitle: { type: String, required: "Question must have a title" }, | ||
questionBody: { type: String, required: "Question must have a body" }, | ||
questionTags: { type: [String], required: "Question must have a tags" }, | ||
noOfAnswers: { type: Number, default: 0 }, | ||
upVote: { type: [String], default: [] }, | ||
downVote: { type: [String], default: [] }, | ||
userPosted: { type: String, required: "Question must have an author" }, | ||
userId: { type: String }, | ||
askedOn: { type: Date, default: Date.now }, | ||
answer: [ | ||
{ | ||
answerBody: String, | ||
userAnswered: String, | ||
userId: String, | ||
answeredOn: { type: Date, default: Date.now }, | ||
}, | ||
], | ||
}); | ||
|
||
export default mongoose.model("Question", QuestionSchema); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import mongoose from "mongoose"; | ||
|
||
const userSchema = mongoose.Schema({ | ||
name: { type: String, required: true }, | ||
email: { type: String, required: true }, | ||
password: { type: String, required: true }, | ||
about: { type: String }, | ||
tags: { type: [String] }, | ||
joinedOn: { type: Date, default: Date.now }, | ||
}); | ||
|
||
export default mongoose.model("User", userSchema); |
Oops, something went wrong.