Repository navigation
Expand file tree
/
Copy pathapp.js
More file actions
96 lines (84 loc) · 3.54 KB
/
Copy pathapp.js
File metadata and controls
96 lines (84 loc) · 3.54 KB
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
const express = require('express');
const path = require('path');
const session = require('express-session');
const MongoStore = require('connect-mongo');
const rateLimit = require('express-rate-limit');
const compression = require('compression');
const { MONGO_URI } = require('./constants/allowed');
const { SESSION_SECRET } = require('./config/env');
const fs = require('fs');
const { sanitizeMiddleware } = require('./middleware/sanitizeMongo');
const { botDetection } = require('./middleware/botDetection');
const { corsHeaders, securityHeaders, cspMiddleware } = require('./middleware/securityHeaders');
const { privacyWrapper } = require('./middleware/privacyWrapper');
const app = express();
app.use(compression());
app.set('trust proxy', 1);
app.use(express.static(path.join(__dirname, 'public')));
if (!global.privacyMap) global.privacyMap = new Map();
if (!fs.existsSync(path.join(__dirname, 'uploads'))) fs.mkdirSync(path.join(__dirname, 'uploads'));
app.use(corsHeaders);
const sessionLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 10000,
validate: { xForwardedForHeader: false },
keyGenerator: (req) => req.session?.username || req.ip,
message: 'Too many requests'
});
app.use(sessionLimiter);
app.use(session({
name: '4send_sid',
secret: SESSION_SECRET,
resave: false,
saveUninitialized: false,
store: MongoStore.create({ mongoUrl: MONGO_URI, collectionName: 'sessions', ttl: 24 * 60 * 60 }),
cookie: { httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax', maxAge: 24 * 60 * 60 * 1000 }
}));
const User = require('./models/User');
app.use(async (req, res, next) => {
if (req.session && req.session.username && !req.session.avatar) {
try {
const user = await User.findOne({ username: req.session.username }).select('avatar').lean();
if (user && user.avatar) req.session.avatar = user.avatar;
} catch (e) {}
}
next();
});
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
app.use(botDetection);
app.use(securityHeaders);
app.use(cspMiddleware);
app.use(sanitizeMiddleware);
app.use(privacyWrapper);
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', require('./routes/root'));
app.use('/', require('./routes/auth'));
app.use('/', require('./routes/users'));
app.use('/', require('./routes/upload'));
app.use('/', require('./routes/chats'));
app.use('/', require('./routes/rooms'));
app.use('/', require('./routes/admin'));
app.use('/', require('./routes/settings'));
app.use('/', require('./routes/security'));
app.use('/', require('./routes/block'));
app.use('/', require('./routes/media'));
app.use('/', require('./routes/pins'));
app.use('/', require('./routes/link'));
app.use('/', require('./routes/push'));
app.use('/', require('./routes/account'));
app.use('/', require('./routes/sessions'));
app.use('/', require('./routes/ai'));
app.use('/', require('./routes/firebase'));
app.use('/', require('./routes/keys'));
app.use('/', require('./routes/reports'));
const API_PREFIXES = ['/auth', '/api', '/upload', '/history', '/chats-extended', '/socket.io', '/languages', '/fonts'];
app.get('*', (req, res) => {
if (API_PREFIXES.some(p => req.path.startsWith(p))) {
return res.status(404).send('Not found');
}
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
app.use((req, res) => res.status(404).send('Not found'));
app.use((err, req, res, next) => { res.status(500).send('Server error'); });
module.exports = app;