-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
233 lines (199 loc) · 8.02 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const obfuscate = require('./obfuscator.js');
const path = require('path');
const mongoose = require('mongoose');
const morgan = require('morgan');
const rateLimit = require('express-rate-limit');
const slowDown = require('express-slow-down');
const fetch = require('node-fetch'); // For VSCode
// import('node-fetch').then(({default: fetch})) // Fix for Replit
const cookieParser = require('cookie-parser');
const app = express();
app.set('trust proxy', 1);
app.use(bodyParser.text());
app.use(bodyParser.json());
app.use(cookieParser());
// Use morgan for logging
app.use(morgan('combined'));
app.use(express.static(path.join(__dirname, 'public')));
// Connect to MongoDB Atlas
mongoose.connect(process.env.MONGODB_URI);
// Define schema for statistics
const StatisticSchema = new mongoose.Schema({
user: String,
filesObfuscated: [String]
});
// Create model from the schema
const Statistic = mongoose.model('Statistic', StatisticSchema);
// Rate limiting and slow down middleware
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // 100 requests per windowMs
handler: async function (req, res, next) {
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
const response = await fetch(`https://ipinfo.io/${ip}/json?token=${process.env.IPINFO_TOKEN}`);
const data = await response.json();
// Check if the IP belongs to a hosting provider (possible VPN)
const isPossibleVPN = data.hosting ? "Possible VPN" : "No indication of VPN";
// Log rate limit to Discord webhook
fetch(process.env.DISCORD_WEBHOOK_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
embeds: [{
title: "Rate Limit Exceeded",
description: `Rate limit exceeded for IP: ${ip}`,
fields: [
{
name: "Limit",
value: this.max
},
{
name: "Reset Time",
value: new Date(Date.now() + this.windowMs).toLocaleString("en-US", { timeZone: "America/New_York" }) // Convert to EST
},
{
name: "Timestamp",
value: new Date().toLocaleString("en-US", { timeZone: "America/New_York" }) // Convert to EST
},
{
name: "VPN Check",
value: isPossibleVPN
}
],
color: 15158332
}]
})
});
res.status(429).send('Rate limit exceeded.');
}
});
// Define speedLimiter for slow down middleware
const speedLimiter = slowDown({
windowMs: 15 * 60 * 1000, // 15 minutes
delayAfter: 50, // allow 50 requests per 15 minutes, then...
delayMs: (req, res, options, used) => {
const delayAfter = options.delayAfter;
const delayMs = options.delayMs;
return (used - delayAfter) * delayMs;
}
});
app.use(speedLimiter);
app.use(limiter);
// Middleware for VPN detection, developer check, and IP blacklist check
app.use(async (req, res, next) => {
let ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
const response = await fetch(`https://ipinfo.io/${ip}/json?token=${process.env.IPINFO_TOKEN}`);
const data = await response.json();
req.isVPN = data.privacy && data.privacy.vpn;
const hiddenIPs = process.env.HIDDEN_IPS.split(',');
if (hiddenIPs.some(hiddenIp => ip.startsWith(hiddenIp))) {
req.isDeveloper = true;
ip = 'Developer IP detected';
}
const blacklistedIPs = process.env.BLACKLISTED_IPS.split(',');
if (blacklistedIPs.includes(ip)) {
res.status(403).send('Your IP address is blacklisted from using this service due to violating the Terms of Service.');
return;
}
next();
});
app.use(speedLimiter);
app.use(limiter);
app.post('/obfuscate', async (req, res) => {
const { code, settings } = req.body;
// Check if the code is empty
if (!code || code.trim() === '') {
res.status(400).send('The code cannot be empty.');
return;
}
const user = req.headers['user-agent']; // Get the User-Agent header
const ip = req.isDeveloper ? 'Developer IP detected' : req.headers['x-forwarded-for'] || req.connection.remoteAddress;
// Fetch data from ipinfo.io
const response = await fetch(`https://ipinfo.io/${ip}/json?token=${process.env.IPINFO_TOKEN}`);
const data = await response.json();
// Check if the IP belongs to a VPN
const isVPN = data.privacy && data.privacy.vpn;
if (isVPN) {
// If a VPN is detected, don't obfuscate and send a message to the Discord webhook
fetch(process.env.DISCORD_WEBHOOK_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
embeds: [{
title: "Failed to Obfuscate",
description: `User attempted to obfuscate with a VPN: ${user}`,
fields: [
{
name: "IP Address",
value: ip
},
{
name: "Timestamp",
value: new Date().toLocaleString("en-US", { timeZone: "America/New_York" }) // Convert to EST
}
],
color: 15158332 // Red color
}]
})
});
res.status(403).send('Obfuscation is not allowed when using a VPN.');
return;
}
const obfuscatedCode = obfuscate(code, settings);
// Log successful obfuscation to Discord webhook
fetch(process.env.DISCORD_WEBHOOK_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
embeds: [{
title: "Successful Obfuscation",
description: `Successful obfuscation for user: ${user}`,
fields: [
{
name: "Obfuscation Settings",
value: JSON.stringify(settings, null, 2)
},
{
name: "Timestamp",
value: new Date().toLocaleString("en-US", { timeZone: "America/New_York" }) // Convert to EST
},
{
name: "IP Address",
value: ip
}
],
color: 3066993 // Green
}]
})
});
// Find or create statistic for user
let statistic = await Statistic.findOne({ user: req.headers['user-agent'] });
if (!statistic) {
statistic = new Statistic({
user: req.headers['user-agent'],
filesObfuscated: []
});
}
// Update statistics
statistic.filesObfuscated.push(obfuscatedCode);
await statistic.save(); // Save the statistic to the database
res.send(obfuscatedCode);
});
app.get('/statistics', async (req, res) => {
const stats = await Statistic.find();
// Send statistics
res.json({
totalUsersServed: stats.length,
totalFilesObfuscated: stats.reduce((total, stat) => total + stat.filesObfuscated.length, 0)
});
});
app.listen(process.env.PORT, () => console.log(`Server running on port ${process.env.PORT}`));