114 lines
2.9 KiB
JavaScript
114 lines
2.9 KiB
JavaScript
const express = require('express');
|
|
const axios = require('axios');
|
|
const path = require('path');
|
|
const ejs = require('ejs');
|
|
const app = express();
|
|
const port = 8080;
|
|
|
|
app.set('view engine', 'ejs');
|
|
app.set('views', path.join(__dirname, 'views'));
|
|
|
|
app.use(express.static(path.join(__dirname, 'public')));
|
|
|
|
app.get('/proxy', async (req, res) => {
|
|
const url = req.query.url;
|
|
const whitelisted_urls = [
|
|
"https://api-cdn.rule34.xxx/",
|
|
"https://api-cdn-mp4.rule34.xxx/"
|
|
];
|
|
|
|
try {
|
|
const isWhitelisted = whitelisted_urls.some((base) => url.startsWith(base));
|
|
|
|
if (!isWhitelisted) {
|
|
return res.status(403).send('URL is not allowed.');
|
|
}
|
|
|
|
const response = await axios.get(url, { responseType: 'arraybuffer' });
|
|
|
|
const contentType = response.headers['content-type'];
|
|
if (!contentType) {
|
|
return res.status(400).send('Invalid content type.');
|
|
}
|
|
|
|
console.log(`Proxied Content-Type: ${contentType}`); //Forgot to remove it but ima leave it for debugging purposes.
|
|
|
|
res.set('Content-Type', contentType);
|
|
res.send(response.data);
|
|
} catch (error) {
|
|
console.error('Error fetching media:', error.message);
|
|
res.status(500).send('Error fetching media.');
|
|
}
|
|
});
|
|
|
|
app.get('/', (req, res) => {
|
|
res.render('index', {
|
|
searchTerm: '',
|
|
});
|
|
});
|
|
|
|
app.get('/donate', (req, res) => {
|
|
res.render('donate', {
|
|
searchTerm: '',
|
|
});
|
|
});
|
|
|
|
app.get('/monero', (req, res) => {
|
|
res.status(200).send('86kNVqWXqTvAYnW97rPCLkGJL1pLyZZAreGa4NgMesEjggvBXso7JQ5TxWVdmu6FgA9zhKk2gvPEwRE2myZwQD4hANE7Pbw') //Please dont change that <3
|
|
});
|
|
|
|
app.get('/posts', async (req, res) => {
|
|
const blacklisted_searches = [
|
|
"rape",
|
|
"child",
|
|
"children",
|
|
"minor",
|
|
"infant",
|
|
"kid",
|
|
"loli",
|
|
"lolita",
|
|
"lolicon",
|
|
"shota",
|
|
"shotacon",
|
|
"bestiality",
|
|
"underage"
|
|
]
|
|
const search = req.query.search || '';
|
|
const page = parseInt(req.query.page) || 1;
|
|
const limit = 10;
|
|
const offset = (page - 1) * limit;
|
|
|
|
const isBlacklisted = blacklisted_searches.some((base) =>
|
|
new RegExp(`\\b${base}s?\\b`, 'i').test(search)
|
|
);
|
|
|
|
if (isBlacklisted) {
|
|
return res.status(403).send('Blacklisted search detected!');
|
|
}
|
|
|
|
try {
|
|
const apiUrl = search
|
|
? `https://api.rule34.xxx/index.php?page=dapi&s=post&q=index&json=1&tags=${encodeURIComponent(search)}&limit=${limit}&pid=${page - 1}`
|
|
: `https://api.rule34.xxx/index.php?page=dapi&s=post&q=index&json=1&limit=${limit}&pid=${page - 1}`;
|
|
|
|
const response = await axios.get(apiUrl, {
|
|
headers: { 'User-Agent': 'Mozilla/5.0' },
|
|
});
|
|
|
|
const posts = response.data || [];
|
|
|
|
res.render('posts', {
|
|
posts,
|
|
search,
|
|
page,
|
|
});
|
|
} catch (error) {
|
|
console.error('Error fetching posts:', error.message);
|
|
res.status(500).send('Error fetching posts. Please try again later.');
|
|
}
|
|
});
|
|
|
|
app.listen(port, () => {
|
|
console.log(`Server running at http://localhost:${port}`);
|
|
});
|