-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathapp.js
149 lines (129 loc) · 4.94 KB
/
app.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
"use strict";
import express from "express";
import swaggerUi from "swagger-ui-express";
import swaggerJsDoc from "swagger-jsdoc";
import bodyParser from "body-parser";
import cookieParser from "cookie-parser";
import morgan from "morgan";
import config from "./config.js";
import docs_config from "./docs-config.js"
import "./lib/configLoader.js"; // to dynamic update config
import * as misc from "./lib/misc.js";
import {generateCaptcha} from "./lib/captcha.js";
import logger from "./logger.js";
import router_user from "./routes/user.js";
import {router as router_user_subscribes} from "./routes/user_subscribes.js";
import {router as router_user_achievement} from "./routes/user_achievements.js";
import router_admin from "./routes/admin.js"
import router_index from "./routes/index.js";
import router_player from "./routes/player.js";
import router_message from "./routes/message.js";
import router_services from "./routes/services.js";
import {query as checkquery, validationResult, body as checkbody} from "express-validator";
import {captchaRateLimiter, UserRateLimiter} from "./middleware/rateLimiter.js";
import {verifyJWT} from "./middleware/auth.js";
import "./services/loader.js";
import fs from "fs";
import path from "path";
// process
process.on('uncaughtException', (err) => {
logger.error('Uncaught Exception:', err.message, err.stack);
});
process.on('unhandledRejection', (err) => {
logger.error('Unhandled Rejection:', err.message, err.stack);
});
const app = express();
// initialize swagger-jsdoc
// see swagger docs [https://swagger.io/specification/]
const swaggerSpec = swaggerJsDoc({
// import swaggerDefinitions
swaggerDefinition: docs_config,
// path to the API docs
apis: ['./routes/*.js'],
});
app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec, {
explorer: true,
customCss: fs.readFileSync('theme-feeling-blue.css', 'utf-8') + ' .swagger-ui .topbar { display: none }',
}));
app.set('trust proxy', false);
app.use((req, res, next) => {
let realIP = '';
switch (true) {
case !!req.get('CF-Connecting-IP') && config.cloudflare:
realIP = req.get('CF-Connecting-IP');
break;
case !!req.get('X-Forwarded-For') && config.behindProxy:
realIP = req.get('X-Forwarded-For').split(',').reverse()[config.behindProxy];
break;
default:
realIP = req.ip;
break;
}
req.REAL_IP = realIP;
next();
});
app.use(cookieParser()); // should throw it into trash bin
app.use(morgan((tokens, req, res) => {
const status = tokens.status(req, res);
const base = `${tokens.status(req, res)} ${tokens.method(req, res)} ${tokens.url(req, res)} in ${tokens['response-time'](req, res)}ms`;
const verbose = config.logLevel >= 3 ? ` RequestBody: ${JSON.stringify(req.body)}` : '';
if (config.logLevel < 0)
return undefined;
if (status >= 500)
return logger.toText.error(base + verbose);
else if (status >= 400)
return logger.toText.warn(base + verbose);
else
return logger.toText.info(base + verbose);
}));
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
// cors options
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', req.header('Origin') || '*'); // better than wildcard *
res.header('Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept, x-access-token' + (config.__DEBUG__ ? ', x-whosdaddy, x-whosdaddy-p' : '')); // DEBUG
res.header('Access-Control-Allow-Methods', 'GET,HEAD,OPTIONS,POST,PUT');
res.header('Access-Control-Allow-Credentials', true);
res.header('Cache-Control', "no-cache");
next();
});
app.use('/static', express.static('./test')); // debug only
app.use('/api', router_index);
app.use('/api/user', router_user, router_user_subscribes, router_user_achievement);
app.use('/api/admin', router_admin);
app.use('/api/player', router_player);
app.use('/api/message', router_message);
app.use('/api/service', router_services);
/**
* @swagger
* /api/captcha:
* get:
* tags:
* - user
* - captcha
* description: Get CAPTCHA
*/
app.get('/api/captcha', captchaRateLimiter, (req, res, next) => {
res.status(200).json({success: 1, code: 'captcha.gen', data: generateCaptcha()});
});
app.get('/', (req, res, next) => {
res.redirect('/docs');
});
app.get('/test', (req, res, next) => {
res.redirect('/static/SPA.html');
});
app.options('*', (req, res, next) => { // for preflight requests
res.status(200).send();
});
app.use((req, res, next) => {
res.status(404).json({error: 1, code: 'request.404'});
});
app.use((err, req, res, next) => { // error handler
logger.error(err.message, err.stack);
res.status(500).json({error: 1, code: 'server.error', message: misc.generateErrorHelper(err)});
});
app.listen(config.port, config.address, () => {
logger.success(`App start at ${config.address}:${config.port}`);
});
export default app;