Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upvote and Downvotes fixed #1093

Merged
merged 1 commit into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions backend/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,20 @@
// Set security headers
app.use(helmet());

// cookie
app.use(cookieParser());

Check failure

Code scanning / CodeQL

Missing CSRF middleware High

This cookie middleware is serving a
request handler
without CSRF protection.
This cookie middleware is serving a
request handler
without CSRF protection.
This cookie middleware is serving a request handler without CSRF protection.
This cookie middleware is serving a request handler without CSRF protection.

// CORS
app.use(cors());
// app.use(cors());
app.use(cors({credentials:true,origin:process.env.FRONTEND_URL}));

app.use(function(req, res, next) {
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Origin', process.env.FRONTEND_URL);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,UPDATE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
next();
});

// Body Parser
app.use(express.json({ limit: '50mb' }));
Expand All @@ -25,8 +37,6 @@
// Response time
app.use(responseTime({ suffix: false }));

// cookie
app.use(cookieParser());

// Use routes
app.use('/', routes);
Expand Down
4 changes: 4 additions & 0 deletions backend/app/models/question.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ const questionSchema = new Schema(
type: Number,
default: 0,
},
downvotes:{
type:Number,
default:0
}
},
{ timestamps: { createdAt: 'createdAt', updatedAt: 'updatedAt' } }
);
Expand Down
26 changes: 6 additions & 20 deletions backend/app/routes/Q&A/question/downvoteQuestion.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,11 @@

module.exports = async (req, res, next) => {
const { questionId } = req.body;
const [err] = await to(
question.updateOne({ _id: questionId }, [
{
$set: {
upvotes: {
$cond: [
{
$gt: ['$upvotes', 0],
},
{
$subtract: ['$upvotes', 1],
},
0,
],
},
},
},
])
);
const existingQues=await question.findById(questionId)

Check failure

Code scanning / CodeQL

Database query built from user-controlled sources High

This query object depends on a
user-provided value
.
if(!existingQues.downvotes){
const [err] = await to(question.updateOne({ _id: questionId },{$set:{downvotes:0}}));

Check failure

Code scanning / CodeQL

Database query built from user-controlled sources High

This query object depends on a
user-provided value
.
}
const [err] = await to(question.updateOne({ _id: questionId }, { $inc: { downvotes: 1 } }));

Check failure

Code scanning / CodeQL

Database query built from user-controlled sources High

This query object depends on a
user-provided value
.
if (err) {
console.log(err);
const error = new ErrorHandler(constants.ERRORS.DATABASE, {
Expand All @@ -36,7 +22,7 @@
return next(error);
}

res.cookie(getVoteCookieName('question', questionId), true, { maxAge: 20 * 365 * 24 * 60 * 60 * 1000 });
res.cookie(getVoteCookieName('question', questionId), true, { maxAge: 20 * 365 * 24 * 60 * 60 * 1000, sameSite: "none", secure: true });
res.status(200).send({
message: 'Question has been down voted',
});
Expand Down
2 changes: 1 addition & 1 deletion backend/app/routes/Q&A/question/upvoteQuestion.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module.exports = async (req, res, next) => {
return next(error);
}

res.cookie(getVoteCookieName('question', questionId), true, { maxAge: 20 * 365 * 24 * 60 * 60 * 1000 });
res.cookie(getVoteCookieName('question', questionId), true, { maxAge: 20 * 365 * 24 * 60 * 60 * 1000,sameSite:"none",secure:true });

res.status(200).send({
message: 'Question has been upvoted',
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/Q&A/Q&A.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ function Ques(props) {
className="vote-btn"
onClick={() => handleDownvote(item._id)}
>
👎 {item?.downvote}
👎 {item?.downvotes}
</button>
</div>
</div>
Expand Down
210 changes: 106 additions & 104 deletions frontend/src/service/Faq.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,127 +2,127 @@ import { END_POINT } from "../config/api";
import { showToast } from "./toastService";

export async function postFaq(formData, setToast, toast) {
try {
const response = await fetch(`${END_POINT}/faq/postFaq`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
body: JSON.stringify(formData),
try {
const response = await fetch(`${END_POINT}/faq/postFaq`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
body: JSON.stringify(formData),
});

if (response.ok) {
setToast({
...toast,
toastMessage: "FAQ has been added",
toastStatus: true,
toastType: "success",
});

if (response.ok) {
setToast({
...toast,
toastMessage: "FAQ has been added",
toastStatus: true,
toastType: "success",
});
return { success: true };
} else {
setToast({
...toast,
toastMessage: "Database Error",
toastStatus: true,
toastType: "error",
});
return { success: false, error: "Database Error" };
}
} catch (error) {
return { success: true };
} else {
setToast({
...toast,
toastMessage: "Network Error",
toastMessage: "Database Error",
toastStatus: true,
toastType: "error",
});
return { success: false, error: "Network Error" };
return { success: false, error: "Database Error" };
}
} catch (error) {
setToast({
...toast,
toastMessage: "Network Error",
toastStatus: true,
toastType: "error",
});
return { success: false, error: "Network Error" };
}
}

export async function getFaq() {
try {
const response = await fetch(`${END_POINT}/faq/getFaq`);
if (!response.ok) {
throw new Error("Failed to fetch FAQs");
}
const data = await response.json();
return data.Faq;
} catch (error) {
console.error("Failed to fetch FAQs:", error.message);
try {
const response = await fetch(`${END_POINT}/faq/getFaq`);
if (!response.ok) {
throw new Error("Failed to fetch FAQs");
}
const data = await response.json();
return data.Faq;
} catch (error) {
console.error("Failed to fetch FAQs:", error.message);
throw new Error("Failed to fetch FAQs");
}
}

export const deleteFaq = async (faqId, setToast, toast) => {
const url = `${END_POINT}/faq/deleteFaq`;
const body = { faqId: faqId };
const headers = {
"Content-Type": "application/json",
authorization: `Bearer ${localStorage.getItem("token")}`,
};
try {
const response = await fetch(url, {
method: "PUT",
headers: headers,
body: JSON.stringify(body),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
setToast({
...toast,
toastMessage: data.message,
toastStatus: true,
toastType: "success",
});
return data.message;
} catch (error) {
console.error("Failed to delete FAQ:", error.message);
setToast({
...toast,
toastMessage: "Failed to delete FAQ",
toastStatus: true,
toastType: "error",
});
throw new Error("Failed to delete FAQ");
export const deleteFaq = async (faqId, setToast, toast) => {
const url = `${END_POINT}/faq/deleteFaq`;
const body = { faqId: faqId };
const headers = {
"Content-Type": "application/json",
authorization: `Bearer ${localStorage.getItem("token")}`,
};
try {
const response = await fetch(url, {
method: "PUT",
headers: headers,
body: JSON.stringify(body),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
setToast({
...toast,
toastMessage: data.message,
toastStatus: true,
toastType: "success",
});
return data.message;
} catch (error) {
console.error("Failed to delete FAQ:", error.message);
setToast({
...toast,
toastMessage: "Failed to delete FAQ",
toastStatus: true,
toastType: "error",
});
throw new Error("Failed to delete FAQ");
}
};

export const updateFaq = async (faqId, updatedFaqDetails, setToast, toast) => {
try {
const response = await fetch(`${END_POINT}/faq/updateFaq`, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
authorization: `Bearer ${localStorage.getItem("token")}`,
},
body: JSON.stringify({ faqId, ...updatedFaqDetails }),
});

if (!response.ok) {
throw new Error("Failed to update FAQ");
}
try {
const response = await fetch(`${END_POINT}/faq/updateFaq`, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
authorization: `Bearer ${localStorage.getItem("token")}`,
},
body: JSON.stringify({ faqId, ...updatedFaqDetails }),
});

const data = await response.json();
setToast({
...toast,
toastMessage: data.message,
toastStatus: true,
toastType: "success",
});
return data.message;
} catch (error) {
console.error("Failed to update FAQ:", error.message);
setToast({
...toast,
toastMessage: "Failed to update FAQ",
toastStatus: true,
toastType: "error",
});
throw new Error("Failed to update FAQ");
if (!response.ok) {
throw new Error("Failed to update FAQ");
}

const data = await response.json();
setToast({
...toast,
toastMessage: data.message,
toastStatus: true,
toastType: "success",
});
return data.message;
} catch (error) {
console.error("Failed to update FAQ:", error.message);
setToast({
...toast,
toastMessage: "Failed to update FAQ",
toastStatus: true,
toastType: "error",
});
throw new Error("Failed to update FAQ");
}
};

export const getAllQuestions = async (setToast, toast) => {
Expand Down Expand Up @@ -292,6 +292,7 @@ export const upvote = async (questionId, handleToast) => {
headers: {
"Content-Type": "application/json",
},
credentials: "include",
body: JSON.stringify({ questionId }),
});
if (!response.ok) {
Expand All @@ -300,7 +301,7 @@ export const upvote = async (questionId, handleToast) => {
showToast(handleToast, "Upvote Successfully");
return response.json();
} catch (error) {
showToast(handleToast, "Failed to upvote question", "error");
showToast(handleToast, "You have already voted", "error");
throw new Error("Failed to upvote question");
}
};
Expand All @@ -312,6 +313,7 @@ export const downvote = async (questionId, handleToast) => {
headers: {
"Content-Type": "application/json",
},
credentials: "include",
body: JSON.stringify({ questionId }),
});
if (!response.ok) {
Expand All @@ -320,7 +322,7 @@ export const downvote = async (questionId, handleToast) => {
showToast(handleToast, "Downvote Successfully");
return response.json();
} catch (error) {
showToast(handleToast, "Failed to downvote question", "error");
showToast(handleToast, "You have already voted", "error");
throw new Error("Failed to downvote question");
}
};
};
Loading