Skip to content

Commit df7bad0

Browse files
committed
fix and migrating
0 parents  commit df7bad0

File tree

13 files changed

+2580
-0
lines changed

13 files changed

+2580
-0
lines changed

Diff for: server/.env.sample

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ACCESS_TOKEN_SECRET=
2+
CLIENT_ID=
3+
CLIENT_SECRET=
4+
PORT=
5+
MONGODB=

Diff for: server/.gitignore

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
.env
6+
7+
# production
8+
/build
9+
10+
# misc
11+
.DS_Store
12+
.env.local
13+
.env.development.local
14+
.env.test.local
15+
.env.production.local
16+
17+
npm-debug.log*
18+
yarn-debug.log*
19+
yarn-error.log*

Diff for: server/README.md

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Backend-Code-editor
2+
3+
## use postman
4+
### Login & Signup
5+
- (POST) https://backendcodecompiler.onrender.com/api/auth/login
6+
- { email, password}
7+
- (POST) https://backendcodecompiler.onrender.com/api/auth/signup
8+
- {name, email, password}
9+
10+
### Get all solution (Get, post, put, delete)
11+
- (GET) https://backendcodecompiler.onrender.com/api/
12+
- (POST) https://backendcodecompiler.onrender.com/api/
13+
- (GET) https://backendcodecompiler.onrender.com/api/:ID
14+
- (PUT) https://backendcodecompiler.onrender.com/api/:ID
15+
- (DELETE) https://backendcodecompiler.onrender.com/api/:ID
16+
17+
### Submit a solution
18+
- (POST) https://backendcodecompiler.onrender.com/api/solution/:ID
19+
20+
21+
![image](https://github.com/luckych8080/Backend-Code-editor/assets/76004920/c0f9b29a-a4ee-4177-b0b8-fcabfc6e44d9)

Diff for: server/controllers/questions.js

+176
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
require("dotenv").config();
2+
const Question = require("../models/Question");
3+
const axios = require("axios");
4+
5+
// Get all Questions
6+
const getQuestions = async (req, res) => {
7+
try {
8+
const questions = await Question.find();
9+
res.status(200).json({ questions });
10+
} catch (error) {
11+
console.log(error);
12+
res.status(500).json({ message: "Internal server error" });
13+
}
14+
};
15+
16+
// Add a Question
17+
const addQuestion = async (req, res) => {
18+
try {
19+
const body = req.body;
20+
21+
const question = new Question({
22+
title: body.title,
23+
description: body.description,
24+
testCases: body.testCases,
25+
createdBy: req.user.userId,
26+
});
27+
28+
const newQuestion = await question.save();
29+
const allQuestions = await Question.find();
30+
31+
res.status(201).json({
32+
message: "Question added",
33+
question: newQuestion,
34+
questions: allQuestions,
35+
});
36+
} catch (error) {
37+
console.log(error);
38+
res.status(500).json({ message: "Internal server error" });
39+
}
40+
};
41+
42+
// Get a Question
43+
const getQuestion = async (req, res) => {
44+
try {
45+
const question = await Question.findById(req.params.id);
46+
res.status(200).json({ question });
47+
} catch (error) {
48+
console.log(error);
49+
res.status(500).json({ message: "Internal server error" });
50+
}
51+
};
52+
53+
// Update a Question
54+
const updateQuestion = async (req, res) => {
55+
try {
56+
const {
57+
params: { id },
58+
body,
59+
} = req;
60+
61+
const updateQuestion = await Question.findByIdAndUpdate({ _id: id }, body);
62+
const allQuestions = await Question.find();
63+
64+
res.status(201).json({
65+
message: "Question Updated",
66+
question: updateQuestion,
67+
questions: allQuestions,
68+
});
69+
} catch (error) {
70+
console.log(error);
71+
res.status(500).json({ message: "Internal server error" });
72+
}
73+
};
74+
75+
// Delete a Question
76+
const deleteQuestion = async (req, res) => {
77+
try {
78+
const deleteQuestion = await Question.findByIdAndRemove(req.params.id);
79+
80+
const allQuestions = await Question.find();
81+
82+
res.status(200).json({
83+
message: "Question deleted",
84+
question: deleteQuestion,
85+
questions: allQuestions,
86+
});
87+
} catch (error) {
88+
console.log(error);
89+
res.status(500).json({ message: "Internal server error" });
90+
}
91+
};
92+
93+
// Add Test case to a Question
94+
const addTestcase = async (req, res) => {
95+
try {
96+
const {
97+
params: { id },
98+
} = req;
99+
const { input, output } = req.body;
100+
101+
const question = await Question.findByIdAndUpdate(id);
102+
103+
if (!question) {
104+
return res.status(404).json({ message: "Question not found" });
105+
}
106+
107+
question.testCases.push({ input, output });
108+
const addtestcase = await question.save();
109+
110+
const allQuestions = await Question.find();
111+
112+
res.status(201).json({
113+
message: "Test case added",
114+
question: addtestcase,
115+
questions: allQuestions,
116+
});
117+
} catch (error) {
118+
console.log(error);
119+
res.status(500).json({ message: "Internal server error" });
120+
}
121+
};
122+
123+
// Submit a solution
124+
const submitSolution = async (req, res) => {
125+
try {
126+
const { code, input, lang } = req.body;
127+
128+
const question = await Question.findById(req.params.id);
129+
console.log(question)
130+
131+
let url = "https://api.jdoodle.com/v1/execute";
132+
let config = {
133+
headers: {
134+
"Content-Type": "application/json",
135+
},
136+
};
137+
138+
let output;
139+
let program = {
140+
script: code,
141+
language: lang,
142+
stdin: input,
143+
versionIndex: "0",
144+
clientId: process.env.CLIENT_ID,
145+
clientSecret: process.env.CLIENT_SECRET
146+
};
147+
148+
try {
149+
await axios
150+
.post(url, program, config)
151+
.then((response) => {
152+
output = response.data;
153+
})
154+
.catch((err) => {
155+
console.log("error in app.js axios ", err);
156+
});
157+
} catch (err) {
158+
res.json({ message: "error" });
159+
}
160+
161+
res.json({ message: "Success", question, output });
162+
} catch (error) {
163+
console.log(error);
164+
res.status(500).json({ message: "Internal server error" });
165+
}
166+
};
167+
168+
module.exports = {
169+
getQuestions,
170+
addQuestion,
171+
getQuestion,
172+
updateQuestion,
173+
deleteQuestion,
174+
addTestcase,
175+
submitSolution,
176+
};

Diff for: server/controllers/user.js

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
require("dotenv").config();
2+
3+
const User = require("../models/User");
4+
const bcrypt = require("bcrypt");
5+
const jwt = require("jsonwebtoken");
6+
7+
// Signup endpoint
8+
const SignUp = async (req, res) => {
9+
try {
10+
const { name, email, password, role } = req.body;
11+
12+
const existingUser = await User.findOne({ email });
13+
if (existingUser) {
14+
return res.status(409).json({ message: "Email already exists" });
15+
}
16+
17+
const hashedPassword = await bcrypt.hash(password, 10);
18+
19+
const newUser = await User.create({
20+
name,
21+
email,
22+
password: hashedPassword,
23+
role,
24+
});
25+
26+
const token = jwt.sign(
27+
{ userId: newUser._id, role: newUser.role },
28+
process.env.ACCESS_TOKEN_SECRET,
29+
{ expiresIn: "1d" }
30+
);
31+
32+
res.status(201).json({ email: newUser.email, accessToken: token });
33+
} catch (error) {
34+
console.error("Error in signup:", error);
35+
res.status(500).json({ message: "Internal server error" });
36+
}
37+
};
38+
39+
// Login endpoint
40+
const LogIn = async (req, res) => {
41+
try {
42+
const { email, password } = req.body;
43+
44+
const user = await User.findOne({ email });
45+
if (!user) {
46+
return res.status(401).json({ message: "Invalid credentials" });
47+
}
48+
49+
const passwordMatch = await bcrypt.compare(password, user.password);
50+
if (!passwordMatch) {
51+
return res.status(401).json({ message: "Invalid credentials" });
52+
}
53+
54+
const token = jwt.sign(
55+
{ userId: user._id, role: user.role },
56+
process.env.ACCESS_TOKEN_SECRET,
57+
{ expiresIn: "1d" }
58+
);
59+
60+
res.status(200).json({ email: user.email, accessToken: token });
61+
} catch (error) {
62+
console.error("Error in login:", error);
63+
res.status(500).json({ message: "Internal server error" });
64+
}
65+
};
66+
67+
module.exports = { SignUp, LogIn };

Diff for: server/middleware/authMiddleware.js

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
require("dotenv").config();
2+
const jwt = require("jsonwebtoken");
3+
4+
function authenticateRole(role) {
5+
return (req, res, next) => {
6+
const token = req.headers.authorization?.split(" ")[1];
7+
8+
if (!token) {
9+
return res
10+
.status(401)
11+
.json({ message: "Authorization token not provided" });
12+
}
13+
14+
try {
15+
const decoded = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET);
16+
if (decoded.role !== role) {
17+
return res.status(403).json({ message: "Forbidden" });
18+
}
19+
req.user = decoded;
20+
next();
21+
} catch (error) {
22+
console.error("Error in authentication middleware:", error);
23+
res.status(500).json({ message: "Internal server error" });
24+
}
25+
};
26+
}
27+
28+
function authenticateToken(req, res, next) {
29+
const authHeader = req.headers.authorization;
30+
const token = authHeader && authHeader.split(" ")[1];
31+
32+
if (!token) {
33+
return res
34+
.status(401)
35+
.json({ message: "Authentication token not provided" });
36+
}
37+
38+
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (error, user) => {
39+
if (error) {
40+
return res.status(403).json({ message: "Invalid token" });
41+
}
42+
43+
req.user = user;
44+
next();
45+
});
46+
}
47+
48+
module.exports = { authenticateToken, authenticateRole };

Diff for: server/models/Question.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const mongoose = require("mongoose");
2+
3+
const questionSchema = new mongoose.Schema({
4+
title: {
5+
type: String,
6+
required: true,
7+
},
8+
description: {
9+
type: String,
10+
required: true,
11+
},
12+
testCases: [
13+
{
14+
input: String,
15+
output: String,
16+
},
17+
],
18+
createdBy: {
19+
type: mongoose.Schema.Types.ObjectId,
20+
ref: "User",
21+
required: true,
22+
},
23+
});
24+
25+
const Question = mongoose.model("Question", questionSchema);
26+
27+
module.exports = Question;

0 commit comments

Comments
 (0)