Update index.js
Browse files
index.js
CHANGED
|
@@ -14,6 +14,8 @@ app.use(express.static(path.join(path.resolve(), 'public')));
|
|
| 14 |
let comments = [];
|
| 15 |
let commentId = 1;
|
| 16 |
|
|
|
|
|
|
|
| 17 |
function findCommentById(id, commentsList = comments) {
|
| 18 |
for (let comment of commentsList) {
|
| 19 |
if (comment.id === id) {
|
|
@@ -29,17 +31,20 @@ function findCommentById(id, commentsList = comments) {
|
|
| 29 |
return null;
|
| 30 |
}
|
| 31 |
|
|
|
|
| 32 |
app.get('/comments', (req, res) => {
|
| 33 |
res.json(comments);
|
| 34 |
});
|
| 35 |
|
| 36 |
-
// Add new comment
|
| 37 |
app.post('/comments', (req, res) => {
|
|
|
|
|
|
|
| 38 |
const comment = {
|
| 39 |
id: commentId++,
|
| 40 |
content: req.body.content,
|
| 41 |
timestamp: req.body.timestamp,
|
| 42 |
sessionId: req.headers['x-session-id'],
|
|
|
|
| 43 |
replies: []
|
| 44 |
};
|
| 45 |
|
|
@@ -47,9 +52,9 @@ app.post('/comments', (req, res) => {
|
|
| 47 |
res.status(201).json(comment);
|
| 48 |
});
|
| 49 |
|
| 50 |
-
// Add reply to a comment
|
| 51 |
app.post('/comments/:id/reply', (req, res) => {
|
| 52 |
const parentId = parseInt(req.params.id);
|
|
|
|
| 53 |
const result = findCommentById(parentId);
|
| 54 |
|
| 55 |
if (!result) {
|
|
@@ -61,6 +66,7 @@ app.post('/comments/:id/reply', (req, res) => {
|
|
| 61 |
content: req.body.content,
|
| 62 |
timestamp: req.body.timestamp,
|
| 63 |
sessionId: req.headers['x-session-id'],
|
|
|
|
| 64 |
replies: []
|
| 65 |
};
|
| 66 |
|
|
@@ -72,21 +78,17 @@ app.post('/comments/:id/reply', (req, res) => {
|
|
| 72 |
app.delete('/comments/:id', (req, res) => {
|
| 73 |
const id = parseInt(req.params.id);
|
| 74 |
const sessionId = req.headers['x-session-id'];
|
| 75 |
-
|
| 76 |
const result = findCommentById(id);
|
| 77 |
-
|
| 78 |
if (!result) {
|
| 79 |
return res.status(404).json({ error: 'Comment not found' });
|
| 80 |
}
|
| 81 |
|
| 82 |
const { comment, parent } = result;
|
| 83 |
-
|
| 84 |
-
// Check if the user is the author of the comment
|
| 85 |
-
if (comment.sessionId !== sessionId) {
|
| 86 |
return res.status(403).json({ error: 'Unauthorized to delete this comment' });
|
| 87 |
}
|
| 88 |
|
| 89 |
-
// Remove the comment from its parent array
|
| 90 |
const index = parent.findIndex(c => c.id === id);
|
| 91 |
if (index !== -1) {
|
| 92 |
parent.splice(index, 1);
|
|
@@ -102,7 +104,6 @@ app.get('/api/proxy-image', (req, res) => {
|
|
| 102 |
return res.status(400).send('Image URL is required');
|
| 103 |
}
|
| 104 |
|
| 105 |
-
// Choose protocol (HTTP or HTTPS)
|
| 106 |
const protocol = imageUrl.startsWith('https') ? https : http;
|
| 107 |
|
| 108 |
protocol.get(imageUrl, (imageResponse) => {
|
|
@@ -160,7 +161,6 @@ app.get('/api/anime/:id', async (req, res) => {
|
|
| 160 |
.map((i, el) => $(el).text().trim())
|
| 161 |
.get();
|
| 162 |
|
| 163 |
-
// Detail tambahan anime
|
| 164 |
const details = {};
|
| 165 |
$('.spe span').each((i, el) => {
|
| 166 |
const label = $(el).find('b').text().trim();
|
|
@@ -168,15 +168,12 @@ app.get('/api/anime/:id', async (req, res) => {
|
|
| 168 |
details[label.replace(':', '')] = value;
|
| 169 |
});
|
| 170 |
|
| 171 |
-
// List episode
|
| 172 |
const episodes = [];
|
| 173 |
$('.lstepsiode ul li').each((i, el) => {
|
| 174 |
const episodeNumber = $(el).find('.eps a').text().trim();
|
| 175 |
const episodeTitle = $(el).find('.lchx a').text().trim();
|
| 176 |
const episodeLink = $(el).find('.lchx a').attr('href');
|
| 177 |
const episodeDate = $(el).find('.date').text().trim();
|
| 178 |
-
|
| 179 |
-
// Extract the episode ID (from URL trimming process)
|
| 180 |
const episodeId = episodeLink.split('/').slice(-2, -1)[0];
|
| 181 |
|
| 182 |
episodes.push({
|
|
@@ -188,7 +185,6 @@ app.get('/api/anime/:id', async (req, res) => {
|
|
| 188 |
});
|
| 189 |
});
|
| 190 |
|
| 191 |
-
// Kirim response JSON
|
| 192 |
res.json({
|
| 193 |
title: animeTitle,
|
| 194 |
image: `https://xinoooo-sme.hf.space/api/proxy-image?url=${encodeURIComponent(animeImage)}`,
|
|
|
|
| 14 |
let comments = [];
|
| 15 |
let commentId = 1;
|
| 16 |
|
| 17 |
+
const ADMIN_KEY = 'yoshino12345';
|
| 18 |
+
|
| 19 |
function findCommentById(id, commentsList = comments) {
|
| 20 |
for (let comment of commentsList) {
|
| 21 |
if (comment.id === id) {
|
|
|
|
| 31 |
return null;
|
| 32 |
}
|
| 33 |
|
| 34 |
+
// Get all comments
|
| 35 |
app.get('/comments', (req, res) => {
|
| 36 |
res.json(comments);
|
| 37 |
});
|
| 38 |
|
|
|
|
| 39 |
app.post('/comments', (req, res) => {
|
| 40 |
+
const isAdmin = req.headers['x-admin'] === 'true';
|
| 41 |
+
|
| 42 |
const comment = {
|
| 43 |
id: commentId++,
|
| 44 |
content: req.body.content,
|
| 45 |
timestamp: req.body.timestamp,
|
| 46 |
sessionId: req.headers['x-session-id'],
|
| 47 |
+
isAdmin: isAdmin,
|
| 48 |
replies: []
|
| 49 |
};
|
| 50 |
|
|
|
|
| 52 |
res.status(201).json(comment);
|
| 53 |
});
|
| 54 |
|
|
|
|
| 55 |
app.post('/comments/:id/reply', (req, res) => {
|
| 56 |
const parentId = parseInt(req.params.id);
|
| 57 |
+
const isAdmin = req.headers['x-admin'] === 'true';
|
| 58 |
const result = findCommentById(parentId);
|
| 59 |
|
| 60 |
if (!result) {
|
|
|
|
| 66 |
content: req.body.content,
|
| 67 |
timestamp: req.body.timestamp,
|
| 68 |
sessionId: req.headers['x-session-id'],
|
| 69 |
+
isAdmin: isAdmin,
|
| 70 |
replies: []
|
| 71 |
};
|
| 72 |
|
|
|
|
| 78 |
app.delete('/comments/:id', (req, res) => {
|
| 79 |
const id = parseInt(req.params.id);
|
| 80 |
const sessionId = req.headers['x-session-id'];
|
| 81 |
+
const isAdmin = req.headers['x-admin'] === 'true';
|
| 82 |
const result = findCommentById(id);
|
|
|
|
| 83 |
if (!result) {
|
| 84 |
return res.status(404).json({ error: 'Comment not found' });
|
| 85 |
}
|
| 86 |
|
| 87 |
const { comment, parent } = result;
|
| 88 |
+
if (!isAdmin && comment.sessionId !== sessionId) {
|
|
|
|
|
|
|
| 89 |
return res.status(403).json({ error: 'Unauthorized to delete this comment' });
|
| 90 |
}
|
| 91 |
|
|
|
|
| 92 |
const index = parent.findIndex(c => c.id === id);
|
| 93 |
if (index !== -1) {
|
| 94 |
parent.splice(index, 1);
|
|
|
|
| 104 |
return res.status(400).send('Image URL is required');
|
| 105 |
}
|
| 106 |
|
|
|
|
| 107 |
const protocol = imageUrl.startsWith('https') ? https : http;
|
| 108 |
|
| 109 |
protocol.get(imageUrl, (imageResponse) => {
|
|
|
|
| 161 |
.map((i, el) => $(el).text().trim())
|
| 162 |
.get();
|
| 163 |
|
|
|
|
| 164 |
const details = {};
|
| 165 |
$('.spe span').each((i, el) => {
|
| 166 |
const label = $(el).find('b').text().trim();
|
|
|
|
| 168 |
details[label.replace(':', '')] = value;
|
| 169 |
});
|
| 170 |
|
|
|
|
| 171 |
const episodes = [];
|
| 172 |
$('.lstepsiode ul li').each((i, el) => {
|
| 173 |
const episodeNumber = $(el).find('.eps a').text().trim();
|
| 174 |
const episodeTitle = $(el).find('.lchx a').text().trim();
|
| 175 |
const episodeLink = $(el).find('.lchx a').attr('href');
|
| 176 |
const episodeDate = $(el).find('.date').text().trim();
|
|
|
|
|
|
|
| 177 |
const episodeId = episodeLink.split('/').slice(-2, -1)[0];
|
| 178 |
|
| 179 |
episodes.push({
|
|
|
|
| 185 |
});
|
| 186 |
});
|
| 187 |
|
|
|
|
| 188 |
res.json({
|
| 189 |
title: animeTitle,
|
| 190 |
image: `https://xinoooo-sme.hf.space/api/proxy-image?url=${encodeURIComponent(animeImage)}`,
|