Server: reorganize express validators
[oweals/peertube.git] / server.js
1 'use strict'
2
3 // ----------- Node modules -----------
4 const bodyParser = require('body-parser')
5 const express = require('express')
6 const expressValidator = require('express-validator')
7 const http = require('http')
8 const morgan = require('morgan')
9 const path = require('path')
10 const TrackerServer = require('bittorrent-tracker').Server
11 const WebSocketServer = require('ws').Server
12
13 // Create our main app
14 const app = express()
15
16 // ----------- Database -----------
17 const config = require('config')
18 const constants = require('./server/initializers/constants')
19 const database = require('./server/initializers/database')
20 const logger = require('./server/helpers/logger')
21
22 database.connect()
23
24 // ----------- Checker -----------
25 const checker = require('./server/initializers/checker')
26
27 const miss = checker.checkConfig()
28 if (miss.length !== 0) {
29   throw new Error('Miss some configurations keys : ' + miss)
30 }
31
32 // ----------- PeerTube modules -----------
33 const customValidators = require('./server/helpers/custom-validators')
34 const installer = require('./server/initializers/installer')
35 const mongoose = require('mongoose')
36 const routes = require('./server/controllers')
37 const utils = require('./server/helpers/utils')
38 const webtorrent = require('./server/lib/webtorrent')
39 const Request = mongoose.model('Request')
40 const Video = mongoose.model('Video')
41
42 // Get configurations
43 const port = config.get('listen.port')
44
45 // ----------- Command line -----------
46
47 // ----------- App -----------
48
49 // For the logger
50 app.use(morgan('combined', { stream: logger.stream }))
51 // For body requests
52 app.use(bodyParser.json())
53 app.use(bodyParser.urlencoded({ extended: false }))
54 // Validate some params for the API
55 app.use(expressValidator({
56   customValidators: Object.assign({}, customValidators.misc, customValidators.users, customValidators.videos)
57 }))
58
59 // ----------- Views, routes and static files -----------
60
61 // Catch sefaults
62 require('segfault-handler').registerHandler()
63
64 // API routes
65 const apiRoute = '/api/' + constants.API_VERSION
66 app.use(apiRoute, routes.api)
67
68 // Static files
69 app.use('/client', express.static(path.join(__dirname, '/client/dist'), { maxAge: 0 }))
70 // 404 for static files not found
71 app.use('/client/*', function (req, res, next) {
72   res.sendStatus(404)
73 })
74
75 // Thumbnails path for express
76 const thumbnailsPhysicalPath = path.join(__dirname, config.get('storage.thumbnails'))
77 app.use(constants.THUMBNAILS_STATIC_PATH, express.static(thumbnailsPhysicalPath, { maxAge: 0 }))
78
79 // Client application
80 app.use('/*', function (req, res, next) {
81   res.sendFile(path.join(__dirname, 'client/dist/index.html'))
82 })
83
84 // ----------- Tracker -----------
85
86 const trackerServer = new TrackerServer({
87   http: false,
88   udp: false,
89   ws: false,
90   dht: false
91 })
92
93 trackerServer.on('error', function (err) {
94   logger.error(err)
95 })
96
97 trackerServer.on('warning', function (err) {
98   logger.error(err)
99 })
100
101 const server = http.createServer(app)
102 const wss = new WebSocketServer({server: server, path: '/tracker/socket'})
103 wss.on('connection', function (ws) {
104   trackerServer.onWebSocketConnection(ws)
105 })
106
107 // ----------- Errors -----------
108
109 // Catch 404 and forward to error handler
110 app.use(function (req, res, next) {
111   const err = new Error('Not Found')
112   err.status = 404
113   next(err)
114 })
115
116 app.use(function (err, req, res, next) {
117   logger.error(err)
118   res.sendStatus(err.status || 500)
119 })
120
121 installer.installApplication(function (err) {
122   if (err) throw err
123
124   // Create/activate the webtorrent module
125   webtorrent.create(function () {
126     function cleanForExit () {
127       utils.cleanForExit(webtorrent.app)
128     }
129
130     function exitGracefullyOnSignal () {
131       process.exit(-1)
132     }
133
134     process.on('exit', cleanForExit)
135     process.on('SIGINT', exitGracefullyOnSignal)
136     process.on('SIGTERM', exitGracefullyOnSignal)
137
138     // ----------- Make the server listening -----------
139     server.listen(port, function () {
140       // Activate the pool requests
141       Request.activate()
142
143       Video.seedAllExisting(function (err) {
144         if (err) throw err
145
146         logger.info('Seeded all the videos')
147         logger.info('Server listening on port %d', port)
148         app.emit('ready')
149       })
150     })
151   })
152 })
153
154 module.exports = app