aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--package.json16
-rw-r--r--server.ts (renamed from server.js)80
-rw-r--r--server/controllers/api/clients.ts (renamed from server/controllers/api/clients.js)20
-rw-r--r--server/controllers/api/config.js22
-rw-r--r--server/controllers/api/config.ts22
-rw-r--r--server/controllers/api/index.js35
-rw-r--r--server/controllers/api/index.ts33
-rw-r--r--server/controllers/api/pods.js109
-rw-r--r--server/controllers/api/pods.ts118
-rw-r--r--server/controllers/api/remote/index.js18
-rw-r--r--server/controllers/api/remote/index.ts18
-rw-r--r--server/controllers/api/remote/pods.ts (renamed from server/controllers/api/remote/pods.js)20
-rw-r--r--server/controllers/api/remote/videos.ts (renamed from server/controllers/api/remote/videos.js)122
-rw-r--r--server/controllers/api/requests.ts (renamed from server/controllers/api/requests.js)34
-rw-r--r--server/controllers/api/users.ts (renamed from server/controllers/api/users.js)96
-rw-r--r--server/controllers/api/videos/abuse.ts (renamed from server/controllers/api/videos/abuse.js)77
-rw-r--r--server/controllers/api/videos/blacklist.ts (renamed from server/controllers/api/videos/blacklist.js)34
-rw-r--r--server/controllers/api/videos/index.ts (renamed from server/controllers/api/videos/index.js)182
-rw-r--r--server/controllers/api/videos/rate.ts (renamed from server/controllers/api/videos/rate.js)78
-rw-r--r--server/controllers/client.ts (renamed from server/controllers/client.js)56
-rw-r--r--server/controllers/index.js11
-rw-r--r--server/controllers/index.ts3
-rw-r--r--server/controllers/static.js45
-rw-r--r--server/controllers/static.ts49
-rw-r--r--server/helpers/custom-validators/index.js19
-rw-r--r--server/helpers/custom-validators/index.ts6
-rw-r--r--server/helpers/custom-validators/misc.ts (renamed from server/helpers/custom-validators/misc.js)12
-rw-r--r--server/helpers/custom-validators/pods.ts (renamed from server/helpers/custom-validators/pods.js)20
-rw-r--r--server/helpers/custom-validators/remote/index.js11
-rw-r--r--server/helpers/custom-validators/remote/index.ts1
-rw-r--r--server/helpers/custom-validators/remote/videos.js118
-rw-r--r--server/helpers/custom-validators/remote/videos.ts138
-rw-r--r--server/helpers/custom-validators/users.ts (renamed from server/helpers/custom-validators/users.js)28
-rw-r--r--server/helpers/custom-validators/videos.ts (renamed from server/helpers/custom-validators/videos.js)95
-rw-r--r--server/helpers/database-utils.ts (renamed from server/helpers/database-utils.js)25
-rw-r--r--server/helpers/index.ts6
-rw-r--r--server/helpers/logger.ts (renamed from server/helpers/logger.js)31
-rw-r--r--server/helpers/peertube-crypto.ts (renamed from server/helpers/peertube-crypto.js)67
-rw-r--r--server/helpers/requests.ts (renamed from server/helpers/requests.js)41
-rw-r--r--server/helpers/utils.ts (renamed from server/helpers/utils.js)26
-rw-r--r--server/initializers/checker.ts (renamed from server/initializers/checker.js)24
-rw-r--r--server/initializers/constants.ts (renamed from server/initializers/constants.js)52
-rw-r--r--server/initializers/database.ts (renamed from server/initializers/database.js)51
-rw-r--r--server/initializers/index.ts6
-rw-r--r--server/initializers/installer.ts (renamed from server/initializers/installer.js)44
-rw-r--r--server/initializers/migrations/0005-email-pod.ts (renamed from server/initializers/migrations/0005-email-pod.js)13
-rw-r--r--server/initializers/migrations/0010-email-user.ts (renamed from server/initializers/migrations/0010-email-user.js)13
-rw-r--r--server/initializers/migrations/0015-video-views.ts (renamed from server/initializers/migrations/0015-video-views.js)11
-rw-r--r--server/initializers/migrations/0020-video-likes.ts (renamed from server/initializers/migrations/0020-video-likes.js)11
-rw-r--r--server/initializers/migrations/0025-video-dislikes.ts (renamed from server/initializers/migrations/0025-video-dislikes.js)11
-rw-r--r--server/initializers/migrations/0030-video-category.ts (renamed from server/initializers/migrations/0030-video-category.js)13
-rw-r--r--server/initializers/migrations/0035-video-licence.ts (renamed from server/initializers/migrations/0035-video-licence.js)13
-rw-r--r--server/initializers/migrations/0040-video-nsfw.ts (renamed from server/initializers/migrations/0040-video-nsfw.js)13
-rw-r--r--server/initializers/migrations/0045-user-display-nsfw.ts (renamed from server/initializers/migrations/0045-user-display-nsfw.js)11
-rw-r--r--server/initializers/migrations/0050-video-language.ts (renamed from server/initializers/migrations/0050-video-language.js)11
-rw-r--r--server/initializers/migrator.ts (renamed from server/initializers/migrator.js)25
-rw-r--r--server/lib/friends.ts (renamed from server/lib/friends.js)133
-rw-r--r--server/lib/index.ts4
-rw-r--r--server/lib/jobs/handlers/index.js7
-rw-r--r--server/lib/jobs/handlers/index.ts9
-rw-r--r--server/lib/jobs/handlers/video-transcoder.ts (renamed from server/lib/jobs/handlers/video-transcoder.js)22
-rw-r--r--server/lib/jobs/index.ts1
-rw-r--r--server/lib/jobs/job-scheduler.js129
-rw-r--r--server/lib/jobs/job-scheduler.ts137
-rw-r--r--server/lib/oauth-model.ts (renamed from server/lib/oauth-model.js)22
-rw-r--r--server/lib/request/base-request-scheduler.ts (renamed from server/lib/request/base-request-scheduler.js)64
-rw-r--r--server/lib/request/index.ts3
-rw-r--r--server/lib/request/request-scheduler.ts (renamed from server/lib/request/request-scheduler.js)25
-rw-r--r--server/lib/request/request-video-event-scheduler.ts (renamed from server/lib/request/request-video-event-scheduler.js)28
-rw-r--r--server/lib/request/request-video-qadu-scheduler.ts (renamed from server/lib/request/request-video-qadu-scheduler.js)37
-rw-r--r--server/middlewares/admin.ts (renamed from server/middlewares/admin.js)10
-rw-r--r--server/middlewares/index.js25
-rw-r--r--server/middlewares/index.ts8
-rw-r--r--server/middlewares/oauth.ts (renamed from server/middlewares/oauth.js)14
-rw-r--r--server/middlewares/pagination.ts (renamed from server/middlewares/pagination.js)11
-rw-r--r--server/middlewares/pods.ts (renamed from server/middlewares/pods.js)10
-rw-r--r--server/middlewares/search.ts (renamed from server/middlewares/search.js)10
-rw-r--r--server/middlewares/secure.ts (renamed from server/middlewares/secure.js)10
-rw-r--r--server/middlewares/sort.ts (renamed from server/middlewares/sort.js)14
-rw-r--r--server/middlewares/validators/index.js21
-rw-r--r--server/middlewares/validators/index.ts6
-rw-r--r--server/middlewares/validators/pagination.ts (renamed from server/middlewares/validators/pagination.js)16
-rw-r--r--server/middlewares/validators/pods.ts (renamed from server/middlewares/validators/pods.js)32
-rw-r--r--server/middlewares/validators/remote/index.js13
-rw-r--r--server/middlewares/validators/remote/index.ts2
-rw-r--r--server/middlewares/validators/remote/signature.ts (renamed from server/middlewares/validators/remote/signature.js)16
-rw-r--r--server/middlewares/validators/remote/videos.ts (renamed from server/middlewares/validators/remote/videos.js)25
-rw-r--r--server/middlewares/validators/sort.ts (renamed from server/middlewares/validators/sort.js)32
-rw-r--r--server/middlewares/validators/users.ts (renamed from server/middlewares/validators/users.js)28
-rw-r--r--server/middlewares/validators/utils.ts (renamed from server/middlewares/validators/utils.js)18
-rw-r--r--server/middlewares/validators/videos.ts (renamed from server/middlewares/validators/videos.js)59
-rw-r--r--server/models/application.ts (renamed from server/models/application.js)4
-rw-r--r--server/models/author.ts (renamed from server/models/author.js)8
-rw-r--r--server/models/job.ts (renamed from server/models/job.js)8
-rw-r--r--server/models/oauth-client.ts (renamed from server/models/oauth-client.js)2
-rw-r--r--server/models/oauth-token.ts (renamed from server/models/oauth-token.js)4
-rw-r--r--server/models/pod.ts (renamed from server/models/pod.js)28
-rw-r--r--server/models/request-to-pod.ts (renamed from server/models/request-to-pod.js)6
-rw-r--r--server/models/request-video-event.ts (renamed from server/models/request-video-event.js)12
-rw-r--r--server/models/request-video-qadu.ts (renamed from server/models/request-video-qadu.js)8
-rw-r--r--server/models/request.ts (renamed from server/models/request.js)10
-rw-r--r--server/models/tag.ts (renamed from server/models/tag.js)6
-rw-r--r--server/models/user-video-rate.ts (renamed from server/models/user-video-rate.js)11
-rw-r--r--server/models/user.ts (renamed from server/models/user.js)35
-rw-r--r--server/models/utils.ts (renamed from server/models/utils.js)10
-rw-r--r--server/models/video-abuse.ts (renamed from server/models/video-abuse.js)16
-rw-r--r--server/models/video-blacklist.ts (renamed from server/models/video-blacklist.js)6
-rw-r--r--server/models/video-tag.ts (renamed from server/models/video-tag.js)4
-rw-r--r--server/models/video.ts (renamed from server/models/video.js)155
-rw-r--r--tsconfig.json19
-rw-r--r--tslint.json3
-rw-r--r--yarn.lock166
113 files changed, 1982 insertions, 1805 deletions
diff --git a/.gitignore b/.gitignore
index 28dec58f3..6caee2e4c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,4 @@
16/ffmpeg/ 16/ffmpeg/
17/*.sublime-project 17/*.sublime-project
18/*.sublime-workspace 18/*.sublime-workspace
19/dist
diff --git a/package.json b/package.json
index 9c63c67b4..00d0bb5ee 100644
--- a/package.json
+++ b/package.json
@@ -70,15 +70,31 @@
70 "safe-buffer": "^5.0.1", 70 "safe-buffer": "^5.0.1",
71 "scripty": "^1.5.0", 71 "scripty": "^1.5.0",
72 "sequelize": "^3.27.0", 72 "sequelize": "^3.27.0",
73 "typescript": "~2.2.0",
73 "winston": "^2.1.1", 74 "winston": "^2.1.1",
74 "ws": "^2.0.0" 75 "ws": "^2.0.0"
75 }, 76 },
76 "devDependencies": { 77 "devDependencies": {
78 "@types/async": "^2.0.40",
79 "@types/bcrypt": "^1.0.0",
80 "@types/body-parser": "^1.16.3",
81 "@types/config": "^0.0.32",
82 "@types/express": "^4.0.35",
83 "@types/lodash": "^4.14.64",
84 "@types/mkdirp": "^0.3.29",
85 "@types/morgan": "^1.7.32",
86 "@types/node": "^7.0.18",
87 "@types/request": "^0.0.43",
88 "@types/sequelize": "3",
89 "@types/winston": "^2.3.2",
90 "@types/ws": "^0.0.41",
77 "chai": "^3.3.0", 91 "chai": "^3.3.0",
78 "commander": "^2.9.0", 92 "commander": "^2.9.0",
79 "mocha": "^3.0.1", 93 "mocha": "^3.0.1",
80 "standard": "^10.0.0", 94 "standard": "^10.0.0",
81 "supertest": "^3.0.0", 95 "supertest": "^3.0.0",
96 "tslint": "^5.2.0",
97 "tslint-config-standard": "^5.0.2",
82 "webtorrent": "^0.98.0" 98 "webtorrent": "^0.98.0"
83 }, 99 },
84 "standard": { 100 "standard": {
diff --git a/server.js b/server.ts
index b2487b767..119c0c61d 100644
--- a/server.js
+++ b/server.ts
@@ -1,14 +1,14 @@
1'use strict'
2
3// ----------- Node modules ----------- 1// ----------- Node modules -----------
4const bodyParser = require('body-parser') 2import bodyParser = require('body-parser')
5const express = require('express') 3import express = require('express')
6const expressValidator = require('express-validator') 4const expressValidator = require('express-validator')
7const http = require('http') 5import http = require('http')
8const morgan = require('morgan') 6import morgan = require('morgan')
9const path = require('path') 7import path = require('path')
10const TrackerServer = require('bittorrent-tracker').Server 8import bittorrentTracker = require('bittorrent-tracker')
11const WebSocketServer = require('ws').Server 9import { Server as WebSocketServer } from 'ws'
10
11const TrackerServer = bittorrentTracker.Server
12 12
13process.title = 'peertube' 13process.title = 'peertube'
14 14
@@ -16,70 +16,62 @@ process.title = 'peertube'
16const app = express() 16const app = express()
17 17
18// ----------- Database ----------- 18// ----------- Database -----------
19const constants = require('./server/initializers/constants') 19// Do not use barels because we don't want to load all modules here (we need to initialize database first)
20const logger = require('./server/helpers/logger') 20import { logger } from './server/helpers/logger'
21import { API_VERSION, CONFIG } from './server/initializers/constants'
21// Initialize database and models 22// Initialize database and models
22const db = require('./server/initializers/database') 23const db = require('./server/initializers/database')
23db.init(onDatabaseInitDone) 24db.init(onDatabaseInitDone)
24 25
25// ----------- Checker ----------- 26// ----------- Checker -----------
26const checker = require('./server/initializers/checker') 27import { checkMissedConfig, checkFFmpeg, checkConfig } from './server/initializers/checker'
27 28
28const missed = checker.checkMissedConfig() 29const missed = checkMissedConfig()
29if (missed.length !== 0) { 30if (missed.length !== 0) {
30 throw new Error('Miss some configurations keys : ' + missed) 31 throw new Error('Miss some configurations keys : ' + missed)
31} 32}
32checker.checkFFmpeg(function (err) { 33checkFFmpeg(function (err) {
33 if (err) { 34 if (err) {
34 throw err 35 throw err
35 } 36 }
36}) 37})
37 38
38const errorMessage = checker.checkConfig() 39const errorMessage = checkConfig()
39if (errorMessage !== null) { 40if (errorMessage !== null) {
40 throw new Error(errorMessage) 41 throw new Error(errorMessage)
41} 42}
42 43
43// ----------- PeerTube modules ----------- 44// ----------- PeerTube modules -----------
44const customValidators = require('./server/helpers/custom-validators') 45import { migrate, installApplication } from './server/initializers'
45const friends = require('./server/lib/friends') 46import { JobScheduler, activateSchedulers } from './server/lib'
46const installer = require('./server/initializers/installer') 47import * as customValidators from './server/helpers/custom-validators'
47const migrator = require('./server/initializers/migrator') 48import { apiRouter, clientsRouter, staticRouter } from './server/controllers'
48const jobScheduler = require('./server/lib/jobs/job-scheduler')
49const routes = require('./server/controllers')
50 49
51// ----------- Command line ----------- 50// ----------- Command line -----------
52 51
53// ----------- App ----------- 52// ----------- App -----------
54 53
55// For the logger 54// For the logger
56app.use(morgan('combined', { stream: logger.stream })) 55// app.use(morgan('combined', { stream: logger.stream }))
57// For body requests 56// For body requests
58app.use(bodyParser.json({ limit: '500kb' })) 57app.use(bodyParser.json({ limit: '500kb' }))
59app.use(bodyParser.urlencoded({ extended: false })) 58app.use(bodyParser.urlencoded({ extended: false }))
60// Validate some params for the API 59// Validate some params for the API
61app.use(expressValidator({ 60app.use(expressValidator({
62 customValidators: Object.assign( 61 customValidators: customValidators
63 {},
64 customValidators.misc,
65 customValidators.pods,
66 customValidators.users,
67 customValidators.videos,
68 customValidators.remote.videos
69 )
70})) 62}))
71 63
72// ----------- Views, routes and static files ----------- 64// ----------- Views, routes and static files -----------
73 65
74// API 66// API
75const apiRoute = '/api/' + constants.API_VERSION 67const apiRoute = '/api/' + API_VERSION
76app.use(apiRoute, routes.api) 68app.use(apiRoute, apiRouter)
77 69
78// Client files 70// Client files
79app.use('/', routes.client) 71app.use('/', clientsRouter)
80 72
81// Static files 73// Static files
82app.use('/', routes.static) 74app.use('/', staticRouter)
83 75
84// Always serve index client page (the client is a single page application, let it handle routing) 76// Always serve index client page (the client is a single page application, let it handle routing)
85app.use('/*', function (req, res, next) { 77app.use('/*', function (req, res, next) {
@@ -104,7 +96,7 @@ trackerServer.on('warning', function (err) {
104}) 96})
105 97
106const server = http.createServer(app) 98const server = http.createServer(app)
107const wss = new WebSocketServer({server: server, path: '/tracker/socket'}) 99const wss = new WebSocketServer({ server: server, path: '/tracker/socket' })
108wss.on('connection', function (ws) { 100wss.on('connection', function (ws) {
109 trackerServer.onWebSocketConnection(ws) 101 trackerServer.onWebSocketConnection(ws)
110}) 102})
@@ -114,7 +106,7 @@ wss.on('connection', function (ws) {
114// Catch 404 and forward to error handler 106// Catch 404 and forward to error handler
115app.use(function (req, res, next) { 107app.use(function (req, res, next) {
116 const err = new Error('Not Found') 108 const err = new Error('Not Found')
117 err.status = 404 109 err['status'] = 404
118 next(err) 110 next(err)
119}) 111})
120 112
@@ -126,29 +118,25 @@ app.use(function (err, req, res, next) {
126// ----------- Run ----------- 118// ----------- Run -----------
127 119
128function onDatabaseInitDone () { 120function onDatabaseInitDone () {
129 const port = constants.CONFIG.LISTEN.PORT 121 const port = CONFIG.LISTEN.PORT
130 // Run the migration scripts if needed 122 // Run the migration scripts if needed
131 migrator.migrate(function (err) { 123 migrate(function (err) {
132 if (err) throw err 124 if (err) throw err
133 125
134 installer.installApplication(function (err) { 126 installApplication(function (err) {
135 if (err) throw err 127 if (err) throw err
136 128
137 // ----------- Make the server listening ----------- 129 // ----------- Make the server listening -----------
138 server.listen(port, function () { 130 server.listen(port, function () {
139 // Activate the communication with friends 131 // Activate the communication with friends
140 friends.activate() 132 activateSchedulers()
141 133
142 // Activate job scheduler 134 // Activate job scheduler
143 jobScheduler.activate() 135 JobScheduler.Instance.activate()
144 136
145 logger.info('Server listening on port %d', port) 137 logger.info('Server listening on port %d', port)
146 logger.info('Webserver: %s', constants.CONFIG.WEBSERVER.URL) 138 logger.info('Webserver: %s', CONFIG.WEBSERVER.URL)
147
148 app.emit('ready')
149 }) 139 })
150 }) 140 })
151 }) 141 })
152} 142}
153
154module.exports = app
diff --git a/server/controllers/api/clients.js b/server/controllers/api/clients.ts
index cf83cb835..902f62995 100644
--- a/server/controllers/api/clients.js
+++ b/server/controllers/api/clients.ts
@@ -1,19 +1,17 @@
1'use strict' 1import express = require('express')
2 2
3const express = require('express') 3import { CONFIG } from '../../initializers';
4 4import { logger } from '../../helpers'
5const constants = require('../../initializers/constants')
6const db = require('../../initializers/database') 5const db = require('../../initializers/database')
7const logger = require('../../helpers/logger')
8 6
9const router = express.Router() 7const clientsRouter = express.Router()
10 8
11router.get('/local', getLocalClient) 9clientsRouter.get('/local', getLocalClient)
12 10
13// Get the client credentials for the PeerTube front end 11// Get the client credentials for the PeerTube front end
14function getLocalClient (req, res, next) { 12function getLocalClient (req, res, next) {
15 const serverHostname = constants.CONFIG.WEBSERVER.HOSTNAME 13 const serverHostname = CONFIG.WEBSERVER.HOSTNAME
16 const serverPort = constants.CONFIG.WEBSERVER.PORT 14 const serverPort = CONFIG.WEBSERVER.PORT
17 let headerHostShouldBe = serverHostname 15 let headerHostShouldBe = serverHostname
18 if (serverPort !== 80 && serverPort !== 443) { 16 if (serverPort !== 80 && serverPort !== 443) {
19 headerHostShouldBe += ':' + serverPort 17 headerHostShouldBe += ':' + serverPort
@@ -38,4 +36,6 @@ function getLocalClient (req, res, next) {
38 36
39// --------------------------------------------------------------------------- 37// ---------------------------------------------------------------------------
40 38
41module.exports = router 39export {
40 clientsRouter
41}
diff --git a/server/controllers/api/config.js b/server/controllers/api/config.js
deleted file mode 100644
index 8154b6ad0..000000000
--- a/server/controllers/api/config.js
+++ /dev/null
@@ -1,22 +0,0 @@
1'use strict'
2
3const express = require('express')
4
5const constants = require('../../initializers/constants')
6
7const router = express.Router()
8
9router.get('/', getConfig)
10
11// Get the client credentials for the PeerTube front end
12function getConfig (req, res, next) {
13 res.json({
14 signup: {
15 enabled: constants.CONFIG.SIGNUP.ENABLED
16 }
17 })
18}
19
20// ---------------------------------------------------------------------------
21
22module.exports = router
diff --git a/server/controllers/api/config.ts b/server/controllers/api/config.ts
new file mode 100644
index 000000000..8f3fa2473
--- /dev/null
+++ b/server/controllers/api/config.ts
@@ -0,0 +1,22 @@
1import express = require('express')
2
3import { CONFIG } from '../../initializers';
4
5const configRouter = express.Router()
6
7configRouter.get('/', getConfig)
8
9// Get the client credentials for the PeerTube front end
10function getConfig (req, res, next) {
11 res.json({
12 signup: {
13 enabled: CONFIG.SIGNUP.ENABLED
14 }
15 })
16}
17
18// ---------------------------------------------------------------------------
19
20export {
21 configRouter
22}
diff --git a/server/controllers/api/index.js b/server/controllers/api/index.js
deleted file mode 100644
index 6edc089f4..000000000
--- a/server/controllers/api/index.js
+++ /dev/null
@@ -1,35 +0,0 @@
1'use strict'
2
3const express = require('express')
4
5const utils = require('../../helpers/utils')
6
7const router = express.Router()
8
9const clientsController = require('./clients')
10const configController = require('./config')
11const podsController = require('./pods')
12const remoteController = require('./remote')
13const requestsController = require('./requests')
14const usersController = require('./users')
15const videosController = require('./videos')
16
17router.use('/clients', clientsController)
18router.use('/config', configController)
19router.use('/pods', podsController)
20router.use('/remote', remoteController)
21router.use('/requests', requestsController)
22router.use('/users', usersController)
23router.use('/videos', videosController)
24router.use('/ping', pong)
25router.use('/*', utils.badRequest)
26
27// ---------------------------------------------------------------------------
28
29module.exports = router
30
31// ---------------------------------------------------------------------------
32
33function pong (req, res, next) {
34 return res.send('pong').status(200).end()
35}
diff --git a/server/controllers/api/index.ts b/server/controllers/api/index.ts
new file mode 100644
index 000000000..18bef2d3d
--- /dev/null
+++ b/server/controllers/api/index.ts
@@ -0,0 +1,33 @@
1import express = require('express')
2
3import { badRequest } from '../../helpers'
4
5import { clientsRouter } from './clients'
6import { configRouter } from './config'
7import { podsRouter } from './pods'
8import { remoteRouter } from './remote'
9import { requestsRouter } from './requests'
10import { usersRouter } from './users'
11import { videosRouter } from './videos'
12
13const apiRouter = express.Router()
14
15apiRouter.use('/clients', clientsRouter)
16apiRouter.use('/config', configRouter)
17apiRouter.use('/pods', podsRouter)
18apiRouter.use('/remote', remoteRouter)
19apiRouter.use('/requests', requestsRouter)
20apiRouter.use('/users', usersRouter)
21apiRouter.use('/videos', videosRouter)
22apiRouter.use('/ping', pong)
23apiRouter.use('/*', badRequest)
24
25// ---------------------------------------------------------------------------
26
27export { apiRouter }
28
29// ---------------------------------------------------------------------------
30
31function pong (req, res, next) {
32 return res.send('pong').status(200).end()
33}
diff --git a/server/controllers/api/pods.js b/server/controllers/api/pods.js
deleted file mode 100644
index ab5763cf6..000000000
--- a/server/controllers/api/pods.js
+++ /dev/null
@@ -1,109 +0,0 @@
1'use strict'
2
3const express = require('express')
4const waterfall = require('async/waterfall')
5
6const db = require('../../initializers/database')
7const constants = require('../../initializers/constants')
8const logger = require('../../helpers/logger')
9const peertubeCrypto = require('../../helpers/peertube-crypto')
10const utils = require('../../helpers/utils')
11const friends = require('../../lib/friends')
12const middlewares = require('../../middlewares')
13const admin = middlewares.admin
14const oAuth = middlewares.oauth
15const podsMiddleware = middlewares.pods
16const validators = middlewares.validators.pods
17
18const router = express.Router()
19
20router.get('/', listPods)
21router.post('/',
22 podsMiddleware.setBodyHostPort, // We need to modify the host before running the validator!
23 validators.podsAdd,
24 addPods
25)
26router.post('/makefriends',
27 oAuth.authenticate,
28 admin.ensureIsAdmin,
29 validators.makeFriends,
30 podsMiddleware.setBodyHostsPort,
31 makeFriends
32)
33router.get('/quitfriends',
34 oAuth.authenticate,
35 admin.ensureIsAdmin,
36 quitFriends
37)
38
39// ---------------------------------------------------------------------------
40
41module.exports = router
42
43// ---------------------------------------------------------------------------
44
45function addPods (req, res, next) {
46 const informations = req.body
47
48 waterfall([
49 function addPod (callback) {
50 const pod = db.Pod.build(informations)
51 pod.save().asCallback(function (err, podCreated) {
52 // Be sure about the number of parameters for the callback
53 return callback(err, podCreated)
54 })
55 },
56
57 function sendMyVideos (podCreated, callback) {
58 friends.sendOwnedVideosToPod(podCreated.id)
59
60 callback(null)
61 },
62
63 function fetchMyCertificate (callback) {
64 peertubeCrypto.getMyPublicCert(function (err, cert) {
65 if (err) {
66 logger.error('Cannot read cert file.')
67 return callback(err)
68 }
69
70 return callback(null, cert)
71 })
72 }
73 ], function (err, cert) {
74 if (err) return next(err)
75
76 return res.json({ cert: cert, email: constants.CONFIG.ADMIN.EMAIL })
77 })
78}
79
80function listPods (req, res, next) {
81 db.Pod.list(function (err, podsList) {
82 if (err) return next(err)
83
84 res.json(utils.getFormatedObjects(podsList, podsList.length))
85 })
86}
87
88function makeFriends (req, res, next) {
89 const hosts = req.body.hosts
90
91 friends.makeFriends(hosts, function (err) {
92 if (err) {
93 logger.error('Could not make friends.', { error: err })
94 return
95 }
96
97 logger.info('Made friends!')
98 })
99
100 res.type('json').status(204).end()
101}
102
103function quitFriends (req, res, next) {
104 friends.quitFriends(function (err) {
105 if (err) return next(err)
106
107 res.type('json').status(204).end()
108 })
109}
diff --git a/server/controllers/api/pods.ts b/server/controllers/api/pods.ts
new file mode 100644
index 000000000..06dfd8295
--- /dev/null
+++ b/server/controllers/api/pods.ts
@@ -0,0 +1,118 @@
1import express = require('express')
2import { waterfall } from 'async'
3
4const db = require('../../initializers/database')
5import { CONFIG } from '../../initializers'
6import {
7 logger,
8 getMyPublicCert,
9 getFormatedObjects
10} from '../../helpers'
11import {
12 sendOwnedVideosToPod,
13 makeFriends,
14 quitFriends
15} from '../../lib'
16import {
17 podsAddValidator,
18 authenticate,
19 ensureIsAdmin,
20 makeFriendsValidator,
21 setBodyHostPort,
22 setBodyHostsPort
23} from '../../middlewares'
24
25const podsRouter = express.Router()
26
27podsRouter.get('/', listPods)
28podsRouter.post('/',
29 setBodyHostPort, // We need to modify the host before running the validator!
30 podsAddValidator,
31 addPods
32)
33podsRouter.post('/makefriends',
34 authenticate,
35 ensureIsAdmin,
36 makeFriendsValidator,
37 setBodyHostsPort,
38 makeFriends
39)
40podsRouter.get('/quitfriends',
41 authenticate,
42 ensureIsAdmin,
43 quitFriends
44)
45
46// ---------------------------------------------------------------------------
47
48export {
49 podsRouter
50}
51
52// ---------------------------------------------------------------------------
53
54function addPods (req, res, next) {
55 const informations = req.body
56
57 waterfall([
58 function addPod (callback) {
59 const pod = db.Pod.build(informations)
60 pod.save().asCallback(function (err, podCreated) {
61 // Be sure about the number of parameters for the callback
62 return callback(err, podCreated)
63 })
64 },
65
66 function sendMyVideos (podCreated, callback) {
67 sendOwnedVideosToPod(podCreated.id)
68
69 callback(null)
70 },
71
72 function fetchMyCertificate (callback) {
73 getMyPublicCert(function (err, cert) {
74 if (err) {
75 logger.error('Cannot read cert file.')
76 return callback(err)
77 }
78
79 return callback(null, cert)
80 })
81 }
82 ], function (err, cert) {
83 if (err) return next(err)
84
85 return res.json({ cert: cert, email: CONFIG.ADMIN.EMAIL })
86 })
87}
88
89function listPods (req, res, next) {
90 db.Pod.list(function (err, podsList) {
91 if (err) return next(err)
92
93 res.json(getFormatedObjects(podsList, podsList.length))
94 })
95}
96
97function makeFriendsController (req, res, next) {
98 const hosts = req.body.hosts
99
100 makeFriends(hosts, function (err) {
101 if (err) {
102 logger.error('Could not make friends.', { error: err })
103 return
104 }
105
106 logger.info('Made friends!')
107 })
108
109 res.type('json').status(204).end()
110}
111
112function quitFriendsController (req, res, next) {
113 quitFriends(function (err) {
114 if (err) return next(err)
115
116 res.type('json').status(204).end()
117 })
118}
diff --git a/server/controllers/api/remote/index.js b/server/controllers/api/remote/index.js
deleted file mode 100644
index 6106850ab..000000000
--- a/server/controllers/api/remote/index.js
+++ /dev/null
@@ -1,18 +0,0 @@
1'use strict'
2
3const express = require('express')
4
5const utils = require('../../../helpers/utils')
6
7const router = express.Router()
8
9const podsRemoteController = require('./pods')
10const videosRemoteController = require('./videos')
11
12router.use('/pods', podsRemoteController)
13router.use('/videos', videosRemoteController)
14router.use('/*', utils.badRequest)
15
16// ---------------------------------------------------------------------------
17
18module.exports = router
diff --git a/server/controllers/api/remote/index.ts b/server/controllers/api/remote/index.ts
new file mode 100644
index 000000000..b11439204
--- /dev/null
+++ b/server/controllers/api/remote/index.ts
@@ -0,0 +1,18 @@
1import express = require('express')
2
3import { badRequest } from '../../../helpers'
4
5import { remotePodsRouter } from './pods'
6import { remoteVideosRouter } from './videos'
7
8const remoteRouter = express.Router()
9
10remoteRouter.use('/pods', remotePodsRouter)
11remoteRouter.use('/videos', remoteVideosRouter)
12remoteRouter.use('/*', badRequest)
13
14// ---------------------------------------------------------------------------
15
16export {
17 remoteRouter
18}
diff --git a/server/controllers/api/remote/pods.js b/server/controllers/api/remote/pods.ts
index 0343bc62e..85ef7bb42 100644
--- a/server/controllers/api/remote/pods.js
+++ b/server/controllers/api/remote/pods.ts
@@ -1,25 +1,23 @@
1'use strict' 1import express = require('express')
2 2import { waterfall } from 'async/waterfall'
3const express = require('express')
4const waterfall = require('async/waterfall')
5 3
6const db = require('../../../initializers/database') 4const db = require('../../../initializers/database')
7const middlewares = require('../../../middlewares') 5import { checkSignature, signatureValidator } from '../../../middlewares'
8const checkSignature = middlewares.secure.checkSignature
9const signatureValidator = middlewares.validators.remote.signature
10 6
11const router = express.Router() 7const remotePodsRouter = express.Router()
12 8
13// Post because this is a secured request 9// Post because this is a secured request
14router.post('/remove', 10remotePodsRouter.post('/remove',
15 signatureValidator.signature, 11 signatureValidator,
16 checkSignature, 12 checkSignature,
17 removePods 13 removePods
18) 14)
19 15
20// --------------------------------------------------------------------------- 16// ---------------------------------------------------------------------------
21 17
22module.exports = router 18export {
19 remotePodsRouter
20}
23 21
24// --------------------------------------------------------------------------- 22// ---------------------------------------------------------------------------
25 23
diff --git a/server/controllers/api/remote/videos.js b/server/controllers/api/remote/videos.ts
index e54793628..df4ba8309 100644
--- a/server/controllers/api/remote/videos.js
+++ b/server/controllers/api/remote/videos.ts
@@ -1,20 +1,30 @@
1'use strict' 1import express = require('express')
2 2import { eachSeries, waterfall } from 'async'
3const eachSeries = require('async/eachSeries')
4const express = require('express')
5const waterfall = require('async/waterfall')
6 3
7const db = require('../../../initializers/database') 4const db = require('../../../initializers/database')
8const constants = require('../../../initializers/constants') 5import {
9const middlewares = require('../../../middlewares') 6 REQUEST_ENDPOINT_ACTIONS,
10const secureMiddleware = middlewares.secure 7 REQUEST_ENDPOINTS,
11const videosValidators = middlewares.validators.remote.videos 8 REQUEST_VIDEO_EVENT_TYPES,
12const signatureValidators = middlewares.validators.remote.signature 9 REQUEST_VIDEO_QADU_TYPES
13const logger = require('../../../helpers/logger') 10} from '../../../initializers'
14const friends = require('../../../lib/friends') 11import {
15const databaseUtils = require('../../../helpers/database-utils') 12 checkSignature,
16 13 signatureValidator,
17const ENDPOINT_ACTIONS = constants.REQUEST_ENDPOINT_ACTIONS[constants.REQUEST_ENDPOINTS.VIDEOS] 14 remoteVideosValidator,
15 remoteQaduVideosValidator,
16 remoteEventsVideosValidator
17} from '../../../middlewares'
18import {
19 logger,
20 commitTransaction,
21 retryTransactionWrapper,
22 rollbackTransaction,
23 startSerializableTransaction
24} from '../../../helpers'
25import { quickAndDirtyUpdatesVideoToFriends } from '../../../lib'
26
27const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS]
18 28
19// Functions to call when processing a remote request 29// Functions to call when processing a remote request
20const functionsHash = {} 30const functionsHash = {}
@@ -23,32 +33,34 @@ functionsHash[ENDPOINT_ACTIONS.UPDATE] = updateRemoteVideoRetryWrapper
23functionsHash[ENDPOINT_ACTIONS.REMOVE] = removeRemoteVideo 33functionsHash[ENDPOINT_ACTIONS.REMOVE] = removeRemoteVideo
24functionsHash[ENDPOINT_ACTIONS.REPORT_ABUSE] = reportAbuseRemoteVideo 34functionsHash[ENDPOINT_ACTIONS.REPORT_ABUSE] = reportAbuseRemoteVideo
25 35
26const router = express.Router() 36const remoteVideosRouter = express.Router()
27 37
28router.post('/', 38remoteVideosRouter.post('/',
29 signatureValidators.signature, 39 signatureValidator,
30 secureMiddleware.checkSignature, 40 checkSignature,
31 videosValidators.remoteVideos, 41 remoteVideosValidator,
32 remoteVideos 42 remoteVideos
33) 43)
34 44
35router.post('/qadu', 45remoteVideosRouter.post('/qadu',
36 signatureValidators.signature, 46 signatureValidator,
37 secureMiddleware.checkSignature, 47 checkSignature,
38 videosValidators.remoteQaduVideos, 48 remoteQaduVideosValidator,
39 remoteVideosQadu 49 remoteVideosQadu
40) 50)
41 51
42router.post('/events', 52remoteVideosRouter.post('/events',
43 signatureValidators.signature, 53 signatureValidator,
44 secureMiddleware.checkSignature, 54 checkSignature,
45 videosValidators.remoteEventsVideos, 55 remoteEventsVideosValidator,
46 remoteVideosEvents 56 remoteVideosEvents
47) 57)
48 58
49// --------------------------------------------------------------------------- 59// ---------------------------------------------------------------------------
50 60
51module.exports = router 61export {
62 remoteVideosRouter
63}
52 64
53// --------------------------------------------------------------------------- 65// ---------------------------------------------------------------------------
54 66
@@ -58,7 +70,7 @@ function remoteVideos (req, res, next) {
58 70
59 // We need to process in the same order to keep consistency 71 // We need to process in the same order to keep consistency
60 // TODO: optimization 72 // TODO: optimization
61 eachSeries(requests, function (request, callbackEach) { 73 eachSeries(requests, function (request: any, callbackEach) {
62 const data = request.data 74 const data = request.data
63 75
64 // Get the function we need to call in order to process the request 76 // Get the function we need to call in order to process the request
@@ -81,7 +93,7 @@ function remoteVideosQadu (req, res, next) {
81 const requests = req.body.data 93 const requests = req.body.data
82 const fromPod = res.locals.secure.pod 94 const fromPod = res.locals.secure.pod
83 95
84 eachSeries(requests, function (request, callbackEach) { 96 eachSeries(requests, function (request: any, callbackEach) {
85 const videoData = request.data 97 const videoData = request.data
86 98
87 quickAndDirtyUpdateVideoRetryWrapper(videoData, fromPod, callbackEach) 99 quickAndDirtyUpdateVideoRetryWrapper(videoData, fromPod, callbackEach)
@@ -96,7 +108,7 @@ function remoteVideosEvents (req, res, next) {
96 const requests = req.body.data 108 const requests = req.body.data
97 const fromPod = res.locals.secure.pod 109 const fromPod = res.locals.secure.pod
98 110
99 eachSeries(requests, function (request, callbackEach) { 111 eachSeries(requests, function (request: any, callbackEach) {
100 const eventData = request.data 112 const eventData = request.data
101 113
102 processVideosEventsRetryWrapper(eventData, fromPod, callbackEach) 114 processVideosEventsRetryWrapper(eventData, fromPod, callbackEach)
@@ -113,12 +125,12 @@ function processVideosEventsRetryWrapper (eventData, fromPod, finalCallback) {
113 errorMessage: 'Cannot process videos events with many retries.' 125 errorMessage: 'Cannot process videos events with many retries.'
114 } 126 }
115 127
116 databaseUtils.retryTransactionWrapper(processVideosEvents, options, finalCallback) 128 retryTransactionWrapper(processVideosEvents, options, finalCallback)
117} 129}
118 130
119function processVideosEvents (eventData, fromPod, finalCallback) { 131function processVideosEvents (eventData, fromPod, finalCallback) {
120 waterfall([ 132 waterfall([
121 databaseUtils.startSerializableTransaction, 133 startSerializableTransaction,
122 134
123 function findVideo (t, callback) { 135 function findVideo (t, callback) {
124 fetchOwnedVideo(eventData.remoteId, function (err, videoInstance) { 136 fetchOwnedVideo(eventData.remoteId, function (err, videoInstance) {
@@ -133,19 +145,19 @@ function processVideosEvents (eventData, fromPod, finalCallback) {
133 let qaduType 145 let qaduType
134 146
135 switch (eventData.eventType) { 147 switch (eventData.eventType) {
136 case constants.REQUEST_VIDEO_EVENT_TYPES.VIEWS: 148 case REQUEST_VIDEO_EVENT_TYPES.VIEWS:
137 columnToUpdate = 'views' 149 columnToUpdate = 'views'
138 qaduType = constants.REQUEST_VIDEO_QADU_TYPES.VIEWS 150 qaduType = REQUEST_VIDEO_QADU_TYPES.VIEWS
139 break 151 break
140 152
141 case constants.REQUEST_VIDEO_EVENT_TYPES.LIKES: 153 case REQUEST_VIDEO_EVENT_TYPES.LIKES:
142 columnToUpdate = 'likes' 154 columnToUpdate = 'likes'
143 qaduType = constants.REQUEST_VIDEO_QADU_TYPES.LIKES 155 qaduType = REQUEST_VIDEO_QADU_TYPES.LIKES
144 break 156 break
145 157
146 case constants.REQUEST_VIDEO_EVENT_TYPES.DISLIKES: 158 case REQUEST_VIDEO_EVENT_TYPES.DISLIKES:
147 columnToUpdate = 'dislikes' 159 columnToUpdate = 'dislikes'
148 qaduType = constants.REQUEST_VIDEO_QADU_TYPES.DISLIKES 160 qaduType = REQUEST_VIDEO_QADU_TYPES.DISLIKES
149 break 161 break
150 162
151 default: 163 default:
@@ -168,17 +180,17 @@ function processVideosEvents (eventData, fromPod, finalCallback) {
168 } 180 }
169 ] 181 ]
170 182
171 friends.quickAndDirtyUpdatesVideoToFriends(qadusParams, t, function (err) { 183 quickAndDirtyUpdatesVideoToFriends(qadusParams, t, function (err) {
172 return callback(err, t) 184 return callback(err, t)
173 }) 185 })
174 }, 186 },
175 187
176 databaseUtils.commitTransaction 188 commitTransaction
177 189
178 ], function (err, t) { 190 ], function (err, t) {
179 if (err) { 191 if (err) {
180 logger.debug('Cannot process a video event.', { error: err }) 192 logger.debug('Cannot process a video event.', { error: err })
181 return databaseUtils.rollbackTransaction(err, t, finalCallback) 193 return rollbackTransaction(err, t, finalCallback)
182 } 194 }
183 195
184 logger.info('Remote video event processed for video %s.', eventData.remoteId) 196 logger.info('Remote video event processed for video %s.', eventData.remoteId)
@@ -192,14 +204,14 @@ function quickAndDirtyUpdateVideoRetryWrapper (videoData, fromPod, finalCallback
192 errorMessage: 'Cannot update quick and dirty the remote video with many retries.' 204 errorMessage: 'Cannot update quick and dirty the remote video with many retries.'
193 } 205 }
194 206
195 databaseUtils.retryTransactionWrapper(quickAndDirtyUpdateVideo, options, finalCallback) 207 retryTransactionWrapper(quickAndDirtyUpdateVideo, options, finalCallback)
196} 208}
197 209
198function quickAndDirtyUpdateVideo (videoData, fromPod, finalCallback) { 210function quickAndDirtyUpdateVideo (videoData, fromPod, finalCallback) {
199 let videoName 211 let videoName
200 212
201 waterfall([ 213 waterfall([
202 databaseUtils.startSerializableTransaction, 214 startSerializableTransaction,
203 215
204 function findVideo (t, callback) { 216 function findVideo (t, callback) {
205 fetchRemoteVideo(fromPod.host, videoData.remoteId, function (err, videoInstance) { 217 fetchRemoteVideo(fromPod.host, videoData.remoteId, function (err, videoInstance) {
@@ -229,12 +241,12 @@ function quickAndDirtyUpdateVideo (videoData, fromPod, finalCallback) {
229 }) 241 })
230 }, 242 },
231 243
232 databaseUtils.commitTransaction 244 commitTransaction
233 245
234 ], function (err, t) { 246 ], function (err, t) {
235 if (err) { 247 if (err) {
236 logger.debug('Cannot quick and dirty update the remote video.', { error: err }) 248 logger.debug('Cannot quick and dirty update the remote video.', { error: err })
237 return databaseUtils.rollbackTransaction(err, t, finalCallback) 249 return rollbackTransaction(err, t, finalCallback)
238 } 250 }
239 251
240 logger.info('Remote video %s quick and dirty updated', videoName) 252 logger.info('Remote video %s quick and dirty updated', videoName)
@@ -249,7 +261,7 @@ function addRemoteVideoRetryWrapper (videoToCreateData, fromPod, finalCallback)
249 errorMessage: 'Cannot insert the remote video with many retries.' 261 errorMessage: 'Cannot insert the remote video with many retries.'
250 } 262 }
251 263
252 databaseUtils.retryTransactionWrapper(addRemoteVideo, options, finalCallback) 264 retryTransactionWrapper(addRemoteVideo, options, finalCallback)
253} 265}
254 266
255function addRemoteVideo (videoToCreateData, fromPod, finalCallback) { 267function addRemoteVideo (videoToCreateData, fromPod, finalCallback) {
@@ -257,7 +269,7 @@ function addRemoteVideo (videoToCreateData, fromPod, finalCallback) {
257 269
258 waterfall([ 270 waterfall([
259 271
260 databaseUtils.startSerializableTransaction, 272 startSerializableTransaction,
261 273
262 function assertRemoteIdAndHostUnique (t, callback) { 274 function assertRemoteIdAndHostUnique (t, callback) {
263 db.Video.loadByHostAndRemoteId(fromPod.host, videoToCreateData.remoteId, function (err, video) { 275 db.Video.loadByHostAndRemoteId(fromPod.host, videoToCreateData.remoteId, function (err, video) {
@@ -345,13 +357,13 @@ function addRemoteVideo (videoToCreateData, fromPod, finalCallback) {
345 }) 357 })
346 }, 358 },
347 359
348 databaseUtils.commitTransaction 360 commitTransaction
349 361
350 ], function (err, t) { 362 ], function (err, t) {
351 if (err) { 363 if (err) {
352 // This is just a debug because we will retry the insert 364 // This is just a debug because we will retry the insert
353 logger.debug('Cannot insert the remote video.', { error: err }) 365 logger.debug('Cannot insert the remote video.', { error: err })
354 return databaseUtils.rollbackTransaction(err, t, finalCallback) 366 return rollbackTransaction(err, t, finalCallback)
355 } 367 }
356 368
357 logger.info('Remote video %s inserted.', videoToCreateData.name) 369 logger.info('Remote video %s inserted.', videoToCreateData.name)
@@ -366,7 +378,7 @@ function updateRemoteVideoRetryWrapper (videoAttributesToUpdate, fromPod, finalC
366 errorMessage: 'Cannot update the remote video with many retries' 378 errorMessage: 'Cannot update the remote video with many retries'
367 } 379 }
368 380
369 databaseUtils.retryTransactionWrapper(updateRemoteVideo, options, finalCallback) 381 retryTransactionWrapper(updateRemoteVideo, options, finalCallback)
370} 382}
371 383
372function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) { 384function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) {
@@ -374,7 +386,7 @@ function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) {
374 386
375 waterfall([ 387 waterfall([
376 388
377 databaseUtils.startSerializableTransaction, 389 startSerializableTransaction,
378 390
379 function findVideo (t, callback) { 391 function findVideo (t, callback) {
380 fetchRemoteVideo(fromPod.host, videoAttributesToUpdate.remoteId, function (err, videoInstance) { 392 fetchRemoteVideo(fromPod.host, videoAttributesToUpdate.remoteId, function (err, videoInstance) {
@@ -421,13 +433,13 @@ function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) {
421 }) 433 })
422 }, 434 },
423 435
424 databaseUtils.commitTransaction 436 commitTransaction
425 437
426 ], function (err, t) { 438 ], function (err, t) {
427 if (err) { 439 if (err) {
428 // This is just a debug because we will retry the insert 440 // This is just a debug because we will retry the insert
429 logger.debug('Cannot update the remote video.', { error: err }) 441 logger.debug('Cannot update the remote video.', { error: err })
430 return databaseUtils.rollbackTransaction(err, t, finalCallback) 442 return rollbackTransaction(err, t, finalCallback)
431 } 443 }
432 444
433 logger.info('Remote video %s updated', videoAttributesToUpdate.name) 445 logger.info('Remote video %s updated', videoAttributesToUpdate.name)
diff --git a/server/controllers/api/requests.js b/server/controllers/api/requests.ts
index 6fd5753ac..304499a4f 100644
--- a/server/controllers/api/requests.js
+++ b/server/controllers/api/requests.ts
@@ -1,32 +1,34 @@
1'use strict' 1import express = require('express')
2import { parallel } from 'async'
2 3
3const express = require('express') 4import {
4const parallel = require('async/parallel') 5 getRequestScheduler,
6 getRequestVideoQaduScheduler,
7 getRequestVideoEventScheduler
8} from '../../lib'
9import { authenticate, ensureIsAdmin } from '../../middlewares'
5 10
6const friends = require('../../lib/friends') 11const requestsRouter = express.Router()
7const middlewares = require('../../middlewares')
8const admin = middlewares.admin
9const oAuth = middlewares.oauth
10 12
11const router = express.Router() 13requestsRouter.get('/stats',
12 14 authenticate,
13router.get('/stats', 15 ensureIsAdmin,
14 oAuth.authenticate,
15 admin.ensureIsAdmin,
16 getStatsRequests 16 getStatsRequests
17) 17)
18 18
19// --------------------------------------------------------------------------- 19// ---------------------------------------------------------------------------
20 20
21module.exports = router 21export {
22 requestsRouter
23}
22 24
23// --------------------------------------------------------------------------- 25// ---------------------------------------------------------------------------
24 26
25function getStatsRequests (req, res, next) { 27function getStatsRequests (req, res, next) {
26 parallel({ 28 parallel({
27 requestScheduler: buildRequestSchedulerFunction(friends.getRequestScheduler()), 29 requestScheduler: buildRequestSchedulerFunction(getRequestScheduler()),
28 requestVideoQaduScheduler: buildRequestSchedulerFunction(friends.getRequestVideoQaduScheduler()), 30 requestVideoQaduScheduler: buildRequestSchedulerFunction(getRequestVideoQaduScheduler()),
29 requestVideoEventScheduler: buildRequestSchedulerFunction(friends.getRequestVideoEventScheduler()) 31 requestVideoEventScheduler: buildRequestSchedulerFunction(getRequestVideoEventScheduler())
30 }, function (err, result) { 32 }, function (err, result) {
31 if (err) return next(err) 33 if (err) return next(err)
32 34
diff --git a/server/controllers/api/users.js b/server/controllers/api/users.ts
index c7fe7bf85..981a4706a 100644
--- a/server/controllers/api/users.js
+++ b/server/controllers/api/users.ts
@@ -1,79 +1,83 @@
1'use strict' 1import express = require('express')
2import { waterfall } from 'async'
2 3
3const express = require('express')
4const waterfall = require('async/waterfall')
5
6const constants = require('../../initializers/constants')
7const db = require('../../initializers/database') 4const db = require('../../initializers/database')
8const logger = require('../../helpers/logger') 5import { CONFIG, USER_ROLES } from '../../initializers'
9const utils = require('../../helpers/utils') 6import { logger, getFormatedObjects } from '../../helpers'
10const middlewares = require('../../middlewares') 7import {
11const admin = middlewares.admin 8 authenticate,
12const oAuth = middlewares.oauth 9 ensureIsAdmin,
13const pagination = middlewares.pagination 10 usersAddValidator,
14const sort = middlewares.sort 11 usersUpdateValidator,
15const validatorsPagination = middlewares.validators.pagination 12 usersRemoveValidator,
16const validatorsSort = middlewares.validators.sort 13 usersVideoRatingValidator,
17const validatorsUsers = middlewares.validators.users 14 paginationValidator,
18 15 setPagination,
19const router = express.Router() 16 usersSortValidator,
20 17 setUsersSort,
21router.get('/me', 18 token
22 oAuth.authenticate, 19} from '../../middlewares'
20
21const usersRouter = express.Router()
22
23usersRouter.get('/me',
24 authenticate,
23 getUserInformation 25 getUserInformation
24) 26)
25 27
26router.get('/me/videos/:videoId/rating', 28usersRouter.get('/me/videos/:videoId/rating',
27 oAuth.authenticate, 29 authenticate,
28 validatorsUsers.usersVideoRating, 30 usersVideoRatingValidator,
29 getUserVideoRating 31 getUserVideoRating
30) 32)
31 33
32router.get('/', 34usersRouter.get('/',
33 validatorsPagination.pagination, 35 paginationValidator,
34 validatorsSort.usersSort, 36 usersSortValidator,
35 sort.setUsersSort, 37 setUsersSort,
36 pagination.setPagination, 38 setPagination,
37 listUsers 39 listUsers
38) 40)
39 41
40router.post('/', 42usersRouter.post('/',
41 oAuth.authenticate, 43 authenticate,
42 admin.ensureIsAdmin, 44 ensureIsAdmin,
43 validatorsUsers.usersAdd, 45 usersAddValidator,
44 createUser 46 createUser
45) 47)
46 48
47router.post('/register', 49usersRouter.post('/register',
48 ensureRegistrationEnabled, 50 ensureRegistrationEnabled,
49 validatorsUsers.usersAdd, 51 usersAddValidator,
50 createUser 52 createUser
51) 53)
52 54
53router.put('/:id', 55usersRouter.put('/:id',
54 oAuth.authenticate, 56 authenticate,
55 validatorsUsers.usersUpdate, 57 usersUpdateValidator,
56 updateUser 58 updateUser
57) 59)
58 60
59router.delete('/:id', 61usersRouter.delete('/:id',
60 oAuth.authenticate, 62 authenticate,
61 admin.ensureIsAdmin, 63 ensureIsAdmin,
62 validatorsUsers.usersRemove, 64 usersRemoveValidator,
63 removeUser 65 removeUser
64) 66)
65 67
66router.post('/token', oAuth.token, success) 68usersRouter.post('/token', token, success)
67// TODO: Once https://github.com/oauthjs/node-oauth2-server/pull/289 is merged, implement revoke token route 69// TODO: Once https://github.com/oauthjs/node-oauth2-server/pull/289 is merged, implement revoke token route
68 70
69// --------------------------------------------------------------------------- 71// ---------------------------------------------------------------------------
70 72
71module.exports = router 73export {
74 usersRouter
75}
72 76
73// --------------------------------------------------------------------------- 77// ---------------------------------------------------------------------------
74 78
75function ensureRegistrationEnabled (req, res, next) { 79function ensureRegistrationEnabled (req, res, next) {
76 const registrationEnabled = constants.CONFIG.SIGNUP.ENABLED 80 const registrationEnabled = CONFIG.SIGNUP.ENABLED
77 81
78 if (registrationEnabled === true) { 82 if (registrationEnabled === true) {
79 return next() 83 return next()
@@ -88,7 +92,7 @@ function createUser (req, res, next) {
88 password: req.body.password, 92 password: req.body.password,
89 email: req.body.email, 93 email: req.body.email,
90 displayNSFW: false, 94 displayNSFW: false,
91 role: constants.USER_ROLES.USER 95 role: USER_ROLES.USER
92 }) 96 })
93 97
94 user.save().asCallback(function (err, createdUser) { 98 user.save().asCallback(function (err, createdUser) {
@@ -126,7 +130,7 @@ function listUsers (req, res, next) {
126 db.User.listForApi(req.query.start, req.query.count, req.query.sort, function (err, usersList, usersTotal) { 130 db.User.listForApi(req.query.start, req.query.count, req.query.sort, function (err, usersList, usersTotal) {
127 if (err) return next(err) 131 if (err) return next(err)
128 132
129 res.json(utils.getFormatedObjects(usersList, usersTotal)) 133 res.json(getFormatedObjects(usersList, usersTotal))
130 }) 134 })
131} 135}
132 136
diff --git a/server/controllers/api/videos/abuse.js b/server/controllers/api/videos/abuse.ts
index 0fb44bb14..88204120f 100644
--- a/server/controllers/api/videos/abuse.js
+++ b/server/controllers/api/videos/abuse.ts
@@ -1,43 +1,48 @@
1'use strict' 1import express = require('express')
2 2import { waterfall } from 'async'
3const express = require('express')
4const waterfall = require('async/waterfall')
5 3
6const db = require('../../../initializers/database') 4const db = require('../../../initializers/database')
7const logger = require('../../../helpers/logger') 5import friends = require('../../../lib/friends')
8const friends = require('../../../lib/friends') 6import {
9const middlewares = require('../../../middlewares') 7 logger,
10const admin = middlewares.admin 8 getFormatedObjects,
11const oAuth = middlewares.oauth 9 retryTransactionWrapper,
12const pagination = middlewares.pagination 10 startSerializableTransaction,
13const validators = middlewares.validators 11 commitTransaction,
14const validatorsPagination = validators.pagination 12 rollbackTransaction
15const validatorsSort = validators.sort 13} from '../../../helpers'
16const validatorsVideos = validators.videos 14import {
17const sort = middlewares.sort 15 authenticate,
18const databaseUtils = require('../../../helpers/database-utils') 16 ensureIsAdmin,
19const utils = require('../../../helpers/utils') 17 paginationValidator,
20 18 videoAbuseReportValidator,
21const router = express.Router() 19 videoAbusesSortValidator,
22 20 setVideoAbusesSort,
23router.get('/abuse', 21 setPagination
24 oAuth.authenticate, 22} from '../../../middlewares'
25 admin.ensureIsAdmin, 23
26 validatorsPagination.pagination, 24const abuseVideoRouter = express.Router()
27 validatorsSort.videoAbusesSort, 25
28 sort.setVideoAbusesSort, 26abuseVideoRouter.get('/abuse',
29 pagination.setPagination, 27 authenticate,
28 ensureIsAdmin,
29 paginationValidator,
30 videoAbusesSortValidator,
31 setVideoAbusesSort,
32 setPagination,
30 listVideoAbuses 33 listVideoAbuses
31) 34)
32router.post('/:id/abuse', 35abuseVideoRouter.post('/:id/abuse',
33 oAuth.authenticate, 36 authenticate,
34 validatorsVideos.videoAbuseReport, 37 videoAbuseReportValidator,
35 reportVideoAbuseRetryWrapper 38 reportVideoAbuseRetryWrapper
36) 39)
37 40
38// --------------------------------------------------------------------------- 41// ---------------------------------------------------------------------------
39 42
40module.exports = router 43export {
44 abuseVideoRouter
45}
41 46
42// --------------------------------------------------------------------------- 47// ---------------------------------------------------------------------------
43 48
@@ -45,7 +50,7 @@ function listVideoAbuses (req, res, next) {
45 db.VideoAbuse.listForApi(req.query.start, req.query.count, req.query.sort, function (err, abusesList, abusesTotal) { 50 db.VideoAbuse.listForApi(req.query.start, req.query.count, req.query.sort, function (err, abusesList, abusesTotal) {
46 if (err) return next(err) 51 if (err) return next(err)
47 52
48 res.json(utils.getFormatedObjects(abusesList, abusesTotal)) 53 res.json(getFormatedObjects(abusesList, abusesTotal))
49 }) 54 })
50} 55}
51 56
@@ -55,7 +60,7 @@ function reportVideoAbuseRetryWrapper (req, res, next) {
55 errorMessage: 'Cannot report abuse to the video with many retries.' 60 errorMessage: 'Cannot report abuse to the video with many retries.'
56 } 61 }
57 62
58 databaseUtils.retryTransactionWrapper(reportVideoAbuse, options, function (err) { 63 retryTransactionWrapper(reportVideoAbuse, options, function (err) {
59 if (err) return next(err) 64 if (err) return next(err)
60 65
61 return res.type('json').status(204).end() 66 return res.type('json').status(204).end()
@@ -75,7 +80,7 @@ function reportVideoAbuse (req, res, finalCallback) {
75 80
76 waterfall([ 81 waterfall([
77 82
78 databaseUtils.startSerializableTransaction, 83 startSerializableTransaction,
79 84
80 function createAbuse (t, callback) { 85 function createAbuse (t, callback) {
81 db.VideoAbuse.create(abuse).asCallback(function (err, abuse) { 86 db.VideoAbuse.create(abuse).asCallback(function (err, abuse) {
@@ -98,12 +103,12 @@ function reportVideoAbuse (req, res, finalCallback) {
98 return callback(null, t) 103 return callback(null, t)
99 }, 104 },
100 105
101 databaseUtils.commitTransaction 106 commitTransaction
102 107
103 ], function andFinally (err, t) { 108 ], function andFinally (err, t) {
104 if (err) { 109 if (err) {
105 logger.debug('Cannot update the video.', { error: err }) 110 logger.debug('Cannot update the video.', { error: err })
106 return databaseUtils.rollbackTransaction(err, t, finalCallback) 111 return rollbackTransaction(err, t, finalCallback)
107 } 112 }
108 113
109 logger.info('Abuse report for video %s created.', videoInstance.name) 114 logger.info('Abuse report for video %s created.', videoInstance.name)
diff --git a/server/controllers/api/videos/blacklist.js b/server/controllers/api/videos/blacklist.ts
index 8c3e2a69d..db6d95e73 100644
--- a/server/controllers/api/videos/blacklist.js
+++ b/server/controllers/api/videos/blacklist.ts
@@ -1,27 +1,27 @@
1'use strict' 1import express = require('express')
2
3const express = require('express')
4 2
5const db = require('../../../initializers/database') 3const db = require('../../../initializers/database')
6const logger = require('../../../helpers/logger') 4import { logger } from '../../../helpers'
7const middlewares = require('../../../middlewares') 5import {
8const admin = middlewares.admin 6 authenticate,
9const oAuth = middlewares.oauth 7 ensureIsAdmin,
10const validators = middlewares.validators 8 videosBlacklistValidator
11const validatorsVideos = validators.videos 9} from '../../../middlewares'
12 10
13const router = express.Router() 11const blacklistRouter = express.Router()
14 12
15router.post('/:id/blacklist', 13blacklistRouter.post('/:id/blacklist',
16 oAuth.authenticate, 14 authenticate,
17 admin.ensureIsAdmin, 15 ensureIsAdmin,
18 validatorsVideos.videosBlacklist, 16 videosBlacklistValidator,
19 addVideoToBlacklist 17 addVideoToBlacklist
20) 18)
21 19
22// --------------------------------------------------------------------------- 20// ---------------------------------------------------------------------------
23 21
24module.exports = router 22export {
23 blacklistRouter
24}
25 25
26// --------------------------------------------------------------------------- 26// ---------------------------------------------------------------------------
27 27
diff --git a/server/controllers/api/videos/index.js b/server/controllers/api/videos/index.ts
index 8de44d5ac..5fbf03676 100644
--- a/server/controllers/api/videos/index.js
+++ b/server/controllers/api/videos/index.ts
@@ -1,37 +1,57 @@
1'use strict' 1import express = require('express')
2import fs = require('fs')
3import multer = require('multer')
4import path = require('path')
5import { waterfall } from 'async'
2 6
3const express = require('express')
4const fs = require('fs')
5const multer = require('multer')
6const path = require('path')
7const waterfall = require('async/waterfall')
8
9const constants = require('../../../initializers/constants')
10const db = require('../../../initializers/database') 7const db = require('../../../initializers/database')
11const logger = require('../../../helpers/logger') 8import {
12const friends = require('../../../lib/friends') 9 CONFIG,
13const middlewares = require('../../../middlewares') 10 REQUEST_VIDEO_QADU_TYPES,
14const oAuth = middlewares.oauth 11 REQUEST_VIDEO_EVENT_TYPES,
15const pagination = middlewares.pagination 12 VIDEO_CATEGORIES,
16const validators = middlewares.validators 13 VIDEO_LICENCES,
17const validatorsPagination = validators.pagination 14 VIDEO_LANGUAGES
18const validatorsSort = validators.sort 15} from '../../../initializers'
19const validatorsVideos = validators.videos 16import {
20const search = middlewares.search 17 addEventToRemoteVideo,
21const sort = middlewares.sort 18 quickAndDirtyUpdateVideoToFriends,
22const databaseUtils = require('../../../helpers/database-utils') 19 addVideoToFriends,
23const utils = require('../../../helpers/utils') 20 updateVideoToFriends
24 21} from '../../../lib'
25const abuseController = require('./abuse') 22import {
26const blacklistController = require('./blacklist') 23 authenticate,
27const rateController = require('./rate') 24 paginationValidator,
28 25 videosSortValidator,
29const router = express.Router() 26 setVideosSort,
27 setPagination,
28 setVideosSearch,
29 videosUpdateValidator,
30 videosSearchValidator,
31 videosAddValidator,
32 videosGetValidator,
33 videosRemoveValidator
34} from '../../../middlewares'
35import {
36 logger,
37 commitTransaction,
38 retryTransactionWrapper,
39 rollbackTransaction,
40 startSerializableTransaction,
41 generateRandomString,
42 getFormatedObjects
43} from '../../../helpers'
44
45import { abuseVideoRouter } from './abuse'
46import { blacklistRouter } from './blacklist'
47import { rateVideoRouter } from './rate'
48
49const videosRouter = express.Router()
30 50
31// multer configuration 51// multer configuration
32const storage = multer.diskStorage({ 52const storage = multer.diskStorage({
33 destination: function (req, file, cb) { 53 destination: function (req, file, cb) {
34 cb(null, constants.CONFIG.STORAGE.VIDEOS_DIR) 54 cb(null, CONFIG.STORAGE.VIDEOS_DIR)
35 }, 55 },
36 56
37 filename: function (req, file, cb) { 57 filename: function (req, file, cb) {
@@ -39,7 +59,7 @@ const storage = multer.diskStorage({
39 if (file.mimetype === 'video/webm') extension = 'webm' 59 if (file.mimetype === 'video/webm') extension = 'webm'
40 else if (file.mimetype === 'video/mp4') extension = 'mp4' 60 else if (file.mimetype === 'video/mp4') extension = 'mp4'
41 else if (file.mimetype === 'video/ogg') extension = 'ogv' 61 else if (file.mimetype === 'video/ogg') extension = 'ogv'
42 utils.generateRandomString(16, function (err, randomString) { 62 generateRandomString(16, function (err, randomString) {
43 const fieldname = err ? undefined : randomString 63 const fieldname = err ? undefined : randomString
44 cb(null, fieldname + '.' + extension) 64 cb(null, fieldname + '.' + extension)
45 }) 65 })
@@ -48,70 +68,72 @@ const storage = multer.diskStorage({
48 68
49const reqFiles = multer({ storage: storage }).fields([{ name: 'videofile', maxCount: 1 }]) 69const reqFiles = multer({ storage: storage }).fields([{ name: 'videofile', maxCount: 1 }])
50 70
51router.use('/', abuseController) 71videosRouter.use('/', abuseVideoRouter)
52router.use('/', blacklistController) 72videosRouter.use('/', blacklistRouter)
53router.use('/', rateController) 73videosRouter.use('/', rateVideoRouter)
54 74
55router.get('/categories', listVideoCategories) 75videosRouter.get('/categories', listVideoCategories)
56router.get('/licences', listVideoLicences) 76videosRouter.get('/licences', listVideoLicences)
57router.get('/languages', listVideoLanguages) 77videosRouter.get('/languages', listVideoLanguages)
58 78
59router.get('/', 79videosRouter.get('/',
60 validatorsPagination.pagination, 80 paginationValidator,
61 validatorsSort.videosSort, 81 videosSortValidator,
62 sort.setVideosSort, 82 setVideosSort,
63 pagination.setPagination, 83 setPagination,
64 listVideos 84 listVideos
65) 85)
66router.put('/:id', 86videosRouter.put('/:id',
67 oAuth.authenticate, 87 authenticate,
68 reqFiles, 88 reqFiles,
69 validatorsVideos.videosUpdate, 89 videosUpdateValidator,
70 updateVideoRetryWrapper 90 updateVideoRetryWrapper
71) 91)
72router.post('/', 92videosRouter.post('/',
73 oAuth.authenticate, 93 authenticate,
74 reqFiles, 94 reqFiles,
75 validatorsVideos.videosAdd, 95 videosAddValidator,
76 addVideoRetryWrapper 96 addVideoRetryWrapper
77) 97)
78router.get('/:id', 98videosRouter.get('/:id',
79 validatorsVideos.videosGet, 99 videosGetValidator,
80 getVideo 100 getVideo
81) 101)
82 102
83router.delete('/:id', 103videosRouter.delete('/:id',
84 oAuth.authenticate, 104 authenticate,
85 validatorsVideos.videosRemove, 105 videosRemoveValidator,
86 removeVideo 106 removeVideo
87) 107)
88 108
89router.get('/search/:value', 109videosRouter.get('/search/:value',
90 validatorsVideos.videosSearch, 110 videosSearchValidator,
91 validatorsPagination.pagination, 111 paginationValidator,
92 validatorsSort.videosSort, 112 videosSortValidator,
93 sort.setVideosSort, 113 setVideosSort,
94 pagination.setPagination, 114 setPagination,
95 search.setVideosSearch, 115 setVideosSearch,
96 searchVideos 116 searchVideos
97) 117)
98 118
99// --------------------------------------------------------------------------- 119// ---------------------------------------------------------------------------
100 120
101module.exports = router 121export {
122 videosRouter
123}
102 124
103// --------------------------------------------------------------------------- 125// ---------------------------------------------------------------------------
104 126
105function listVideoCategories (req, res, next) { 127function listVideoCategories (req, res, next) {
106 res.json(constants.VIDEO_CATEGORIES) 128 res.json(VIDEO_CATEGORIES)
107} 129}
108 130
109function listVideoLicences (req, res, next) { 131function listVideoLicences (req, res, next) {
110 res.json(constants.VIDEO_LICENCES) 132 res.json(VIDEO_LICENCES)
111} 133}
112 134
113function listVideoLanguages (req, res, next) { 135function listVideoLanguages (req, res, next) {
114 res.json(constants.VIDEO_LANGUAGES) 136 res.json(VIDEO_LANGUAGES)
115} 137}
116 138
117// Wrapper to video add that retry the function if there is a database error 139// Wrapper to video add that retry the function if there is a database error
@@ -122,7 +144,7 @@ function addVideoRetryWrapper (req, res, next) {
122 errorMessage: 'Cannot insert the video with many retries.' 144 errorMessage: 'Cannot insert the video with many retries.'
123 } 145 }
124 146
125 databaseUtils.retryTransactionWrapper(addVideo, options, function (err) { 147 retryTransactionWrapper(addVideo, options, function (err) {
126 if (err) return next(err) 148 if (err) return next(err)
127 149
128 // TODO : include Location of the new video -> 201 150 // TODO : include Location of the new video -> 201
@@ -135,7 +157,7 @@ function addVideo (req, res, videoFile, finalCallback) {
135 157
136 waterfall([ 158 waterfall([
137 159
138 databaseUtils.startSerializableTransaction, 160 startSerializableTransaction,
139 161
140 function findOrCreateAuthor (t, callback) { 162 function findOrCreateAuthor (t, callback) {
141 const user = res.locals.oauth.token.User 163 const user = res.locals.oauth.token.User
@@ -179,7 +201,7 @@ function addVideo (req, res, videoFile, finalCallback) {
179 201
180 // Set the videoname the same as the id 202 // Set the videoname the same as the id
181 function renameVideoFile (t, author, tagInstances, video, callback) { 203 function renameVideoFile (t, author, tagInstances, video, callback) {
182 const videoDir = constants.CONFIG.STORAGE.VIDEOS_DIR 204 const videoDir = CONFIG.STORAGE.VIDEOS_DIR
183 const source = path.join(videoDir, videoFile.filename) 205 const source = path.join(videoDir, videoFile.filename)
184 const destination = path.join(videoDir, video.getVideoFilename()) 206 const destination = path.join(videoDir, video.getVideoFilename())
185 207
@@ -218,25 +240,25 @@ function addVideo (req, res, videoFile, finalCallback) {
218 240
219 function sendToFriends (t, video, callback) { 241 function sendToFriends (t, video, callback) {
220 // Let transcoding job send the video to friends because the videofile extension might change 242 // Let transcoding job send the video to friends because the videofile extension might change
221 if (constants.CONFIG.TRANSCODING.ENABLED === true) return callback(null, t) 243 if (CONFIG.TRANSCODING.ENABLED === true) return callback(null, t)
222 244
223 video.toAddRemoteJSON(function (err, remoteVideo) { 245 video.toAddRemoteJSON(function (err, remoteVideo) {
224 if (err) return callback(err) 246 if (err) return callback(err)
225 247
226 // Now we'll add the video's meta data to our friends 248 // Now we'll add the video's meta data to our friends
227 friends.addVideoToFriends(remoteVideo, t, function (err) { 249 addVideoToFriends(remoteVideo, t, function (err) {
228 return callback(err, t) 250 return callback(err, t)
229 }) 251 })
230 }) 252 })
231 }, 253 },
232 254
233 databaseUtils.commitTransaction 255 commitTransaction
234 256
235 ], function andFinally (err, t) { 257 ], function andFinally (err, t) {
236 if (err) { 258 if (err) {
237 // This is just a debug because we will retry the insert 259 // This is just a debug because we will retry the insert
238 logger.debug('Cannot insert the video.', { error: err }) 260 logger.debug('Cannot insert the video.', { error: err })
239 return databaseUtils.rollbackTransaction(err, t, finalCallback) 261 return rollbackTransaction(err, t, finalCallback)
240 } 262 }
241 263
242 logger.info('Video with name %s created.', videoInfos.name) 264 logger.info('Video with name %s created.', videoInfos.name)
@@ -250,7 +272,7 @@ function updateVideoRetryWrapper (req, res, next) {
250 errorMessage: 'Cannot update the video with many retries.' 272 errorMessage: 'Cannot update the video with many retries.'
251 } 273 }
252 274
253 databaseUtils.retryTransactionWrapper(updateVideo, options, function (err) { 275 retryTransactionWrapper(updateVideo, options, function (err) {
254 if (err) return next(err) 276 if (err) return next(err)
255 277
256 // TODO : include Location of the new video -> 201 278 // TODO : include Location of the new video -> 201
@@ -265,7 +287,7 @@ function updateVideo (req, res, finalCallback) {
265 287
266 waterfall([ 288 waterfall([
267 289
268 databaseUtils.startSerializableTransaction, 290 startSerializableTransaction,
269 291
270 function findOrCreateTags (t, callback) { 292 function findOrCreateTags (t, callback) {
271 if (videoInfosToUpdate.tags) { 293 if (videoInfosToUpdate.tags) {
@@ -312,12 +334,12 @@ function updateVideo (req, res, finalCallback) {
312 const json = videoInstance.toUpdateRemoteJSON() 334 const json = videoInstance.toUpdateRemoteJSON()
313 335
314 // Now we'll update the video's meta data to our friends 336 // Now we'll update the video's meta data to our friends
315 friends.updateVideoToFriends(json, t, function (err) { 337 updateVideoToFriends(json, t, function (err) {
316 return callback(err, t) 338 return callback(err, t)
317 }) 339 })
318 }, 340 },
319 341
320 databaseUtils.commitTransaction 342 commitTransaction
321 343
322 ], function andFinally (err, t) { 344 ], function andFinally (err, t) {
323 if (err) { 345 if (err) {
@@ -331,7 +353,7 @@ function updateVideo (req, res, finalCallback) {
331 videoInstance.set(key, value) 353 videoInstance.set(key, value)
332 }) 354 })
333 355
334 return databaseUtils.rollbackTransaction(err, t, finalCallback) 356 return rollbackTransaction(err, t, finalCallback)
335 } 357 }
336 358
337 logger.info('Video with name %s updated.', videoInfosToUpdate.name) 359 logger.info('Video with name %s updated.', videoInfosToUpdate.name)
@@ -354,17 +376,17 @@ function getVideo (req, res, next) {
354 // For example, only add a view when a user watch a video during 30s etc 376 // For example, only add a view when a user watch a video during 30s etc
355 const qaduParams = { 377 const qaduParams = {
356 videoId: videoInstance.id, 378 videoId: videoInstance.id,
357 type: constants.REQUEST_VIDEO_QADU_TYPES.VIEWS 379 type: REQUEST_VIDEO_QADU_TYPES.VIEWS
358 } 380 }
359 friends.quickAndDirtyUpdateVideoToFriends(qaduParams) 381 quickAndDirtyUpdateVideoToFriends(qaduParams)
360 }) 382 })
361 } else { 383 } else {
362 // Just send the event to our friends 384 // Just send the event to our friends
363 const eventParams = { 385 const eventParams = {
364 videoId: videoInstance.id, 386 videoId: videoInstance.id,
365 type: constants.REQUEST_VIDEO_EVENT_TYPES.VIEWS 387 type: REQUEST_VIDEO_EVENT_TYPES.VIEWS
366 } 388 }
367 friends.addEventToRemoteVideo(eventParams) 389 addEventToRemoteVideo(eventParams)
368 } 390 }
369 391
370 // Do not wait the view system 392 // Do not wait the view system
@@ -375,7 +397,7 @@ function listVideos (req, res, next) {
375 db.Video.listForApi(req.query.start, req.query.count, req.query.sort, function (err, videosList, videosTotal) { 397 db.Video.listForApi(req.query.start, req.query.count, req.query.sort, function (err, videosList, videosTotal) {
376 if (err) return next(err) 398 if (err) return next(err)
377 399
378 res.json(utils.getFormatedObjects(videosList, videosTotal)) 400 res.json(getFormatedObjects(videosList, videosTotal))
379 }) 401 })
380} 402}
381 403
@@ -398,7 +420,7 @@ function searchVideos (req, res, next) {
398 function (err, videosList, videosTotal) { 420 function (err, videosList, videosTotal) {
399 if (err) return next(err) 421 if (err) return next(err)
400 422
401 res.json(utils.getFormatedObjects(videosList, videosTotal)) 423 res.json(getFormatedObjects(videosList, videosTotal))
402 } 424 }
403 ) 425 )
404} 426}
diff --git a/server/controllers/api/videos/rate.js b/server/controllers/api/videos/rate.ts
index df8a69a1d..21053792a 100644
--- a/server/controllers/api/videos/rate.js
+++ b/server/controllers/api/videos/rate.ts
@@ -1,29 +1,41 @@
1'use strict' 1import express = require('express')
2import { waterfall } from 'async'
2 3
3const express = require('express')
4const waterfall = require('async/waterfall')
5
6const constants = require('../../../initializers/constants')
7const db = require('../../../initializers/database') 4const db = require('../../../initializers/database')
8const logger = require('../../../helpers/logger') 5import {
9const friends = require('../../../lib/friends') 6 logger,
10const middlewares = require('../../../middlewares') 7 retryTransactionWrapper,
11const oAuth = middlewares.oauth 8 startSerializableTransaction,
12const validators = middlewares.validators 9 commitTransaction,
13const validatorsVideos = validators.videos 10 rollbackTransaction
14const databaseUtils = require('../../../helpers/database-utils') 11} from '../../../helpers'
15 12import {
16const router = express.Router() 13 VIDEO_RATE_TYPES,
17 14 REQUEST_VIDEO_EVENT_TYPES,
18router.put('/:id/rate', 15 REQUEST_VIDEO_QADU_TYPES
19 oAuth.authenticate, 16} from '../../../initializers'
20 validatorsVideos.videoRate, 17import {
18 addEventsToRemoteVideo,
19 quickAndDirtyUpdatesVideoToFriends
20} from '../../../lib'
21import {
22 authenticate,
23 videoRateValidator
24} from '../../../middlewares'
25
26const rateVideoRouter = express.Router()
27
28rateVideoRouter.put('/:id/rate',
29 authenticate,
30 videoRateValidator,
21 rateVideoRetryWrapper 31 rateVideoRetryWrapper
22) 32)
23 33
24// --------------------------------------------------------------------------- 34// ---------------------------------------------------------------------------
25 35
26module.exports = router 36export {
37 rateVideoRouter
38}
27 39
28// --------------------------------------------------------------------------- 40// ---------------------------------------------------------------------------
29 41
@@ -33,7 +45,7 @@ function rateVideoRetryWrapper (req, res, next) {
33 errorMessage: 'Cannot update the user video rate.' 45 errorMessage: 'Cannot update the user video rate.'
34 } 46 }
35 47
36 databaseUtils.retryTransactionWrapper(rateVideo, options, function (err) { 48 retryTransactionWrapper(rateVideo, options, function (err) {
37 if (err) return next(err) 49 if (err) return next(err)
38 50
39 return res.type('json').status(204).end() 51 return res.type('json').status(204).end()
@@ -46,7 +58,7 @@ function rateVideo (req, res, finalCallback) {
46 const userInstance = res.locals.oauth.token.User 58 const userInstance = res.locals.oauth.token.User
47 59
48 waterfall([ 60 waterfall([
49 databaseUtils.startSerializableTransaction, 61 startSerializableTransaction,
50 62
51 function findPreviousRate (t, callback) { 63 function findPreviousRate (t, callback) {
52 db.UserVideoRate.load(userInstance.id, videoInstance.id, t, function (err, previousRate) { 64 db.UserVideoRate.load(userInstance.id, videoInstance.id, t, function (err, previousRate) {
@@ -60,14 +72,14 @@ function rateVideo (req, res, finalCallback) {
60 let likesToIncrement = 0 72 let likesToIncrement = 0
61 let dislikesToIncrement = 0 73 let dislikesToIncrement = 0
62 74
63 if (rateType === constants.VIDEO_RATE_TYPES.LIKE) likesToIncrement++ 75 if (rateType === VIDEO_RATE_TYPES.LIKE) likesToIncrement++
64 else if (rateType === constants.VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement++ 76 else if (rateType === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement++
65 77
66 // There was a previous rate, update it 78 // There was a previous rate, update it
67 if (previousRate) { 79 if (previousRate) {
68 // We will remove the previous rate, so we will need to remove it from the video attribute 80 // We will remove the previous rate, so we will need to remove it from the video attribute
69 if (previousRate.type === constants.VIDEO_RATE_TYPES.LIKE) likesToIncrement-- 81 if (previousRate.type === VIDEO_RATE_TYPES.LIKE) likesToIncrement--
70 else if (previousRate.type === constants.VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement-- 82 else if (previousRate.type === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement--
71 83
72 previousRate.type = rateType 84 previousRate.type = rateType
73 85
@@ -110,7 +122,7 @@ function rateVideo (req, res, finalCallback) {
110 if (likesToIncrement !== 0) { 122 if (likesToIncrement !== 0) {
111 eventsParams.push({ 123 eventsParams.push({
112 videoId: videoInstance.id, 124 videoId: videoInstance.id,
113 type: constants.REQUEST_VIDEO_EVENT_TYPES.LIKES, 125 type: REQUEST_VIDEO_EVENT_TYPES.LIKES,
114 count: likesToIncrement 126 count: likesToIncrement
115 }) 127 })
116 } 128 }
@@ -118,12 +130,12 @@ function rateVideo (req, res, finalCallback) {
118 if (dislikesToIncrement !== 0) { 130 if (dislikesToIncrement !== 0) {
119 eventsParams.push({ 131 eventsParams.push({
120 videoId: videoInstance.id, 132 videoId: videoInstance.id,
121 type: constants.REQUEST_VIDEO_EVENT_TYPES.DISLIKES, 133 type: REQUEST_VIDEO_EVENT_TYPES.DISLIKES,
122 count: dislikesToIncrement 134 count: dislikesToIncrement
123 }) 135 })
124 } 136 }
125 137
126 friends.addEventsToRemoteVideo(eventsParams, t, function (err) { 138 addEventsToRemoteVideo(eventsParams, t, function (err) {
127 return callback(err, t, likesToIncrement, dislikesToIncrement) 139 return callback(err, t, likesToIncrement, dislikesToIncrement)
128 }) 140 })
129 }, 141 },
@@ -138,29 +150,29 @@ function rateVideo (req, res, finalCallback) {
138 if (likesToIncrement !== 0) { 150 if (likesToIncrement !== 0) {
139 qadusParams.push({ 151 qadusParams.push({
140 videoId: videoInstance.id, 152 videoId: videoInstance.id,
141 type: constants.REQUEST_VIDEO_QADU_TYPES.LIKES 153 type: REQUEST_VIDEO_QADU_TYPES.LIKES
142 }) 154 })
143 } 155 }
144 156
145 if (dislikesToIncrement !== 0) { 157 if (dislikesToIncrement !== 0) {
146 qadusParams.push({ 158 qadusParams.push({
147 videoId: videoInstance.id, 159 videoId: videoInstance.id,
148 type: constants.REQUEST_VIDEO_QADU_TYPES.DISLIKES 160 type: REQUEST_VIDEO_QADU_TYPES.DISLIKES
149 }) 161 })
150 } 162 }
151 163
152 friends.quickAndDirtyUpdatesVideoToFriends(qadusParams, t, function (err) { 164 quickAndDirtyUpdatesVideoToFriends(qadusParams, t, function (err) {
153 return callback(err, t) 165 return callback(err, t)
154 }) 166 })
155 }, 167 },
156 168
157 databaseUtils.commitTransaction 169 commitTransaction
158 170
159 ], function (err, t) { 171 ], function (err, t) {
160 if (err) { 172 if (err) {
161 // This is just a debug because we will retry the insert 173 // This is just a debug because we will retry the insert
162 logger.debug('Cannot add the user video rate.', { error: err }) 174 logger.debug('Cannot add the user video rate.', { error: err })
163 return databaseUtils.rollbackTransaction(err, t, finalCallback) 175 return rollbackTransaction(err, t, finalCallback)
164 } 176 }
165 177
166 logger.info('User video rate for video %s of user %s updated.', videoInstance.name, userInstance.username) 178 logger.info('User video rate for video %s of user %s updated.', videoInstance.name, userInstance.username)
diff --git a/server/controllers/client.js b/server/controllers/client.ts
index 83243a4f7..aaa04889a 100644
--- a/server/controllers/client.js
+++ b/server/controllers/client.ts
@@ -1,40 +1,48 @@
1'use strict' 1import { parallel } from 'async'
2import express = require('express')
3import fs = require('fs')
4import { join } from 'path'
5import expressValidator = require('express-validator')
6// TODO: use .validator when express-validator typing will have validator field
7const validator = expressValidator['validator']
2 8
3const parallel = require('async/parallel')
4const express = require('express')
5const fs = require('fs')
6const path = require('path')
7const validator = require('express-validator').validator
8
9const constants = require('../initializers/constants')
10const db = require('../initializers/database') 9const db = require('../initializers/database')
10import {
11 CONFIG,
12 REMOTE_SCHEME,
13 STATIC_PATHS,
14 STATIC_MAX_AGE
15} from '../initializers'
11 16
12const router = express.Router() 17const clientsRouter = express.Router()
13 18
19// TODO: move to constants
14const opengraphComment = '<!-- opengraph tags -->' 20const opengraphComment = '<!-- opengraph tags -->'
15const distPath = path.join(__dirname, '..', '..', 'client/dist') 21const distPath = join(__dirname, '..', '..', 'client/dist')
16const embedPath = path.join(distPath, 'standalone/videos/embed.html') 22const embedPath = join(distPath, 'standalone/videos/embed.html')
17const indexPath = path.join(distPath, 'index.html') 23const indexPath = join(distPath, 'index.html')
18 24
19// Special route that add OpenGraph tags 25// Special route that add OpenGraph tags
20// Do not use a template engine for a so little thing 26// Do not use a template engine for a so little thing
21router.use('/videos/watch/:id', generateWatchHtmlPage) 27clientsRouter.use('/videos/watch/:id', generateWatchHtmlPage)
22 28
23router.use('/videos/embed', function (req, res, next) { 29clientsRouter.use('/videos/embed', function (req, res, next) {
24 res.sendFile(embedPath) 30 res.sendFile(embedPath)
25}) 31})
26 32
27// Static HTML/CSS/JS client files 33// Static HTML/CSS/JS client files
28router.use('/client', express.static(distPath, { maxAge: constants.STATIC_MAX_AGE })) 34clientsRouter.use('/client', express.static(distPath, { maxAge: STATIC_MAX_AGE }))
29 35
30// 404 for static files not found 36// 404 for static files not found
31router.use('/client/*', function (req, res, next) { 37clientsRouter.use('/client/*', function (req, res, next) {
32 res.sendStatus(404) 38 res.sendStatus(404)
33}) 39})
34 40
35// --------------------------------------------------------------------------- 41// ---------------------------------------------------------------------------
36 42
37module.exports = router 43export {
44 clientsRouter
45}
38 46
39// --------------------------------------------------------------------------- 47// ---------------------------------------------------------------------------
40 48
@@ -42,16 +50,16 @@ function addOpenGraphTags (htmlStringPage, video) {
42 let basePreviewUrlHttp 50 let basePreviewUrlHttp
43 51
44 if (video.isOwned()) { 52 if (video.isOwned()) {
45 basePreviewUrlHttp = constants.CONFIG.WEBSERVER.URL 53 basePreviewUrlHttp = CONFIG.WEBSERVER.URL
46 } else { 54 } else {
47 basePreviewUrlHttp = constants.REMOTE_SCHEME.HTTP + '://' + video.Author.Pod.host 55 basePreviewUrlHttp = REMOTE_SCHEME.HTTP + '://' + video.Author.Pod.host
48 } 56 }
49 57
50 // We fetch the remote preview (bigger than the thumbnail) 58 // We fetch the remote preview (bigger than the thumbnail)
51 // This should not overhead the remote server since social websites put in a cache the OpenGraph tags 59 // This should not overhead the remote server since social websites put in a cache the OpenGraph tags
52 // We can't use the thumbnail because these social websites want bigger images (> 200x200 for Facebook for example) 60 // We can't use the thumbnail because these social websites want bigger images (> 200x200 for Facebook for example)
53 const previewUrl = basePreviewUrlHttp + constants.STATIC_PATHS.PREVIEWS + video.getPreviewName() 61 const previewUrl = basePreviewUrlHttp + STATIC_PATHS.PREVIEWS + video.getPreviewName()
54 const videoUrl = constants.CONFIG.WEBSERVER.URL + '/videos/watch/' + video.id 62 const videoUrl = CONFIG.WEBSERVER.URL + '/videos/watch/' + video.id
55 63
56 const metaTags = { 64 const metaTags = {
57 'og:type': 'video', 65 'og:type': 'video',
@@ -95,11 +103,11 @@ function generateWatchHtmlPage (req, res, next) {
95 video: function (callback) { 103 video: function (callback) {
96 db.Video.loadAndPopulateAuthorAndPodAndTags(videoId, callback) 104 db.Video.loadAndPopulateAuthorAndPodAndTags(videoId, callback)
97 } 105 }
98 }, function (err, results) { 106 }, function (err, result: any) {
99 if (err) return next(err) 107 if (err) return next(err)
100 108
101 const html = results.file.toString() 109 const html = result.file.toString()
102 const video = results.video 110 const video = result.video
103 111
104 // Let Angular application handle errors 112 // Let Angular application handle errors
105 if (!video) return res.sendFile(indexPath) 113 if (!video) return res.sendFile(indexPath)
diff --git a/server/controllers/index.js b/server/controllers/index.js
deleted file mode 100644
index c9ca297ef..000000000
--- a/server/controllers/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
1'use strict'
2
3const apiController = require('./api/')
4const clientController = require('./client')
5const staticController = require('./static')
6
7module.exports = {
8 api: apiController,
9 client: clientController,
10 static: staticController
11}
diff --git a/server/controllers/index.ts b/server/controllers/index.ts
new file mode 100644
index 000000000..bb56fd7cf
--- /dev/null
+++ b/server/controllers/index.ts
@@ -0,0 +1,3 @@
1export * from './static';
2export * from './client';
3export * from './api';
diff --git a/server/controllers/static.js b/server/controllers/static.js
deleted file mode 100644
index 810b752af..000000000
--- a/server/controllers/static.js
+++ /dev/null
@@ -1,45 +0,0 @@
1'use strict'
2
3const express = require('express')
4const cors = require('cors')
5
6const constants = require('../initializers/constants')
7
8const router = express.Router()
9
10/*
11 Cors is very important to let other pods access torrent and video files
12*/
13
14const torrentsPhysicalPath = constants.CONFIG.STORAGE.TORRENTS_DIR
15router.use(
16 constants.STATIC_PATHS.TORRENTS,
17 cors(),
18 express.static(torrentsPhysicalPath, { maxAge: constants.STATIC_MAX_AGE })
19)
20
21// Videos path for webseeding
22const videosPhysicalPath = constants.CONFIG.STORAGE.VIDEOS_DIR
23router.use(
24 constants.STATIC_PATHS.WEBSEED,
25 cors(),
26 express.static(videosPhysicalPath, { maxAge: constants.STATIC_MAX_AGE })
27)
28
29// Thumbnails path for express
30const thumbnailsPhysicalPath = constants.CONFIG.STORAGE.THUMBNAILS_DIR
31router.use(
32 constants.STATIC_PATHS.THUMBNAILS,
33 express.static(thumbnailsPhysicalPath, { maxAge: constants.STATIC_MAX_AGE })
34)
35
36// Video previews path for express
37const previewsPhysicalPath = constants.CONFIG.STORAGE.PREVIEWS_DIR
38router.use(
39 constants.STATIC_PATHS.PREVIEWS,
40 express.static(previewsPhysicalPath, { maxAge: constants.STATIC_MAX_AGE })
41)
42
43// ---------------------------------------------------------------------------
44
45module.exports = router
diff --git a/server/controllers/static.ts b/server/controllers/static.ts
new file mode 100644
index 000000000..51f75c57e
--- /dev/null
+++ b/server/controllers/static.ts
@@ -0,0 +1,49 @@
1import express = require('express')
2import cors = require('cors')
3
4import {
5 CONFIG,
6 STATIC_MAX_AGE,
7 STATIC_PATHS
8} from '../initializers'
9
10const staticRouter = express.Router()
11
12/*
13 Cors is very important to let other pods access torrent and video files
14*/
15
16const torrentsPhysicalPath = CONFIG.STORAGE.TORRENTS_DIR
17staticRouter.use(
18 STATIC_PATHS.TORRENTS,
19 cors(),
20 express.static(torrentsPhysicalPath, { maxAge: STATIC_MAX_AGE })
21)
22
23// Videos path for webseeding
24const videosPhysicalPath = CONFIG.STORAGE.VIDEOS_DIR
25staticRouter.use(
26 STATIC_PATHS.WEBSEED,
27 cors(),
28 express.static(videosPhysicalPath, { maxAge: STATIC_MAX_AGE })
29)
30
31// Thumbnails path for express
32const thumbnailsPhysicalPath = CONFIG.STORAGE.THUMBNAILS_DIR
33staticRouter.use(
34 STATIC_PATHS.THUMBNAILS,
35 express.static(thumbnailsPhysicalPath, { maxAge: STATIC_MAX_AGE })
36)
37
38// Video previews path for express
39const previewsPhysicalPath = CONFIG.STORAGE.PREVIEWS_DIR
40staticRouter.use(
41 STATIC_PATHS.PREVIEWS,
42 express.static(previewsPhysicalPath, { maxAge: STATIC_MAX_AGE })
43)
44
45// ---------------------------------------------------------------------------
46
47export {
48 staticRouter
49}
diff --git a/server/helpers/custom-validators/index.js b/server/helpers/custom-validators/index.js
deleted file mode 100644
index 9383e0304..000000000
--- a/server/helpers/custom-validators/index.js
+++ /dev/null
@@ -1,19 +0,0 @@
1'use strict'
2
3const miscValidators = require('./misc')
4const podsValidators = require('./pods')
5const remoteValidators = require('./remote')
6const usersValidators = require('./users')
7const videosValidators = require('./videos')
8
9const validators = {
10 misc: miscValidators,
11 pods: podsValidators,
12 remote: remoteValidators,
13 users: usersValidators,
14 videos: videosValidators
15}
16
17// ---------------------------------------------------------------------------
18
19module.exports = validators
diff --git a/server/helpers/custom-validators/index.ts b/server/helpers/custom-validators/index.ts
new file mode 100644
index 000000000..1dcab624a
--- /dev/null
+++ b/server/helpers/custom-validators/index.ts
@@ -0,0 +1,6 @@
1export * from './remote'
2export * from './misc'
3export * from './pods'
4export * from './pods'
5export * from './users'
6export * from './videos'
diff --git a/server/helpers/custom-validators/misc.js b/server/helpers/custom-validators/misc.ts
index 052726241..83f50a7fe 100644
--- a/server/helpers/custom-validators/misc.js
+++ b/server/helpers/custom-validators/misc.ts
@@ -1,10 +1,3 @@
1'use strict'
2
3const miscValidators = {
4 exists,
5 isArray
6}
7
8function exists (value) { 1function exists (value) {
9 return value !== undefined && value !== null 2 return value !== undefined && value !== null
10} 3}
@@ -15,4 +8,7 @@ function isArray (value) {
15 8
16// --------------------------------------------------------------------------- 9// ---------------------------------------------------------------------------
17 10
18module.exports = miscValidators 11export {
12 exists,
13 isArray
14}
diff --git a/server/helpers/custom-validators/pods.js b/server/helpers/custom-validators/pods.ts
index 8bb3733ff..e4c827feb 100644
--- a/server/helpers/custom-validators/pods.js
+++ b/server/helpers/custom-validators/pods.ts
@@ -1,20 +1,15 @@
1'use strict' 1import expressValidator = require('express-validator')
2// TODO: use .validator when express-validator typing will have validator field
3const validator = expressValidator['validator']
2 4
3const validator = require('express-validator').validator 5import { isArray } from './misc'
4
5const miscValidators = require('./misc')
6
7const podsValidators = {
8 isEachUniqueHostValid,
9 isHostValid
10}
11 6
12function isHostValid (host) { 7function isHostValid (host) {
13 return validator.isURL(host) && host.split('://').length === 1 8 return validator.isURL(host) && host.split('://').length === 1
14} 9}
15 10
16function isEachUniqueHostValid (hosts) { 11function isEachUniqueHostValid (hosts) {
17 return miscValidators.isArray(hosts) && 12 return isArray(hosts) &&
18 hosts.length !== 0 && 13 hosts.length !== 0 &&
19 hosts.every(function (host) { 14 hosts.every(function (host) {
20 return isHostValid(host) && hosts.indexOf(host) === hosts.lastIndexOf(host) 15 return isHostValid(host) && hosts.indexOf(host) === hosts.lastIndexOf(host)
@@ -23,4 +18,7 @@ function isEachUniqueHostValid (hosts) {
23 18
24// --------------------------------------------------------------------------- 19// ---------------------------------------------------------------------------
25 20
26module.exports = podsValidators 21export {
22 isEachUniqueHostValid,
23 isHostValid
24}
diff --git a/server/helpers/custom-validators/remote/index.js b/server/helpers/custom-validators/remote/index.js
deleted file mode 100644
index 1939a95f4..000000000
--- a/server/helpers/custom-validators/remote/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
1'use strict'
2
3const remoteVideosValidators = require('./videos')
4
5const validators = {
6 videos: remoteVideosValidators
7}
8
9// ---------------------------------------------------------------------------
10
11module.exports = validators
diff --git a/server/helpers/custom-validators/remote/index.ts b/server/helpers/custom-validators/remote/index.ts
new file mode 100644
index 000000000..d6f9a7e77
--- /dev/null
+++ b/server/helpers/custom-validators/remote/index.ts
@@ -0,0 +1 @@
export * from './videos';
diff --git a/server/helpers/custom-validators/remote/videos.js b/server/helpers/custom-validators/remote/videos.js
deleted file mode 100644
index 24715b4b3..000000000
--- a/server/helpers/custom-validators/remote/videos.js
+++ /dev/null
@@ -1,118 +0,0 @@
1'use strict'
2
3const has = require('lodash/has')
4const values = require('lodash/values')
5
6const constants = require('../../../initializers/constants')
7const videosValidators = require('../videos')
8const miscValidators = require('../misc')
9
10const ENDPOINT_ACTIONS = constants.REQUEST_ENDPOINT_ACTIONS[constants.REQUEST_ENDPOINTS.VIDEOS]
11
12const remoteVideosValidators = {
13 isEachRemoteRequestVideosValid,
14 isEachRemoteRequestVideosQaduValid,
15 isEachRemoteRequestVideosEventsValid
16}
17
18function isEachRemoteRequestVideosValid (requests) {
19 return miscValidators.isArray(requests) &&
20 requests.every(function (request) {
21 const video = request.data
22
23 if (!video) return false
24
25 return (
26 isRequestTypeAddValid(request.type) &&
27 isCommonVideoAttributesValid(video) &&
28 videosValidators.isVideoAuthorValid(video.author) &&
29 videosValidators.isVideoThumbnailDataValid(video.thumbnailData)
30 ) ||
31 (
32 isRequestTypeUpdateValid(request.type) &&
33 isCommonVideoAttributesValid(video)
34 ) ||
35 (
36 isRequestTypeRemoveValid(request.type) &&
37 videosValidators.isVideoRemoteIdValid(video.remoteId)
38 ) ||
39 (
40 isRequestTypeReportAbuseValid(request.type) &&
41 videosValidators.isVideoRemoteIdValid(request.data.videoRemoteId) &&
42 videosValidators.isVideoAbuseReasonValid(request.data.reportReason) &&
43 videosValidators.isVideoAbuseReporterUsernameValid(request.data.reporterUsername)
44 )
45 })
46}
47
48function isEachRemoteRequestVideosQaduValid (requests) {
49 return miscValidators.isArray(requests) &&
50 requests.every(function (request) {
51 const video = request.data
52
53 if (!video) return false
54
55 return (
56 videosValidators.isVideoRemoteIdValid(video.remoteId) &&
57 (has(video, 'views') === false || videosValidators.isVideoViewsValid) &&
58 (has(video, 'likes') === false || videosValidators.isVideoLikesValid) &&
59 (has(video, 'dislikes') === false || videosValidators.isVideoDislikesValid)
60 )
61 })
62}
63
64function isEachRemoteRequestVideosEventsValid (requests) {
65 return miscValidators.isArray(requests) &&
66 requests.every(function (request) {
67 const eventData = request.data
68
69 if (!eventData) return false
70
71 return (
72 videosValidators.isVideoRemoteIdValid(eventData.remoteId) &&
73 values(constants.REQUEST_VIDEO_EVENT_TYPES).indexOf(eventData.eventType) !== -1 &&
74 videosValidators.isVideoEventCountValid(eventData.count)
75 )
76 })
77}
78
79// ---------------------------------------------------------------------------
80
81module.exports = remoteVideosValidators
82
83// ---------------------------------------------------------------------------
84
85function isCommonVideoAttributesValid (video) {
86 return videosValidators.isVideoDateValid(video.createdAt) &&
87 videosValidators.isVideoDateValid(video.updatedAt) &&
88 videosValidators.isVideoCategoryValid(video.category) &&
89 videosValidators.isVideoLicenceValid(video.licence) &&
90 videosValidators.isVideoLanguageValid(video.language) &&
91 videosValidators.isVideoNSFWValid(video.nsfw) &&
92 videosValidators.isVideoDescriptionValid(video.description) &&
93 videosValidators.isVideoDurationValid(video.duration) &&
94 videosValidators.isVideoInfoHashValid(video.infoHash) &&
95 videosValidators.isVideoNameValid(video.name) &&
96 videosValidators.isVideoTagsValid(video.tags) &&
97 videosValidators.isVideoRemoteIdValid(video.remoteId) &&
98 videosValidators.isVideoExtnameValid(video.extname) &&
99 videosValidators.isVideoViewsValid(video.views) &&
100 videosValidators.isVideoLikesValid(video.likes) &&
101 videosValidators.isVideoDislikesValid(video.dislikes)
102}
103
104function isRequestTypeAddValid (value) {
105 return value === ENDPOINT_ACTIONS.ADD
106}
107
108function isRequestTypeUpdateValid (value) {
109 return value === ENDPOINT_ACTIONS.UPDATE
110}
111
112function isRequestTypeRemoveValid (value) {
113 return value === ENDPOINT_ACTIONS.REMOVE
114}
115
116function isRequestTypeReportAbuseValid (value) {
117 return value === ENDPOINT_ACTIONS.REPORT_ABUSE
118}
diff --git a/server/helpers/custom-validators/remote/videos.ts b/server/helpers/custom-validators/remote/videos.ts
new file mode 100644
index 000000000..4b904d011
--- /dev/null
+++ b/server/helpers/custom-validators/remote/videos.ts
@@ -0,0 +1,138 @@
1import { has, values } from 'lodash'
2
3import {
4 REQUEST_ENDPOINTS,
5 REQUEST_ENDPOINT_ACTIONS,
6 REQUEST_VIDEO_EVENT_TYPES
7} from '../../../initializers'
8import { isArray } from '../misc'
9import {
10 isVideoAuthorValid,
11 isVideoThumbnailDataValid,
12 isVideoRemoteIdValid,
13 isVideoAbuseReasonValid,
14 isVideoAbuseReporterUsernameValid,
15 isVideoViewsValid,
16 isVideoLikesValid,
17 isVideoDislikesValid,
18 isVideoEventCountValid,
19 isVideoDateValid,
20 isVideoCategoryValid,
21 isVideoLicenceValid,
22 isVideoLanguageValid,
23 isVideoNSFWValid,
24 isVideoDescriptionValid,
25 isVideoDurationValid,
26 isVideoInfoHashValid,
27 isVideoNameValid,
28 isVideoTagsValid,
29 isVideoExtnameValid
30} from '../videos'
31
32const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS]
33
34function isEachRemoteRequestVideosValid (requests) {
35 return isArray(requests) &&
36 requests.every(function (request) {
37 const video = request.data
38
39 if (!video) return false
40
41 return (
42 isRequestTypeAddValid(request.type) &&
43 isCommonVideoAttributesValid(video) &&
44 isVideoAuthorValid(video.author) &&
45 isVideoThumbnailDataValid(video.thumbnailData)
46 ) ||
47 (
48 isRequestTypeUpdateValid(request.type) &&
49 isCommonVideoAttributesValid(video)
50 ) ||
51 (
52 isRequestTypeRemoveValid(request.type) &&
53 isVideoRemoteIdValid(video.remoteId)
54 ) ||
55 (
56 isRequestTypeReportAbuseValid(request.type) &&
57 isVideoRemoteIdValid(request.data.videoRemoteId) &&
58 isVideoAbuseReasonValid(request.data.reportReason) &&
59 isVideoAbuseReporterUsernameValid(request.data.reporterUsername)
60 )
61 })
62}
63
64function isEachRemoteRequestVideosQaduValid (requests) {
65 return isArray(requests) &&
66 requests.every(function (request) {
67 const video = request.data
68
69 if (!video) return false
70
71 return (
72 isVideoRemoteIdValid(video.remoteId) &&
73 (has(video, 'views') === false || isVideoViewsValid) &&
74 (has(video, 'likes') === false || isVideoLikesValid) &&
75 (has(video, 'dislikes') === false || isVideoDislikesValid)
76 )
77 })
78}
79
80function isEachRemoteRequestVideosEventsValid (requests) {
81 return isArray(requests) &&
82 requests.every(function (request) {
83 const eventData = request.data
84
85 if (!eventData) return false
86
87 return (
88 isVideoRemoteIdValid(eventData.remoteId) &&
89 values(REQUEST_VIDEO_EVENT_TYPES).indexOf(eventData.eventType) !== -1 &&
90 isVideoEventCountValid(eventData.count)
91 )
92 })
93}
94
95// ---------------------------------------------------------------------------
96
97export {
98 isEachRemoteRequestVideosValid,
99 isEachRemoteRequestVideosQaduValid,
100 isEachRemoteRequestVideosEventsValid
101}
102
103// ---------------------------------------------------------------------------
104
105function isCommonVideoAttributesValid (video) {
106 return isVideoDateValid(video.createdAt) &&
107 isVideoDateValid(video.updatedAt) &&
108 isVideoCategoryValid(video.category) &&
109 isVideoLicenceValid(video.licence) &&
110 isVideoLanguageValid(video.language) &&
111 isVideoNSFWValid(video.nsfw) &&
112 isVideoDescriptionValid(video.description) &&
113 isVideoDurationValid(video.duration) &&
114 isVideoInfoHashValid(video.infoHash) &&
115 isVideoNameValid(video.name) &&
116 isVideoTagsValid(video.tags) &&
117 isVideoRemoteIdValid(video.remoteId) &&
118 isVideoExtnameValid(video.extname) &&
119 isVideoViewsValid(video.views) &&
120 isVideoLikesValid(video.likes) &&
121 isVideoDislikesValid(video.dislikes)
122}
123
124function isRequestTypeAddValid (value) {
125 return value === ENDPOINT_ACTIONS.ADD
126}
127
128function isRequestTypeUpdateValid (value) {
129 return value === ENDPOINT_ACTIONS.UPDATE
130}
131
132function isRequestTypeRemoveValid (value) {
133 return value === ENDPOINT_ACTIONS.REMOVE
134}
135
136function isRequestTypeReportAbuseValid (value) {
137 return value === ENDPOINT_ACTIONS.REPORT_ABUSE
138}
diff --git a/server/helpers/custom-validators/users.js b/server/helpers/custom-validators/users.ts
index 2fc026e98..8fd2dac4f 100644
--- a/server/helpers/custom-validators/users.js
+++ b/server/helpers/custom-validators/users.ts
@@ -1,24 +1,17 @@
1'use strict' 1import { values } from 'lodash'
2import expressValidator = require('express-validator')
3// TODO: use .validator when express-validator typing will have validator field
4const validator = expressValidator['validator']
2 5
3const validator = require('express-validator').validator 6import { CONSTRAINTS_FIELDS, USER_ROLES } from '../../initializers'
4const values = require('lodash/values') 7const USERS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.USERS
5
6const constants = require('../../initializers/constants')
7const USERS_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.USERS
8
9const usersValidators = {
10 isUserPasswordValid,
11 isUserRoleValid,
12 isUserUsernameValid,
13 isUserDisplayNSFWValid
14}
15 8
16function isUserPasswordValid (value) { 9function isUserPasswordValid (value) {
17 return validator.isLength(value, USERS_CONSTRAINTS_FIELDS.PASSWORD) 10 return validator.isLength(value, USERS_CONSTRAINTS_FIELDS.PASSWORD)
18} 11}
19 12
20function isUserRoleValid (value) { 13function isUserRoleValid (value) {
21 return values(constants.USER_ROLES).indexOf(value) !== -1 14 return values(USER_ROLES).indexOf(value) !== -1
22} 15}
23 16
24function isUserUsernameValid (value) { 17function isUserUsernameValid (value) {
@@ -33,4 +26,9 @@ function isUserDisplayNSFWValid (value) {
33 26
34// --------------------------------------------------------------------------- 27// ---------------------------------------------------------------------------
35 28
36module.exports = usersValidators 29export {
30 isUserPasswordValid,
31 isUserRoleValid,
32 isUserUsernameValid,
33 isUserDisplayNSFWValid
34}
diff --git a/server/helpers/custom-validators/videos.js b/server/helpers/custom-validators/videos.ts
index 196731e04..2b2370be4 100644
--- a/server/helpers/custom-validators/videos.js
+++ b/server/helpers/custom-validators/videos.ts
@@ -1,43 +1,24 @@
1'use strict' 1import { values } from 'lodash'
2 2import expressValidator = require('express-validator')
3const validator = require('express-validator').validator 3// TODO: use .validator when express-validator typing will have validator field
4const values = require('lodash/values') 4const validator = expressValidator['validator']
5 5
6const constants = require('../../initializers/constants') 6import {
7const usersValidators = require('./users') 7 CONSTRAINTS_FIELDS,
8const miscValidators = require('./misc') 8 VIDEO_CATEGORIES,
9const VIDEOS_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.VIDEOS 9 VIDEO_LICENCES,
10const VIDEO_ABUSES_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.VIDEO_ABUSES 10 VIDEO_LANGUAGES,
11const VIDEO_EVENTS_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.VIDEO_EVENTS 11 VIDEO_RATE_TYPES
12 12} from '../../initializers'
13const videosValidators = { 13import { isUserUsernameValid } from './users'
14 isVideoAuthorValid, 14import { isArray } from './misc'
15 isVideoDateValid, 15
16 isVideoCategoryValid, 16const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
17 isVideoLicenceValid, 17const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
18 isVideoLanguageValid, 18const VIDEO_EVENTS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_EVENTS
19 isVideoNSFWValid,
20 isVideoDescriptionValid,
21 isVideoDurationValid,
22 isVideoInfoHashValid,
23 isVideoNameValid,
24 isVideoTagsValid,
25 isVideoThumbnailValid,
26 isVideoThumbnailDataValid,
27 isVideoExtnameValid,
28 isVideoRemoteIdValid,
29 isVideoAbuseReasonValid,
30 isVideoAbuseReporterUsernameValid,
31 isVideoFile,
32 isVideoViewsValid,
33 isVideoLikesValid,
34 isVideoRatingTypeValid,
35 isVideoDislikesValid,
36 isVideoEventCountValid
37}
38 19
39function isVideoAuthorValid (value) { 20function isVideoAuthorValid (value) {
40 return usersValidators.isUserUsernameValid(value) 21 return isUserUsernameValid(value)
41} 22}
42 23
43function isVideoDateValid (value) { 24function isVideoDateValid (value) {
@@ -45,15 +26,15 @@ function isVideoDateValid (value) {
45} 26}
46 27
47function isVideoCategoryValid (value) { 28function isVideoCategoryValid (value) {
48 return constants.VIDEO_CATEGORIES[value] !== undefined 29 return VIDEO_CATEGORIES[value] !== undefined
49} 30}
50 31
51function isVideoLicenceValid (value) { 32function isVideoLicenceValid (value) {
52 return constants.VIDEO_LICENCES[value] !== undefined 33 return VIDEO_LICENCES[value] !== undefined
53} 34}
54 35
55function isVideoLanguageValid (value) { 36function isVideoLanguageValid (value) {
56 return value === null || constants.VIDEO_LANGUAGES[value] !== undefined 37 return value === null || VIDEO_LANGUAGES[value] !== undefined
57} 38}
58 39
59function isVideoNSFWValid (value) { 40function isVideoNSFWValid (value) {
@@ -81,7 +62,7 @@ function isVideoNameValid (value) {
81} 62}
82 63
83function isVideoTagsValid (tags) { 64function isVideoTagsValid (tags) {
84 return miscValidators.isArray(tags) && 65 return isArray(tags) &&
85 validator.isInt(tags.length, VIDEOS_CONSTRAINTS_FIELDS.TAGS) && 66 validator.isInt(tags.length, VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
86 tags.every(function (tag) { 67 tags.every(function (tag) {
87 return validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG) 68 return validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
@@ -105,7 +86,7 @@ function isVideoAbuseReasonValid (value) {
105} 86}
106 87
107function isVideoAbuseReporterUsernameValid (value) { 88function isVideoAbuseReporterUsernameValid (value) {
108 return usersValidators.isUserUsernameValid(value) 89 return isUserUsernameValid(value)
109} 90}
110 91
111function isVideoViewsValid (value) { 92function isVideoViewsValid (value) {
@@ -125,7 +106,7 @@ function isVideoEventCountValid (value) {
125} 106}
126 107
127function isVideoRatingTypeValid (value) { 108function isVideoRatingTypeValid (value) {
128 return values(constants.VIDEO_RATE_TYPES).indexOf(value) !== -1 109 return values(VIDEO_RATE_TYPES).indexOf(value) !== -1
129} 110}
130 111
131function isVideoFile (value, files) { 112function isVideoFile (value, files) {
@@ -145,4 +126,28 @@ function isVideoFile (value, files) {
145 126
146// --------------------------------------------------------------------------- 127// ---------------------------------------------------------------------------
147 128
148module.exports = videosValidators 129export {
130 isVideoAuthorValid,
131 isVideoDateValid,
132 isVideoCategoryValid,
133 isVideoLicenceValid,
134 isVideoLanguageValid,
135 isVideoNSFWValid,
136 isVideoDescriptionValid,
137 isVideoDurationValid,
138 isVideoInfoHashValid,
139 isVideoNameValid,
140 isVideoTagsValid,
141 isVideoThumbnailValid,
142 isVideoThumbnailDataValid,
143 isVideoExtnameValid,
144 isVideoRemoteIdValid,
145 isVideoAbuseReasonValid,
146 isVideoAbuseReporterUsernameValid,
147 isVideoFile,
148 isVideoViewsValid,
149 isVideoLikesValid,
150 isVideoRatingTypeValid,
151 isVideoDislikesValid,
152 isVideoEventCountValid
153}
diff --git a/server/helpers/database-utils.js b/server/helpers/database-utils.ts
index c72d19429..b842ab9ec 100644
--- a/server/helpers/database-utils.js
+++ b/server/helpers/database-utils.ts
@@ -1,17 +1,8 @@
1'use strict' 1// TODO: import from ES6 when retry typing file will include errorFilter function
2 2import retry = require('async/retry')
3const retry = require('async/retry')
4 3
5const db = require('../initializers/database') 4const db = require('../initializers/database')
6const logger = require('./logger') 5import { logger } from './logger'
7
8const utils = {
9 commitTransaction,
10 retryTransactionWrapper,
11 rollbackTransaction,
12 startSerializableTransaction,
13 transactionRetryer
14}
15 6
16function commitTransaction (t, callback) { 7function commitTransaction (t, callback) {
17 return t.commit().asCallback(callback) 8 return t.commit().asCallback(callback)
@@ -33,7 +24,7 @@ function rollbackTransaction (err, t, callback) {
33function retryTransactionWrapper (functionToRetry, options, finalCallback) { 24function retryTransactionWrapper (functionToRetry, options, finalCallback) {
34 const args = options.arguments ? options.arguments : [] 25 const args = options.arguments ? options.arguments : []
35 26
36 utils.transactionRetryer( 27 transactionRetryer(
37 function (callback) { 28 function (callback) {
38 return functionToRetry.apply(this, args.concat([ callback ])) 29 return functionToRetry.apply(this, args.concat([ callback ]))
39 }, 30 },
@@ -69,4 +60,10 @@ function startSerializableTransaction (callback) {
69 60
70// --------------------------------------------------------------------------- 61// ---------------------------------------------------------------------------
71 62
72module.exports = utils 63export {
64 commitTransaction,
65 retryTransactionWrapper,
66 rollbackTransaction,
67 startSerializableTransaction,
68 transactionRetryer
69}
diff --git a/server/helpers/index.ts b/server/helpers/index.ts
new file mode 100644
index 000000000..e56bd21ad
--- /dev/null
+++ b/server/helpers/index.ts
@@ -0,0 +1,6 @@
1export * from './logger'
2export * from './custom-validators'
3export * from './database-utils'
4export * from './peertube-crypto'
5export * from './requests'
6export * from './utils'
diff --git a/server/helpers/logger.js b/server/helpers/logger.ts
index 281acedb8..3c35e41e0 100644
--- a/server/helpers/logger.js
+++ b/server/helpers/logger.ts
@@ -1,23 +1,21 @@
1// Thanks http://tostring.it/2014/06/23/advanced-logging-with-nodejs/ 1// Thanks http://tostring.it/2014/06/23/advanced-logging-with-nodejs/
2'use strict' 2import mkdirp = require('mkdirp')
3import path = require('path')
4import winston = require('winston')
3 5
4const mkdirp = require('mkdirp') 6// Do not use barrel (dependencies issues)
5const path = require('path') 7import { CONFIG } from '../initializers/constants'
6const winston = require('winston')
7winston.emitErrs = true
8 8
9const constants = require('../initializers/constants') 9const label = CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
10
11const label = constants.CONFIG.WEBSERVER.HOSTNAME + ':' + constants.CONFIG.WEBSERVER.PORT
12 10
13// Create the directory if it does not exist 11// Create the directory if it does not exist
14mkdirp.sync(constants.CONFIG.STORAGE.LOG_DIR) 12mkdirp.sync(CONFIG.STORAGE.LOG_DIR)
15 13
16const logger = new winston.Logger({ 14const logger = new winston.Logger({
17 transports: [ 15 transports: [
18 new winston.transports.File({ 16 new winston.transports.File({
19 level: 'debug', 17 level: 'debug',
20 filename: path.join(constants.CONFIG.STORAGE.LOG_DIR, 'all-logs.log'), 18 filename: path.join(CONFIG.STORAGE.LOG_DIR, 'all-logs.log'),
21 handleExceptions: true, 19 handleExceptions: true,
22 json: true, 20 json: true,
23 maxsize: 5242880, 21 maxsize: 5242880,
@@ -38,12 +36,13 @@ const logger = new winston.Logger({
38 exitOnError: true 36 exitOnError: true
39}) 37})
40 38
41logger.stream = { 39// TODO: useful?
42 write: function (message, encoding) { 40// logger.stream = {
43 logger.info(message) 41// write: function (message) {
44 } 42// logger.info(message)
45} 43// }
44// }
46 45
47// --------------------------------------------------------------------------- 46// ---------------------------------------------------------------------------
48 47
49module.exports = logger 48export { logger }
diff --git a/server/helpers/peertube-crypto.js b/server/helpers/peertube-crypto.ts
index 55ae6fab3..a4e9672e6 100644
--- a/server/helpers/peertube-crypto.js
+++ b/server/helpers/peertube-crypto.ts
@@ -1,26 +1,21 @@
1'use strict' 1import crypto = require('crypto')
2 2import bcrypt = require('bcrypt')
3const crypto = require('crypto') 3import fs = require('fs')
4const bcrypt = require('bcrypt') 4import openssl = require('openssl-wrapper')
5const fs = require('fs') 5import { join } from 'path'
6const openssl = require('openssl-wrapper') 6
7const pathUtils = require('path') 7import {
8 8 SIGNATURE_ALGORITHM,
9const constants = require('../initializers/constants') 9 SIGNATURE_ENCODING,
10const logger = require('./logger') 10 PRIVATE_CERT_NAME,
11 11 CONFIG,
12const peertubeCrypto = { 12 BCRYPT_SALT_SIZE,
13 checkSignature, 13 PUBLIC_CERT_NAME
14 comparePassword, 14} from '../initializers'
15 createCertsIfNotExist, 15import { logger } from './logger'
16 cryptPassword,
17 getMyPrivateCert,
18 getMyPublicCert,
19 sign
20}
21 16
22function checkSignature (publicKey, data, hexSignature) { 17function checkSignature (publicKey, data, hexSignature) {
23 const verify = crypto.createVerify(constants.SIGNATURE_ALGORITHM) 18 const verify = crypto.createVerify(SIGNATURE_ALGORITHM)
24 19
25 let dataString 20 let dataString
26 if (typeof data === 'string') { 21 if (typeof data === 'string') {
@@ -36,12 +31,12 @@ function checkSignature (publicKey, data, hexSignature) {
36 31
37 verify.update(dataString, 'utf8') 32 verify.update(dataString, 'utf8')
38 33
39 const isValid = verify.verify(publicKey, hexSignature, constants.SIGNATURE_ENCODING) 34 const isValid = verify.verify(publicKey, hexSignature, SIGNATURE_ENCODING)
40 return isValid 35 return isValid
41} 36}
42 37
43function sign (data) { 38function sign (data) {
44 const sign = crypto.createSign(constants.SIGNATURE_ALGORITHM) 39 const sign = crypto.createSign(SIGNATURE_ALGORITHM)
45 40
46 let dataString 41 let dataString
47 if (typeof data === 'string') { 42 if (typeof data === 'string') {
@@ -58,9 +53,9 @@ function sign (data) {
58 sign.update(dataString, 'utf8') 53 sign.update(dataString, 'utf8')
59 54
60 // TODO: make async 55 // TODO: make async
61 const certPath = pathUtils.join(constants.CONFIG.STORAGE.CERT_DIR, constants.PRIVATE_CERT_NAME) 56 const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME)
62 const myKey = fs.readFileSync(certPath) 57 const myKey = fs.readFileSync(certPath)
63 const signature = sign.sign(myKey, constants.SIGNATURE_ENCODING) 58 const signature = sign.sign(myKey.toString(), SIGNATURE_ENCODING)
64 59
65 return signature 60 return signature
66} 61}
@@ -88,7 +83,7 @@ function createCertsIfNotExist (callback) {
88} 83}
89 84
90function cryptPassword (password, callback) { 85function cryptPassword (password, callback) {
91 bcrypt.genSalt(constants.BCRYPT_SALT_SIZE, function (err, salt) { 86 bcrypt.genSalt(BCRYPT_SALT_SIZE, function (err, salt) {
92 if (err) return callback(err) 87 if (err) return callback(err)
93 88
94 bcrypt.hash(password, salt, function (err, hash) { 89 bcrypt.hash(password, salt, function (err, hash) {
@@ -98,23 +93,31 @@ function cryptPassword (password, callback) {
98} 93}
99 94
100function getMyPrivateCert (callback) { 95function getMyPrivateCert (callback) {
101 const certPath = pathUtils.join(constants.CONFIG.STORAGE.CERT_DIR, constants.PRIVATE_CERT_NAME) 96 const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME)
102 fs.readFile(certPath, 'utf8', callback) 97 fs.readFile(certPath, 'utf8', callback)
103} 98}
104 99
105function getMyPublicCert (callback) { 100function getMyPublicCert (callback) {
106 const certPath = pathUtils.join(constants.CONFIG.STORAGE.CERT_DIR, constants.PUBLIC_CERT_NAME) 101 const certPath = join(CONFIG.STORAGE.CERT_DIR, PUBLIC_CERT_NAME)
107 fs.readFile(certPath, 'utf8', callback) 102 fs.readFile(certPath, 'utf8', callback)
108} 103}
109 104
110// --------------------------------------------------------------------------- 105// ---------------------------------------------------------------------------
111 106
112module.exports = peertubeCrypto 107export {
108 checkSignature,
109 comparePassword,
110 createCertsIfNotExist,
111 cryptPassword,
112 getMyPrivateCert,
113 getMyPublicCert,
114 sign
115}
113 116
114// --------------------------------------------------------------------------- 117// ---------------------------------------------------------------------------
115 118
116function certsExist (callback) { 119function certsExist (callback) {
117 const certPath = pathUtils.join(constants.CONFIG.STORAGE.CERT_DIR, constants.PRIVATE_CERT_NAME) 120 const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME)
118 fs.access(certPath, function (err) { 121 fs.access(certPath, function (err) {
119 // If there is an error the certificates do not exist 122 // If there is an error the certificates do not exist
120 const exists = !err 123 const exists = !err
@@ -134,7 +137,7 @@ function createCerts (callback) {
134 137
135 logger.info('Generating a RSA key...') 138 logger.info('Generating a RSA key...')
136 139
137 const privateCertPath = pathUtils.join(constants.CONFIG.STORAGE.CERT_DIR, constants.PRIVATE_CERT_NAME) 140 const privateCertPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME)
138 const genRsaOptions = { 141 const genRsaOptions = {
139 'out': privateCertPath, 142 'out': privateCertPath,
140 '2048': false 143 '2048': false
@@ -148,7 +151,7 @@ function createCerts (callback) {
148 logger.info('RSA key generated.') 151 logger.info('RSA key generated.')
149 logger.info('Managing public key...') 152 logger.info('Managing public key...')
150 153
151 const publicCertPath = pathUtils.join(constants.CONFIG.STORAGE.CERT_DIR, 'peertube.pub') 154 const publicCertPath = join(CONFIG.STORAGE.CERT_DIR, 'peertube.pub')
152 const rsaOptions = { 155 const rsaOptions = {
153 'in': privateCertPath, 156 'in': privateCertPath,
154 'pubout': true, 157 'pubout': true,
diff --git a/server/helpers/requests.js b/server/helpers/requests.ts
index efe056937..8ded52972 100644
--- a/server/helpers/requests.js
+++ b/server/helpers/requests.ts
@@ -1,21 +1,18 @@
1'use strict' 1import replay = require('request-replay')
2import request = require('request')
2 3
3const replay = require('request-replay') 4import {
4const request = require('request') 5 RETRY_REQUESTS,
5 6 REMOTE_SCHEME,
6const constants = require('../initializers/constants') 7 CONFIG
7const peertubeCrypto = require('./peertube-crypto') 8} from '../initializers'
8 9import { sign } from './peertube-crypto'
9const requests = {
10 makeRetryRequest,
11 makeSecureRequest
12}
13 10
14function makeRetryRequest (params, callback) { 11function makeRetryRequest (params, callback) {
15 replay( 12 replay(
16 request(params, callback), 13 request(params, callback),
17 { 14 {
18 retries: constants.RETRY_REQUESTS, 15 retries: RETRY_REQUESTS,
19 factor: 3, 16 factor: 3,
20 maxTimeout: Infinity, 17 maxTimeout: Infinity,
21 errorCodes: [ 'EADDRINFO', 'ETIMEDOUT', 'ECONNRESET', 'ESOCKETTIMEDOUT', 'ENOTFOUND', 'ECONNREFUSED' ] 18 errorCodes: [ 'EADDRINFO', 'ETIMEDOUT', 'ECONNRESET', 'ESOCKETTIMEDOUT', 'ENOTFOUND', 'ECONNREFUSED' ]
@@ -25,18 +22,17 @@ function makeRetryRequest (params, callback) {
25 22
26function makeSecureRequest (params, callback) { 23function makeSecureRequest (params, callback) {
27 const requestParams = { 24 const requestParams = {
28 url: constants.REMOTE_SCHEME.HTTP + '://' + params.toPod.host + params.path 25 url: REMOTE_SCHEME.HTTP + '://' + params.toPod.host + params.path,
26 json: {}
29 } 27 }
30 28
31 if (params.method !== 'POST') { 29 if (params.method !== 'POST') {
32 return callback(new Error('Cannot make a secure request with a non POST method.')) 30 return callback(new Error('Cannot make a secure request with a non POST method.'))
33 } 31 }
34 32
35 requestParams.json = {}
36
37 // Add signature if it is specified in the params 33 // Add signature if it is specified in the params
38 if (params.sign === true) { 34 if (params.sign === true) {
39 const host = constants.CONFIG.WEBSERVER.HOST 35 const host = CONFIG.WEBSERVER.HOST
40 36
41 let dataToSign 37 let dataToSign
42 if (params.data) { 38 if (params.data) {
@@ -47,22 +43,23 @@ function makeSecureRequest (params, callback) {
47 dataToSign = host 43 dataToSign = host
48 } 44 }
49 45
50 requestParams.json.signature = { 46 requestParams.json['signature'] = {
51 host, // Which host we pretend to be 47 host, // Which host we pretend to be
52 signature: peertubeCrypto.sign(dataToSign) 48 signature: sign(dataToSign)
53 } 49 }
54 } 50 }
55 51
56 // If there are data informations 52 // If there are data informations
57 if (params.data) { 53 if (params.data) {
58 requestParams.json.data = params.data 54 requestParams.json['data'] = params.data
59 } 55 }
60 56
61 console.log(requestParams.json.data)
62
63 request.post(requestParams, callback) 57 request.post(requestParams, callback)
64} 58}
65 59
66// --------------------------------------------------------------------------- 60// ---------------------------------------------------------------------------
67 61
68module.exports = requests 62export {
63 makeRetryRequest,
64 makeSecureRequest
65}
diff --git a/server/helpers/utils.js b/server/helpers/utils.ts
index 6d40e8f3f..09c35a533 100644
--- a/server/helpers/utils.js
+++ b/server/helpers/utils.ts
@@ -1,24 +1,13 @@
1'use strict' 1import { pseudoRandomBytes } from 'crypto'
2 2
3const crypto = require('crypto') 3import { logger } from './logger'
4
5const logger = require('./logger')
6
7const utils = {
8 badRequest,
9 createEmptyCallback,
10 cleanForExit,
11 generateRandomString,
12 isTestInstance,
13 getFormatedObjects
14}
15 4
16function badRequest (req, res, next) { 5function badRequest (req, res, next) {
17 res.type('json').status(400).end() 6 res.type('json').status(400).end()
18} 7}
19 8
20function generateRandomString (size, callback) { 9function generateRandomString (size, callback) {
21 crypto.pseudoRandomBytes(size, function (err, raw) { 10 pseudoRandomBytes(size, function (err, raw) {
22 if (err) return callback(err) 11 if (err) return callback(err)
23 12
24 callback(null, raw.toString('hex')) 13 callback(null, raw.toString('hex'))
@@ -55,4 +44,11 @@ function getFormatedObjects (objects, objectsTotal) {
55 44
56// --------------------------------------------------------------------------- 45// ---------------------------------------------------------------------------
57 46
58module.exports = utils 47export {
48 badRequest,
49 createEmptyCallback,
50 cleanForExit,
51 generateRandomString,
52 isTestInstance,
53 getFormatedObjects
54}
diff --git a/server/initializers/checker.js b/server/initializers/checker.ts
index aa8dea4bf..370dff2d4 100644
--- a/server/initializers/checker.js
+++ b/server/initializers/checker.ts
@@ -1,17 +1,7 @@
1'use strict' 1import config = require('config')
2 2
3const config = require('config')
4
5const constants = require('./constants')
6const db = require('./database') 3const db = require('./database')
7 4import { CONFIG } from './constants'
8const checker = {
9 checkConfig,
10 checkFFmpeg,
11 checkMissedConfig,
12 clientsExist,
13 usersExist
14}
15 5
16// Some checks on configuration files 6// Some checks on configuration files
17function checkConfig () { 7function checkConfig () {
@@ -50,7 +40,7 @@ function checkFFmpeg (callback) {
50 40
51 Ffmpeg.getAvailableCodecs(function (err, codecs) { 41 Ffmpeg.getAvailableCodecs(function (err, codecs) {
52 if (err) return callback(err) 42 if (err) return callback(err)
53 if (constants.CONFIG.TRANSCODING.ENABLED === false) return callback(null) 43 if (CONFIG.TRANSCODING.ENABLED === false) return callback(null)
54 44
55 const canEncode = [ 'libx264' ] 45 const canEncode = [ 'libx264' ]
56 canEncode.forEach(function (codec) { 46 canEncode.forEach(function (codec) {
@@ -85,4 +75,10 @@ function usersExist (callback) {
85 75
86// --------------------------------------------------------------------------- 76// ---------------------------------------------------------------------------
87 77
88module.exports = checker 78export {
79 checkConfig,
80 checkFFmpeg,
81 checkMissedConfig,
82 clientsExist,
83 usersExist
84}
diff --git a/server/initializers/constants.js b/server/initializers/constants.ts
index 87e9c8002..6bdc261ad 100644
--- a/server/initializers/constants.js
+++ b/server/initializers/constants.ts
@@ -1,7 +1,5 @@
1'use strict' 1import config = require('config')
2 2import { join } from 'path'
3const config = require('config')
4const path = require('path')
5 3
6// --------------------------------------------------------------------------- 4// ---------------------------------------------------------------------------
7 5
@@ -36,38 +34,40 @@ const OAUTH_LIFETIME = {
36 34
37const CONFIG = { 35const CONFIG = {
38 LISTEN: { 36 LISTEN: {
39 PORT: config.get('listen.port') 37 PORT: config.get<number>('listen.port')
40 }, 38 },
41 DATABASE: { 39 DATABASE: {
42 DBNAME: 'peertube' + config.get('database.suffix'), 40 DBNAME: 'peertube' + config.get<string>('database.suffix'),
43 HOSTNAME: config.get('database.hostname'), 41 HOSTNAME: config.get<string>('database.hostname'),
44 PORT: config.get('database.port'), 42 PORT: config.get<number>('database.port'),
45 USERNAME: config.get('database.username'), 43 USERNAME: config.get<string>('database.username'),
46 PASSWORD: config.get('database.password') 44 PASSWORD: config.get<string>('database.password')
47 }, 45 },
48 STORAGE: { 46 STORAGE: {
49 CERT_DIR: path.join(__dirname, '..', '..', config.get('storage.certs')), 47 CERT_DIR: join(__dirname, '..', '..', config.get<string>('storage.certs')),
50 LOG_DIR: path.join(__dirname, '..', '..', config.get('storage.logs')), 48 LOG_DIR: join(__dirname, '..', '..', config.get<string>('storage.logs')),
51 VIDEOS_DIR: path.join(__dirname, '..', '..', config.get('storage.videos')), 49 VIDEOS_DIR: join(__dirname, '..', '..', config.get<string>('storage.videos')),
52 THUMBNAILS_DIR: path.join(__dirname, '..', '..', config.get('storage.thumbnails')), 50 THUMBNAILS_DIR: join(__dirname, '..', '..', config.get<string>('storage.thumbnails')),
53 PREVIEWS_DIR: path.join(__dirname, '..', '..', config.get('storage.previews')), 51 PREVIEWS_DIR: join(__dirname, '..', '..', config.get<string>('storage.previews')),
54 TORRENTS_DIR: path.join(__dirname, '..', '..', config.get('storage.torrents')) 52 TORRENTS_DIR: join(__dirname, '..', '..', config.get<string>('storage.torrents'))
55 }, 53 },
56 WEBSERVER: { 54 WEBSERVER: {
57 SCHEME: config.get('webserver.https') === true ? 'https' : 'http', 55 SCHEME: config.get<boolean>('webserver.https') === true ? 'https' : 'http',
58 WS: config.get('webserver.https') === true ? 'wss' : 'ws', 56 WS: config.get<boolean>('webserver.https') === true ? 'wss' : 'ws',
59 HOSTNAME: config.get('webserver.hostname'), 57 HOSTNAME: config.get<string>('webserver.hostname'),
60 PORT: config.get('webserver.port') 58 PORT: config.get<number>('webserver.port'),
59 URL: '',
60 HOST: ''
61 }, 61 },
62 ADMIN: { 62 ADMIN: {
63 EMAIL: config.get('admin.email') 63 EMAIL: config.get<string>('admin.email')
64 }, 64 },
65 SIGNUP: { 65 SIGNUP: {
66 ENABLED: config.get('signup.enabled') 66 ENABLED: config.get<boolean>('signup.enabled')
67 }, 67 },
68 TRANSCODING: { 68 TRANSCODING: {
69 ENABLED: config.get('transcoding.enabled'), 69 ENABLED: config.get<boolean>('transcoding.enabled'),
70 THREADS: config.get('transcoding.threads') 70 THREADS: config.get<number>('transcoding.threads')
71 } 71 }
72} 72}
73CONFIG.WEBSERVER.URL = CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT 73CONFIG.WEBSERVER.URL = CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
@@ -283,12 +283,12 @@ if (isTestInstance() === true) {
283 JOBS_FETCHING_INTERVAL = 10000 283 JOBS_FETCHING_INTERVAL = 10000
284 REMOTE_SCHEME.HTTP = 'http' 284 REMOTE_SCHEME.HTTP = 'http'
285 REMOTE_SCHEME.WS = 'ws' 285 REMOTE_SCHEME.WS = 'ws'
286 STATIC_MAX_AGE = 0 286 STATIC_MAX_AGE = '0'
287} 287}
288 288
289// --------------------------------------------------------------------------- 289// ---------------------------------------------------------------------------
290 290
291module.exports = { 291export {
292 API_VERSION, 292 API_VERSION,
293 BCRYPT_SALT_SIZE, 293 BCRYPT_SALT_SIZE,
294 CONFIG, 294 CONFIG,
diff --git a/server/initializers/database.js b/server/initializers/database.ts
index 043152a0e..753a06669 100644
--- a/server/initializers/database.js
+++ b/server/initializers/database.ts
@@ -1,24 +1,23 @@
1'use strict' 1import fs = require('fs')
2import { join } from 'path'
3import Sequelize = require('sequelize')
2 4
3const fs = require('fs') 5import { CONFIG } from './constants'
4const path = require('path') 6// Do not use barrel, we need to load database first
5const Sequelize = require('sequelize') 7import { logger } from '../helpers/logger'
8import { isTestInstance } from '../helpers/utils'
6 9
7const constants = require('../initializers/constants') 10const dbname = CONFIG.DATABASE.DBNAME
8const logger = require('../helpers/logger') 11const username = CONFIG.DATABASE.USERNAME
9const utils = require('../helpers/utils') 12const password = CONFIG.DATABASE.PASSWORD
10 13
11const database = {} 14const database: any = {}
12
13const dbname = constants.CONFIG.DATABASE.DBNAME
14const username = constants.CONFIG.DATABASE.USERNAME
15const password = constants.CONFIG.DATABASE.PASSWORD
16 15
17const sequelize = new Sequelize(dbname, username, password, { 16const sequelize = new Sequelize(dbname, username, password, {
18 dialect: 'postgres', 17 dialect: 'postgres',
19 host: constants.CONFIG.DATABASE.HOSTNAME, 18 host: CONFIG.DATABASE.HOSTNAME,
20 port: constants.CONFIG.DATABASE.PORT, 19 port: CONFIG.DATABASE.PORT,
21 benchmark: utils.isTestInstance(), 20 benchmark: isTestInstance(),
22 21
23 logging: function (message, benchmark) { 22 logging: function (message, benchmark) {
24 let newMessage = message 23 let newMessage = message
@@ -31,24 +30,16 @@ const sequelize = new Sequelize(dbname, username, password, {
31}) 30})
32 31
33database.sequelize = sequelize 32database.sequelize = sequelize
34database.Sequelize = Sequelize
35database.init = init
36
37// ---------------------------------------------------------------------------
38 33
39module.exports = database 34database.init = function (silent, callback) {
40
41// ---------------------------------------------------------------------------
42
43function init (silent, callback) {
44 if (!callback) { 35 if (!callback) {
45 callback = silent 36 callback = silent
46 silent = false 37 silent = false
47 } 38 }
48 39
49 if (!callback) callback = function () {} 40 if (!callback) callback = function () { /* empty */ }
50 41
51 const modelDirectory = path.join(__dirname, '..', 'models') 42 const modelDirectory = join(__dirname, '..', 'models')
52 fs.readdir(modelDirectory, function (err, files) { 43 fs.readdir(modelDirectory, function (err, files) {
53 if (err) throw err 44 if (err) throw err
54 45
@@ -59,9 +50,9 @@ function init (silent, callback) {
59 return true 50 return true
60 }) 51 })
61 .forEach(function (file) { 52 .forEach(function (file) {
62 const model = sequelize.import(path.join(modelDirectory, file)) 53 const model = sequelize.import(join(modelDirectory, file))
63 54
64 database[model.name] = model 55 database[model['name']] = model
65 }) 56 })
66 57
67 Object.keys(database).forEach(function (modelName) { 58 Object.keys(database).forEach(function (modelName) {
@@ -75,3 +66,7 @@ function init (silent, callback) {
75 return callback(null) 66 return callback(null)
76 }) 67 })
77} 68}
69
70// ---------------------------------------------------------------------------
71
72module.exports = database
diff --git a/server/initializers/index.ts b/server/initializers/index.ts
new file mode 100644
index 000000000..b8400ff84
--- /dev/null
+++ b/server/initializers/index.ts
@@ -0,0 +1,6 @@
1// Constants first, databse in second!
2export * from './constants'
3export * from './database'
4export * from './checker'
5export * from './installer'
6export * from './migrator'
diff --git a/server/initializers/installer.js b/server/initializers/installer.ts
index 837a987dd..cd1404d48 100644
--- a/server/initializers/installer.js
+++ b/server/initializers/installer.ts
@@ -1,21 +1,13 @@
1'use strict' 1import { join } from 'path'
2import config = require('config')
3import { each, series } from 'async'
4import mkdirp = require('mkdirp')
5import passwordGenerator = require('password-generator')
2 6
3const config = require('config')
4const each = require('async/each')
5const mkdirp = require('mkdirp')
6const passwordGenerator = require('password-generator')
7const path = require('path')
8const series = require('async/series')
9
10const checker = require('./checker')
11const constants = require('./constants')
12const db = require('./database') 7const db = require('./database')
13const logger = require('../helpers/logger') 8import { USER_ROLES, CONFIG, LAST_MIGRATION_VERSION } from './constants'
14const peertubeCrypto = require('../helpers/peertube-crypto') 9import { clientsExist, usersExist } from './checker'
15 10import { logger, createCertsIfNotExist } from '../helpers'
16const installer = {
17 installApplication
18}
19 11
20function installApplication (callback) { 12function installApplication (callback) {
21 series([ 13 series([
@@ -29,7 +21,7 @@ function installApplication (callback) {
29 }, 21 },
30 22
31 function createCertificates (callbackAsync) { 23 function createCertificates (callbackAsync) {
32 peertubeCrypto.createCertsIfNotExist(callbackAsync) 24 createCertsIfNotExist(callbackAsync)
33 }, 25 },
34 26
35 function createOAuthClient (callbackAsync) { 27 function createOAuthClient (callbackAsync) {
@@ -44,7 +36,9 @@ function installApplication (callback) {
44 36
45// --------------------------------------------------------------------------- 37// ---------------------------------------------------------------------------
46 38
47module.exports = installer 39export {
40 installApplication
41}
48 42
49// --------------------------------------------------------------------------- 43// ---------------------------------------------------------------------------
50 44
@@ -53,12 +47,12 @@ function createDirectoriesIfNotExist (callback) {
53 47
54 each(Object.keys(storages), function (key, callbackEach) { 48 each(Object.keys(storages), function (key, callbackEach) {
55 const dir = storages[key] 49 const dir = storages[key]
56 mkdirp(path.join(__dirname, '..', '..', dir), callbackEach) 50 mkdirp(join(__dirname, '..', '..', dir), callbackEach)
57 }, callback) 51 }, callback)
58} 52}
59 53
60function createOAuthClientIfNotExist (callback) { 54function createOAuthClientIfNotExist (callback) {
61 checker.clientsExist(function (err, exist) { 55 clientsExist(function (err, exist) {
62 if (err) return callback(err) 56 if (err) return callback(err)
63 57
64 // Nothing to do, clients already exist 58 // Nothing to do, clients already exist
@@ -86,7 +80,7 @@ function createOAuthClientIfNotExist (callback) {
86} 80}
87 81
88function createOAuthAdminIfNotExist (callback) { 82function createOAuthAdminIfNotExist (callback) {
89 checker.usersExist(function (err, exist) { 83 usersExist(function (err, exist) {
90 if (err) return callback(err) 84 if (err) return callback(err)
91 85
92 // Nothing to do, users already exist 86 // Nothing to do, users already exist
@@ -95,9 +89,9 @@ function createOAuthAdminIfNotExist (callback) {
95 logger.info('Creating the administrator.') 89 logger.info('Creating the administrator.')
96 90
97 const username = 'root' 91 const username = 'root'
98 const role = constants.USER_ROLES.ADMIN 92 const role = USER_ROLES.ADMIN
99 const email = constants.CONFIG.ADMIN.EMAIL 93 const email = CONFIG.ADMIN.EMAIL
100 const createOptions = {} 94 const createOptions: { validate?: boolean } = {}
101 let password = '' 95 let password = ''
102 96
103 // Do not generate a random password for tests 97 // Do not generate a random password for tests
@@ -128,7 +122,7 @@ function createOAuthAdminIfNotExist (callback) {
128 logger.info('User password: ' + password) 122 logger.info('User password: ' + password)
129 123
130 logger.info('Creating Application table.') 124 logger.info('Creating Application table.')
131 db.Application.create({ migrationVersion: constants.LAST_MIGRATION_VERSION }).asCallback(callback) 125 db.Application.create({ migrationVersion: LAST_MIGRATION_VERSION }).asCallback(callback)
132 }) 126 })
133 }) 127 })
134} 128}
diff --git a/server/initializers/migrations/0005-email-pod.js b/server/initializers/migrations/0005-email-pod.ts
index 9bbb354bf..a9200c47f 100644
--- a/server/initializers/migrations/0005-email-pod.js
+++ b/server/initializers/migrations/0005-email-pod.ts
@@ -1,9 +1,7 @@
1'use strict' 1import { waterfall } from 'async'
2
3const waterfall = require('async/waterfall')
4 2
5// utils = { transaction, queryInterface, sequelize, Sequelize } 3// utils = { transaction, queryInterface, sequelize, Sequelize }
6exports.up = function (utils, finalCallback) { 4function up (utils, finalCallback) {
7 const q = utils.queryInterface 5 const q = utils.queryInterface
8 const Sequelize = utils.Sequelize 6 const Sequelize = utils.Sequelize
9 7
@@ -36,6 +34,11 @@ exports.up = function (utils, finalCallback) {
36 ], finalCallback) 34 ], finalCallback)
37} 35}
38 36
39exports.down = function (options, callback) { 37function down (options, callback) {
40 throw new Error('Not implemented.') 38 throw new Error('Not implemented.')
41} 39}
40
41export {
42 up,
43 down
44}
diff --git a/server/initializers/migrations/0010-email-user.js b/server/initializers/migrations/0010-email-user.ts
index 1ab27133a..4b5d29394 100644
--- a/server/initializers/migrations/0010-email-user.js
+++ b/server/initializers/migrations/0010-email-user.ts
@@ -1,9 +1,7 @@
1'use strict' 1import { waterfall } from 'async'
2
3const waterfall = require('async/waterfall')
4 2
5// utils = { transaction, queryInterface, sequelize, Sequelize } 3// utils = { transaction, queryInterface, sequelize, Sequelize }
6exports.up = function (utils, finalCallback) { 4function up (utils, finalCallback) {
7 const q = utils.queryInterface 5 const q = utils.queryInterface
8 const Sequelize = utils.Sequelize 6 const Sequelize = utils.Sequelize
9 7
@@ -36,6 +34,11 @@ exports.up = function (utils, finalCallback) {
36 ], finalCallback) 34 ], finalCallback)
37} 35}
38 36
39exports.down = function (options, callback) { 37function down (options, callback) {
40 throw new Error('Not implemented.') 38 throw new Error('Not implemented.')
41} 39}
40
41export {
42 up,
43 down
44}
diff --git a/server/initializers/migrations/0015-video-views.js b/server/initializers/migrations/0015-video-views.ts
index ae49fe73c..e70869404 100644
--- a/server/initializers/migrations/0015-video-views.js
+++ b/server/initializers/migrations/0015-video-views.ts
@@ -1,7 +1,5 @@
1'use strict'
2
3// utils = { transaction, queryInterface, sequelize, Sequelize } 1// utils = { transaction, queryInterface, sequelize, Sequelize }
4exports.up = function (utils, finalCallback) { 2function up (utils, finalCallback) {
5 const q = utils.queryInterface 3 const q = utils.queryInterface
6 const Sequelize = utils.Sequelize 4 const Sequelize = utils.Sequelize
7 5
@@ -14,6 +12,11 @@ exports.up = function (utils, finalCallback) {
14 q.addColumn('Videos', 'views', data, { transaction: utils.transaction }).asCallback(finalCallback) 12 q.addColumn('Videos', 'views', data, { transaction: utils.transaction }).asCallback(finalCallback)
15} 13}
16 14
17exports.down = function (options, callback) { 15function down (options, callback) {
18 throw new Error('Not implemented.') 16 throw new Error('Not implemented.')
19} 17}
18
19export {
20 up,
21 down
22}
diff --git a/server/initializers/migrations/0020-video-likes.js b/server/initializers/migrations/0020-video-likes.ts
index 6db62cb90..e435d0657 100644
--- a/server/initializers/migrations/0020-video-likes.js
+++ b/server/initializers/migrations/0020-video-likes.ts
@@ -1,7 +1,5 @@
1'use strict'
2
3// utils = { transaction, queryInterface, sequelize, Sequelize } 1// utils = { transaction, queryInterface, sequelize, Sequelize }
4exports.up = function (utils, finalCallback) { 2function up (utils, finalCallback) {
5 const q = utils.queryInterface 3 const q = utils.queryInterface
6 const Sequelize = utils.Sequelize 4 const Sequelize = utils.Sequelize
7 5
@@ -14,6 +12,11 @@ exports.up = function (utils, finalCallback) {
14 q.addColumn('Videos', 'likes', data, { transaction: utils.transaction }).asCallback(finalCallback) 12 q.addColumn('Videos', 'likes', data, { transaction: utils.transaction }).asCallback(finalCallback)
15} 13}
16 14
17exports.down = function (options, callback) { 15function down (options, callback) {
18 throw new Error('Not implemented.') 16 throw new Error('Not implemented.')
19} 17}
18
19export {
20 up,
21 down
22}
diff --git a/server/initializers/migrations/0025-video-dislikes.js b/server/initializers/migrations/0025-video-dislikes.ts
index 40d2e7351..57e54e904 100644
--- a/server/initializers/migrations/0025-video-dislikes.js
+++ b/server/initializers/migrations/0025-video-dislikes.ts
@@ -1,7 +1,5 @@
1'use strict'
2
3// utils = { transaction, queryInterface, sequelize, Sequelize } 1// utils = { transaction, queryInterface, sequelize, Sequelize }
4exports.up = function (utils, finalCallback) { 2function up (utils, finalCallback) {
5 const q = utils.queryInterface 3 const q = utils.queryInterface
6 const Sequelize = utils.Sequelize 4 const Sequelize = utils.Sequelize
7 5
@@ -14,6 +12,11 @@ exports.up = function (utils, finalCallback) {
14 q.addColumn('Videos', 'dislikes', data, { transaction: utils.transaction }).asCallback(finalCallback) 12 q.addColumn('Videos', 'dislikes', data, { transaction: utils.transaction }).asCallback(finalCallback)
15} 13}
16 14
17exports.down = function (options, callback) { 15function down (options, callback) {
18 throw new Error('Not implemented.') 16 throw new Error('Not implemented.')
19} 17}
18
19export {
20 up,
21 down
22}
diff --git a/server/initializers/migrations/0030-video-category.js b/server/initializers/migrations/0030-video-category.ts
index ada95b2fe..1073f449c 100644
--- a/server/initializers/migrations/0030-video-category.js
+++ b/server/initializers/migrations/0030-video-category.ts
@@ -1,9 +1,7 @@
1'use strict' 1import { waterfall } from 'async'
2
3const waterfall = require('async/waterfall')
4 2
5// utils = { transaction, queryInterface, sequelize, Sequelize } 3// utils = { transaction, queryInterface, sequelize, Sequelize }
6exports.up = function (utils, finalCallback) { 4function up (utils, finalCallback) {
7 const q = utils.queryInterface 5 const q = utils.queryInterface
8 const Sequelize = utils.Sequelize 6 const Sequelize = utils.Sequelize
9 7
@@ -29,6 +27,11 @@ exports.up = function (utils, finalCallback) {
29 ], finalCallback) 27 ], finalCallback)
30} 28}
31 29
32exports.down = function (options, callback) { 30function down (options, callback) {
33 throw new Error('Not implemented.') 31 throw new Error('Not implemented.')
34} 32}
33
34export {
35 up,
36 down
37}
diff --git a/server/initializers/migrations/0035-video-licence.js b/server/initializers/migrations/0035-video-licence.ts
index 9cf75858d..9316b3c37 100644
--- a/server/initializers/migrations/0035-video-licence.js
+++ b/server/initializers/migrations/0035-video-licence.ts
@@ -1,9 +1,7 @@
1'use strict' 1import { waterfall } from 'async'
2
3const waterfall = require('async/waterfall')
4 2
5// utils = { transaction, queryInterface, sequelize, Sequelize } 3// utils = { transaction, queryInterface, sequelize, Sequelize }
6exports.up = function (utils, finalCallback) { 4function up (utils, finalCallback) {
7 const q = utils.queryInterface 5 const q = utils.queryInterface
8 const Sequelize = utils.Sequelize 6 const Sequelize = utils.Sequelize
9 7
@@ -29,6 +27,11 @@ exports.up = function (utils, finalCallback) {
29 ], finalCallback) 27 ], finalCallback)
30} 28}
31 29
32exports.down = function (options, callback) { 30function down (options, callback) {
33 throw new Error('Not implemented.') 31 throw new Error('Not implemented.')
34} 32}
33
34export {
35 up,
36 down
37}
diff --git a/server/initializers/migrations/0040-video-nsfw.js b/server/initializers/migrations/0040-video-nsfw.ts
index 7f3692b28..c61f496f1 100644
--- a/server/initializers/migrations/0040-video-nsfw.js
+++ b/server/initializers/migrations/0040-video-nsfw.ts
@@ -1,9 +1,7 @@
1'use strict' 1import { waterfall } from 'async'
2
3const waterfall = require('async/waterfall')
4 2
5// utils = { transaction, queryInterface, sequelize, Sequelize } 3// utils = { transaction, queryInterface, sequelize, Sequelize }
6exports.up = function (utils, finalCallback) { 4function up (utils, finalCallback) {
7 const q = utils.queryInterface 5 const q = utils.queryInterface
8 const Sequelize = utils.Sequelize 6 const Sequelize = utils.Sequelize
9 7
@@ -29,6 +27,11 @@ exports.up = function (utils, finalCallback) {
29 ], finalCallback) 27 ], finalCallback)
30} 28}
31 29
32exports.down = function (options, callback) { 30function down (options, callback) {
33 throw new Error('Not implemented.') 31 throw new Error('Not implemented.')
34} 32}
33
34export {
35 up,
36 down
37}
diff --git a/server/initializers/migrations/0045-user-display-nsfw.js b/server/initializers/migrations/0045-user-display-nsfw.ts
index 03624e593..1ca317795 100644
--- a/server/initializers/migrations/0045-user-display-nsfw.js
+++ b/server/initializers/migrations/0045-user-display-nsfw.ts
@@ -1,7 +1,5 @@
1'use strict'
2
3// utils = { transaction, queryInterface, sequelize, Sequelize } 1// utils = { transaction, queryInterface, sequelize, Sequelize }
4exports.up = function (utils, finalCallback) { 2function up (utils, finalCallback) {
5 const q = utils.queryInterface 3 const q = utils.queryInterface
6 const Sequelize = utils.Sequelize 4 const Sequelize = utils.Sequelize
7 5
@@ -14,6 +12,11 @@ exports.up = function (utils, finalCallback) {
14 q.addColumn('Users', 'displayNSFW', data, { transaction: utils.transaction }).asCallback(finalCallback) 12 q.addColumn('Users', 'displayNSFW', data, { transaction: utils.transaction }).asCallback(finalCallback)
15} 13}
16 14
17exports.down = function (options, callback) { 15function down (options, callback) {
18 throw new Error('Not implemented.') 16 throw new Error('Not implemented.')
19} 17}
18
19export {
20 up,
21 down
22}
diff --git a/server/initializers/migrations/0050-video-language.js b/server/initializers/migrations/0050-video-language.ts
index 1c978758d..95d0a473a 100644
--- a/server/initializers/migrations/0050-video-language.js
+++ b/server/initializers/migrations/0050-video-language.ts
@@ -1,7 +1,5 @@
1'use strict'
2
3// utils = { transaction, queryInterface, sequelize, Sequelize } 1// utils = { transaction, queryInterface, sequelize, Sequelize }
4exports.up = function (utils, finalCallback) { 2function up (utils, finalCallback) {
5 const q = utils.queryInterface 3 const q = utils.queryInterface
6 const Sequelize = utils.Sequelize 4 const Sequelize = utils.Sequelize
7 5
@@ -14,6 +12,11 @@ exports.up = function (utils, finalCallback) {
14 q.addColumn('Videos', 'language', data, { transaction: utils.transaction }).asCallback(finalCallback) 12 q.addColumn('Videos', 'language', data, { transaction: utils.transaction }).asCallback(finalCallback)
15} 13}
16 14
17exports.down = function (options, callback) { 15function down (options, callback) {
18 throw new Error('Not implemented.') 16 throw new Error('Not implemented.')
19} 17}
18
19export {
20 up,
21 down
22}
diff --git a/server/initializers/migrator.js b/server/initializers/migrator.ts
index 9a6415b1a..cfa3220e0 100644
--- a/server/initializers/migrator.js
+++ b/server/initializers/migrator.ts
@@ -1,17 +1,10 @@
1'use strict' 1import { waterfall, eachSeries } from 'async'
2import fs = require('fs')
3import path = require('path')
2 4
3const waterfall = require('async/waterfall')
4const eachSeries = require('async/eachSeries')
5const fs = require('fs')
6const path = require('path')
7
8const constants = require('./constants')
9const db = require('./database') 5const db = require('./database')
10const logger = require('../helpers/logger') 6import { LAST_MIGRATION_VERSION } from './constants'
11 7import { logger } from '../helpers'
12const migrator = {
13 migrate: migrate
14}
15 8
16function migrate (finalCallback) { 9function migrate (finalCallback) {
17 waterfall([ 10 waterfall([
@@ -46,7 +39,7 @@ function migrate (finalCallback) {
46 39
47 function abortMigrationIfNotNeeded (actualVersion, callback) { 40 function abortMigrationIfNotNeeded (actualVersion, callback) {
48 // No need migrations 41 // No need migrations
49 if (actualVersion >= constants.LAST_MIGRATION_VERSION) return finalCallback(null) 42 if (actualVersion >= LAST_MIGRATION_VERSION) return finalCallback(null)
50 43
51 return callback(null, actualVersion) 44 return callback(null, actualVersion)
52 }, 45 },
@@ -66,7 +59,7 @@ function migrate (finalCallback) {
66 }, function (err) { 59 }, function (err) {
67 if (err) return callback(err) 60 if (err) return callback(err)
68 61
69 logger.info('Migrations finished. New migration version schema: %s', constants.LAST_MIGRATION_VERSION) 62 logger.info('Migrations finished. New migration version schema: %s', LAST_MIGRATION_VERSION)
70 return callback(null) 63 return callback(null)
71 }) 64 })
72 } 65 }
@@ -75,7 +68,9 @@ function migrate (finalCallback) {
75 68
76// --------------------------------------------------------------------------- 69// ---------------------------------------------------------------------------
77 70
78module.exports = migrator 71export {
72 migrate
73}
79 74
80// --------------------------------------------------------------------------- 75// ---------------------------------------------------------------------------
81 76
diff --git a/server/lib/friends.js b/server/lib/friends.ts
index 6dd32406c..b32783019 100644
--- a/server/lib/friends.js
+++ b/server/lib/friends.ts
@@ -1,48 +1,35 @@
1'use strict' 1import { each, eachLimit, eachSeries, series, waterfall } from 'async'
2import request = require('request')
2 3
3const each = require('async/each')
4const eachLimit = require('async/eachLimit')
5const eachSeries = require('async/eachSeries')
6const series = require('async/series')
7const request = require('request')
8const waterfall = require('async/waterfall')
9
10const constants = require('../initializers/constants')
11const db = require('../initializers/database') 4const db = require('../initializers/database')
12const logger = require('../helpers/logger') 5import {
13const peertubeCrypto = require('../helpers/peertube-crypto') 6 API_VERSION,
14const requests = require('../helpers/requests') 7 CONFIG,
15const utils = require('../helpers/utils') 8 REQUESTS_IN_PARALLEL,
16const RequestScheduler = require('./request/request-scheduler') 9 REQUEST_ENDPOINTS,
17const RequestVideoQaduScheduler = require('./request/request-video-qadu-scheduler') 10 REQUEST_ENDPOINT_ACTIONS,
18const RequestVideoEventScheduler = require('./request/request-video-event-scheduler') 11 REMOTE_SCHEME
19 12} from '../initializers'
20const ENDPOINT_ACTIONS = constants.REQUEST_ENDPOINT_ACTIONS[constants.REQUEST_ENDPOINTS.VIDEOS] 13import {
14 logger,
15 getMyPublicCert,
16 makeSecureRequest,
17 makeRetryRequest,
18 createEmptyCallback
19} from '../helpers'
20import {
21 RequestScheduler,
22 RequestVideoQaduScheduler,
23 RequestVideoEventScheduler
24} from './request'
25
26const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS]
21 27
22const requestScheduler = new RequestScheduler() 28const requestScheduler = new RequestScheduler()
23const requestVideoQaduScheduler = new RequestVideoQaduScheduler() 29const requestVideoQaduScheduler = new RequestVideoQaduScheduler()
24const requestVideoEventScheduler = new RequestVideoEventScheduler() 30const requestVideoEventScheduler = new RequestVideoEventScheduler()
25 31
26const friends = { 32function activateSchedulers () {
27 activate,
28 addVideoToFriends,
29 updateVideoToFriends,
30 reportAbuseVideoToFriend,
31 quickAndDirtyUpdateVideoToFriends,
32 quickAndDirtyUpdatesVideoToFriends,
33 addEventToRemoteVideo,
34 addEventsToRemoteVideo,
35 hasFriends,
36 makeFriends,
37 quitFriends,
38 removeVideoToFriends,
39 sendOwnedVideosToPod,
40 getRequestScheduler,
41 getRequestVideoQaduScheduler,
42 getRequestVideoEventScheduler
43}
44
45function activate () {
46 requestScheduler.activate() 33 requestScheduler.activate()
47 requestVideoQaduScheduler.activate() 34 requestVideoQaduScheduler.activate()
48 requestVideoEventScheduler.activate() 35 requestVideoEventScheduler.activate()
@@ -51,7 +38,7 @@ function activate () {
51function addVideoToFriends (videoData, transaction, callback) { 38function addVideoToFriends (videoData, transaction, callback) {
52 const options = { 39 const options = {
53 type: ENDPOINT_ACTIONS.ADD, 40 type: ENDPOINT_ACTIONS.ADD,
54 endpoint: constants.REQUEST_ENDPOINTS.VIDEOS, 41 endpoint: REQUEST_ENDPOINTS.VIDEOS,
55 data: videoData, 42 data: videoData,
56 transaction 43 transaction
57 } 44 }
@@ -61,7 +48,7 @@ function addVideoToFriends (videoData, transaction, callback) {
61function updateVideoToFriends (videoData, transaction, callback) { 48function updateVideoToFriends (videoData, transaction, callback) {
62 const options = { 49 const options = {
63 type: ENDPOINT_ACTIONS.UPDATE, 50 type: ENDPOINT_ACTIONS.UPDATE,
64 endpoint: constants.REQUEST_ENDPOINTS.VIDEOS, 51 endpoint: REQUEST_ENDPOINTS.VIDEOS,
65 data: videoData, 52 data: videoData,
66 transaction 53 transaction
67 } 54 }
@@ -71,7 +58,7 @@ function updateVideoToFriends (videoData, transaction, callback) {
71function removeVideoToFriends (videoParams) { 58function removeVideoToFriends (videoParams) {
72 const options = { 59 const options = {
73 type: ENDPOINT_ACTIONS.REMOVE, 60 type: ENDPOINT_ACTIONS.REMOVE,
74 endpoint: constants.REQUEST_ENDPOINTS.VIDEOS, 61 endpoint: REQUEST_ENDPOINTS.VIDEOS,
75 data: videoParams 62 data: videoParams
76 } 63 }
77 createRequest(options) 64 createRequest(options)
@@ -80,14 +67,14 @@ function removeVideoToFriends (videoParams) {
80function reportAbuseVideoToFriend (reportData, video) { 67function reportAbuseVideoToFriend (reportData, video) {
81 const options = { 68 const options = {
82 type: ENDPOINT_ACTIONS.REPORT_ABUSE, 69 type: ENDPOINT_ACTIONS.REPORT_ABUSE,
83 endpoint: constants.REQUEST_ENDPOINTS.VIDEOS, 70 endpoint: REQUEST_ENDPOINTS.VIDEOS,
84 data: reportData, 71 data: reportData,
85 toIds: [ video.Author.podId ] 72 toIds: [ video.Author.podId ]
86 } 73 }
87 createRequest(options) 74 createRequest(options)
88} 75}
89 76
90function quickAndDirtyUpdateVideoToFriends (qaduParams, transaction, callback) { 77function quickAndDirtyUpdateVideoToFriends (qaduParams, transaction?, callback?) {
91 const options = { 78 const options = {
92 videoId: qaduParams.videoId, 79 videoId: qaduParams.videoId,
93 type: qaduParams.type, 80 type: qaduParams.type,
@@ -110,7 +97,7 @@ function quickAndDirtyUpdatesVideoToFriends (qadusParams, transaction, finalCall
110 series(tasks, finalCallback) 97 series(tasks, finalCallback)
111} 98}
112 99
113function addEventToRemoteVideo (eventParams, transaction, callback) { 100function addEventToRemoteVideo (eventParams, transaction?, callback?) {
114 const options = { 101 const options = {
115 videoId: eventParams.videoId, 102 videoId: eventParams.videoId,
116 type: eventParams.type, 103 type: eventParams.type,
@@ -146,7 +133,7 @@ function makeFriends (hosts, callback) {
146 const podsScore = {} 133 const podsScore = {}
147 134
148 logger.info('Make friends!') 135 logger.info('Make friends!')
149 peertubeCrypto.getMyPublicCert(function (err, cert) { 136 getMyPublicCert(function (err, cert) {
150 if (err) { 137 if (err) {
151 logger.error('Cannot read public cert.') 138 logger.error('Cannot read public cert.')
152 return callback(err) 139 return callback(err)
@@ -186,16 +173,17 @@ function quitFriends (callback) {
186 function announceIQuitMyFriends (pods, callbackAsync) { 173 function announceIQuitMyFriends (pods, callbackAsync) {
187 const requestParams = { 174 const requestParams = {
188 method: 'POST', 175 method: 'POST',
189 path: '/api/' + constants.API_VERSION + '/remote/pods/remove', 176 path: '/api/' + API_VERSION + '/remote/pods/remove',
190 sign: true 177 sign: true,
178 toPod: null
191 } 179 }
192 180
193 // Announce we quit them 181 // Announce we quit them
194 // We don't care if the request fails 182 // We don't care if the request fails
195 // The other pod will exclude us automatically after a while 183 // The other pod will exclude us automatically after a while
196 eachLimit(pods, constants.REQUESTS_IN_PARALLEL, function (pod, callbackEach) { 184 eachLimit(pods, REQUESTS_IN_PARALLEL, function (pod, callbackEach) {
197 requestParams.toPod = pod 185 requestParams.toPod = pod
198 requests.makeSecureRequest(requestParams, callbackEach) 186 makeSecureRequest(requestParams, callbackEach)
199 }, function (err) { 187 }, function (err) {
200 if (err) { 188 if (err) {
201 logger.error('Some errors while quitting friends.', { err: err }) 189 logger.error('Some errors while quitting friends.', { err: err })
@@ -207,7 +195,7 @@ function quitFriends (callback) {
207 }, 195 },
208 196
209 function removePodsFromDB (pods, callbackAsync) { 197 function removePodsFromDB (pods, callbackAsync) {
210 each(pods, function (pod, callbackEach) { 198 each(pods, function (pod: any, callbackEach) {
211 pod.destroy().asCallback(callbackEach) 199 pod.destroy().asCallback(callbackEach)
212 }, callbackAsync) 200 }, callbackAsync)
213 } 201 }
@@ -239,7 +227,7 @@ function sendOwnedVideosToPod (podId) {
239 227
240 const options = { 228 const options = {
241 type: 'add', 229 type: 'add',
242 endpoint: constants.REQUEST_ENDPOINTS.VIDEOS, 230 endpoint: REQUEST_ENDPOINTS.VIDEOS,
243 data: remoteVideo, 231 data: remoteVideo,
244 toIds: [ podId ] 232 toIds: [ podId ]
245 } 233 }
@@ -263,7 +251,24 @@ function getRequestVideoEventScheduler () {
263 251
264// --------------------------------------------------------------------------- 252// ---------------------------------------------------------------------------
265 253
266module.exports = friends 254export {
255 activateSchedulers,
256 addVideoToFriends,
257 updateVideoToFriends,
258 reportAbuseVideoToFriend,
259 quickAndDirtyUpdateVideoToFriends,
260 quickAndDirtyUpdatesVideoToFriends,
261 addEventToRemoteVideo,
262 addEventsToRemoteVideo,
263 hasFriends,
264 makeFriends,
265 quitFriends,
266 removeVideoToFriends,
267 sendOwnedVideosToPod,
268 getRequestScheduler,
269 getRequestVideoQaduScheduler,
270 getRequestVideoEventScheduler
271}
267 272
268// --------------------------------------------------------------------------- 273// ---------------------------------------------------------------------------
269 274
@@ -304,9 +309,9 @@ function computeWinningPods (hosts, podsScore) {
304} 309}
305 310
306function getForeignPodsList (host, callback) { 311function getForeignPodsList (host, callback) {
307 const path = '/api/' + constants.API_VERSION + '/pods' 312 const path = '/api/' + API_VERSION + '/pods'
308 313
309 request.get(constants.REMOTE_SCHEME.HTTP + '://' + host + path, function (err, response, body) { 314 request.get(REMOTE_SCHEME.HTTP + '://' + host + path, function (err, response, body) {
310 if (err) return callback(err) 315 if (err) return callback(err)
311 316
312 try { 317 try {
@@ -324,18 +329,18 @@ function makeRequestsToWinningPods (cert, podsList, callback) {
324 // Flush pool requests 329 // Flush pool requests
325 requestScheduler.forceSend() 330 requestScheduler.forceSend()
326 331
327 eachLimit(podsList, constants.REQUESTS_IN_PARALLEL, function (pod, callbackEach) { 332 eachLimit(podsList, REQUESTS_IN_PARALLEL, function (pod: any, callbackEach) {
328 const params = { 333 const params = {
329 url: constants.REMOTE_SCHEME.HTTP + '://' + pod.host + '/api/' + constants.API_VERSION + '/pods/', 334 url: REMOTE_SCHEME.HTTP + '://' + pod.host + '/api/' + API_VERSION + '/pods/',
330 method: 'POST', 335 method: 'POST',
331 json: { 336 json: {
332 host: constants.CONFIG.WEBSERVER.HOST, 337 host: CONFIG.WEBSERVER.HOST,
333 email: constants.CONFIG.ADMIN.EMAIL, 338 email: CONFIG.ADMIN.EMAIL,
334 publicKey: cert 339 publicKey: cert
335 } 340 }
336 } 341 }
337 342
338 requests.makeRetryRequest(params, function (err, res, body) { 343 makeRetryRequest(params, function (err, res, body) {
339 if (err) { 344 if (err) {
340 logger.error('Error with adding %s pod.', pod.host, { error: err }) 345 logger.error('Error with adding %s pod.', pod.host, { error: err })
341 // Don't break the process 346 // Don't break the process
@@ -372,8 +377,8 @@ function makeRequestsToWinningPods (cert, podsList, callback) {
372 377
373// Wrapper that populate "toIds" argument with all our friends if it is not specified 378// Wrapper that populate "toIds" argument with all our friends if it is not specified
374// { type, endpoint, data, toIds, transaction } 379// { type, endpoint, data, toIds, transaction }
375function createRequest (options, callback) { 380function createRequest (options, callback?) {
376 if (!callback) callback = function () {} 381 if (!callback) callback = function () { /* empty */ }
377 if (options.toIds) return requestScheduler.createRequest(options, callback) 382 if (options.toIds) return requestScheduler.createRequest(options, callback)
378 383
379 // If the "toIds" pods is not specified, we send the request to all our friends 384 // If the "toIds" pods is not specified, we send the request to all our friends
@@ -389,17 +394,17 @@ function createRequest (options, callback) {
389} 394}
390 395
391function createVideoQaduRequest (options, callback) { 396function createVideoQaduRequest (options, callback) {
392 if (!callback) callback = utils.createEmptyCallback() 397 if (!callback) callback = createEmptyCallback()
393 398
394 requestVideoQaduScheduler.createRequest(options, callback) 399 requestVideoQaduScheduler.createRequest(options, callback)
395} 400}
396 401
397function createVideoEventRequest (options, callback) { 402function createVideoEventRequest (options, callback) {
398 if (!callback) callback = utils.createEmptyCallback() 403 if (!callback) callback = createEmptyCallback()
399 404
400 requestVideoEventScheduler.createRequest(options, callback) 405 requestVideoEventScheduler.createRequest(options, callback)
401} 406}
402 407
403function isMe (host) { 408function isMe (host) {
404 return host === constants.CONFIG.WEBSERVER.HOST 409 return host === CONFIG.WEBSERVER.HOST
405} 410}
diff --git a/server/lib/index.ts b/server/lib/index.ts
new file mode 100644
index 000000000..b8697fb96
--- /dev/null
+++ b/server/lib/index.ts
@@ -0,0 +1,4 @@
1export * from './jobs'
2export * from './request'
3export * from './friends'
4export * from './oauth-model'
diff --git a/server/lib/jobs/handlers/index.js b/server/lib/jobs/handlers/index.js
deleted file mode 100644
index 59c1ccce5..000000000
--- a/server/lib/jobs/handlers/index.js
+++ /dev/null
@@ -1,7 +0,0 @@
1'use strict'
2
3const videoTranscoder = require('./video-transcoder')
4
5module.exports = {
6 videoTranscoder
7}
diff --git a/server/lib/jobs/handlers/index.ts b/server/lib/jobs/handlers/index.ts
new file mode 100644
index 000000000..ae5440031
--- /dev/null
+++ b/server/lib/jobs/handlers/index.ts
@@ -0,0 +1,9 @@
1import * as videoTranscoder from './video-transcoder'
2
3const jobHandlers = {
4 videoTranscoder
5}
6
7export {
8 jobHandlers
9}
diff --git a/server/lib/jobs/handlers/video-transcoder.js b/server/lib/jobs/handlers/video-transcoder.ts
index d2ad4f9c7..35db5fb96 100644
--- a/server/lib/jobs/handlers/video-transcoder.js
+++ b/server/lib/jobs/handlers/video-transcoder.ts
@@ -1,16 +1,6 @@
1'use strict'
2
3const db = require('../../../initializers/database') 1const db = require('../../../initializers/database')
4const logger = require('../../../helpers/logger') 2import { logger } from '../../../helpers'
5const friends = require('../../../lib/friends') 3import { addVideoToFriends } from '../../../lib'
6
7const VideoTranscoderHandler = {
8 process,
9 onError,
10 onSuccess
11}
12
13// ---------------------------------------------------------------------------
14 4
15function process (data, callback) { 5function process (data, callback) {
16 db.Video.loadAndPopulateAuthorAndPodAndTags(data.id, function (err, video) { 6 db.Video.loadAndPopulateAuthorAndPodAndTags(data.id, function (err, video) {
@@ -34,10 +24,14 @@ function onSuccess (data, jobId, video, callback) {
34 if (err) return callback(err) 24 if (err) return callback(err)
35 25
36 // Now we'll add the video's meta data to our friends 26 // Now we'll add the video's meta data to our friends
37 friends.addVideoToFriends(remoteVideo, null, callback) 27 addVideoToFriends(remoteVideo, null, callback)
38 }) 28 })
39} 29}
40 30
41// --------------------------------------------------------------------------- 31// ---------------------------------------------------------------------------
42 32
43module.exports = VideoTranscoderHandler 33export {
34 process,
35 onError,
36 onSuccess
37}
diff --git a/server/lib/jobs/index.ts b/server/lib/jobs/index.ts
new file mode 100644
index 000000000..b18a3d845
--- /dev/null
+++ b/server/lib/jobs/index.ts
@@ -0,0 +1 @@
export * from './job-scheduler'
diff --git a/server/lib/jobs/job-scheduler.js b/server/lib/jobs/job-scheduler.js
deleted file mode 100644
index 7b239577f..000000000
--- a/server/lib/jobs/job-scheduler.js
+++ /dev/null
@@ -1,129 +0,0 @@
1'use strict'
2
3const forever = require('async/forever')
4const queue = require('async/queue')
5
6const constants = require('../../initializers/constants')
7const db = require('../../initializers/database')
8const logger = require('../../helpers/logger')
9
10const jobHandlers = require('./handlers')
11
12const jobScheduler = {
13 activate,
14 createJob
15}
16
17function activate () {
18 const limit = constants.JOBS_FETCH_LIMIT_PER_CYCLE
19
20 logger.info('Jobs scheduler activated.')
21
22 const jobsQueue = queue(processJob)
23
24 // Finish processing jobs from a previous start
25 const state = constants.JOB_STATES.PROCESSING
26 db.Job.listWithLimit(limit, state, function (err, jobs) {
27 enqueueJobs(err, jobsQueue, jobs)
28
29 forever(
30 function (next) {
31 if (jobsQueue.length() !== 0) {
32 // Finish processing the queue first
33 return setTimeout(next, constants.JOBS_FETCHING_INTERVAL)
34 }
35
36 const state = constants.JOB_STATES.PENDING
37 db.Job.listWithLimit(limit, state, function (err, jobs) {
38 if (err) {
39 logger.error('Cannot list pending jobs.', { error: err })
40 } else {
41 jobs.forEach(function (job) {
42 jobsQueue.push(job)
43 })
44 }
45
46 // Optimization: we could use "drain" from queue object
47 return setTimeout(next, constants.JOBS_FETCHING_INTERVAL)
48 })
49 }
50 )
51 })
52}
53
54// ---------------------------------------------------------------------------
55
56module.exports = jobScheduler
57
58// ---------------------------------------------------------------------------
59
60function enqueueJobs (err, jobsQueue, jobs) {
61 if (err) {
62 logger.error('Cannot list pending jobs.', { error: err })
63 } else {
64 jobs.forEach(function (job) {
65 jobsQueue.push(job)
66 })
67 }
68}
69
70function createJob (transaction, handlerName, handlerInputData, callback) {
71 const createQuery = {
72 state: constants.JOB_STATES.PENDING,
73 handlerName,
74 handlerInputData
75 }
76 const options = { transaction }
77
78 db.Job.create(createQuery, options).asCallback(callback)
79}
80
81function processJob (job, callback) {
82 const jobHandler = jobHandlers[job.handlerName]
83
84 logger.info('Processing job %d with handler %s.', job.id, job.handlerName)
85
86 job.state = constants.JOB_STATES.PROCESSING
87 job.save().asCallback(function (err) {
88 if (err) return cannotSaveJobError(err, callback)
89
90 if (jobHandler === undefined) {
91 logger.error('Unknown job handler for job %s.', jobHandler.handlerName)
92 return callback()
93 }
94
95 return jobHandler.process(job.handlerInputData, function (err, result) {
96 if (err) {
97 logger.error('Error in job handler %s.', job.handlerName, { error: err })
98 return onJobError(jobHandler, job, result, callback)
99 }
100
101 return onJobSuccess(jobHandler, job, result, callback)
102 })
103 })
104}
105
106function onJobError (jobHandler, job, jobResult, callback) {
107 job.state = constants.JOB_STATES.ERROR
108
109 job.save().asCallback(function (err) {
110 if (err) return cannotSaveJobError(err, callback)
111
112 return jobHandler.onError(err, job.id, jobResult, callback)
113 })
114}
115
116function onJobSuccess (jobHandler, job, jobResult, callback) {
117 job.state = constants.JOB_STATES.SUCCESS
118
119 job.save().asCallback(function (err) {
120 if (err) return cannotSaveJobError(err, callback)
121
122 return jobHandler.onSuccess(err, job.id, jobResult, callback)
123 })
124}
125
126function cannotSaveJobError (err, callback) {
127 logger.error('Cannot save new job state.', { error: err })
128 return callback(err)
129}
diff --git a/server/lib/jobs/job-scheduler.ts b/server/lib/jobs/job-scheduler.ts
new file mode 100644
index 000000000..7b8c6faf9
--- /dev/null
+++ b/server/lib/jobs/job-scheduler.ts
@@ -0,0 +1,137 @@
1import { forever, queue } from 'async'
2
3const db = require('../../initializers/database')
4import {
5 JOBS_FETCHING_INTERVAL,
6 JOBS_FETCH_LIMIT_PER_CYCLE,
7 JOB_STATES
8} from '../../initializers'
9import { logger } from '../../helpers'
10import { jobHandlers } from './handlers'
11
12class JobScheduler {
13
14 private static instance: JobScheduler
15
16 private constructor () { }
17
18 static get Instance () {
19 return this.instance || (this.instance = new this())
20 }
21
22 activate () {
23 const limit = JOBS_FETCH_LIMIT_PER_CYCLE
24
25 logger.info('Jobs scheduler activated.')
26
27 const jobsQueue = queue(this.processJob)
28
29 // Finish processing jobs from a previous start
30 const state = JOB_STATES.PROCESSING
31 db.Job.listWithLimit(limit, state, (err, jobs) => {
32 this.enqueueJobs(err, jobsQueue, jobs)
33
34 forever(
35 next => {
36 if (jobsQueue.length() !== 0) {
37 // Finish processing the queue first
38 return setTimeout(next, JOBS_FETCHING_INTERVAL)
39 }
40
41 const state = JOB_STATES.PENDING
42 db.Job.listWithLimit(limit, state, (err, jobs) => {
43 if (err) {
44 logger.error('Cannot list pending jobs.', { error: err })
45 } else {
46 jobs.forEach(job => {
47 jobsQueue.push(job)
48 })
49 }
50
51 // Optimization: we could use "drain" from queue object
52 return setTimeout(next, JOBS_FETCHING_INTERVAL)
53 })
54 },
55
56 err => { logger.error('Error in job scheduler queue.', { error: err }) }
57 )
58 })
59 }
60
61 createJob (transaction, handlerName, handlerInputData, callback) {
62 const createQuery = {
63 state: JOB_STATES.PENDING,
64 handlerName,
65 handlerInputData
66 }
67 const options = { transaction }
68
69 db.Job.create(createQuery, options).asCallback(callback)
70 }
71
72 private enqueueJobs (err, jobsQueue, jobs) {
73 if (err) {
74 logger.error('Cannot list pending jobs.', { error: err })
75 } else {
76 jobs.forEach(job => {
77 jobsQueue.push(job)
78 })
79 }
80 }
81
82 private processJob (job, callback) {
83 const jobHandler = jobHandlers[job.handlerName]
84
85 logger.info('Processing job %d with handler %s.', job.id, job.handlerName)
86
87 job.state = JOB_STATES.PROCESSING
88 job.save().asCallback(err => {
89 if (err) return this.cannotSaveJobError(err, callback)
90
91 if (jobHandler === undefined) {
92 logger.error('Unknown job handler for job %s.', jobHandler.handlerName)
93 return callback()
94 }
95
96 return jobHandler.process(job.handlerInputData, (err, result) => {
97 if (err) {
98 logger.error('Error in job handler %s.', job.handlerName, { error: err })
99 return this.onJobError(jobHandler, job, result, callback)
100 }
101
102 return this.onJobSuccess(jobHandler, job, result, callback)
103 })
104 })
105 }
106
107 private onJobError (jobHandler, job, jobResult, callback) {
108 job.state = JOB_STATES.ERROR
109
110 job.save().asCallback(err => {
111 if (err) return this.cannotSaveJobError(err, callback)
112
113 return jobHandler.onError(err, job.id, jobResult, callback)
114 })
115 }
116
117 private onJobSuccess (jobHandler, job, jobResult, callback) {
118 job.state = JOB_STATES.SUCCESS
119
120 job.save().asCallback(err => {
121 if (err) return this.cannotSaveJobError(err, callback)
122
123 return jobHandler.onSuccess(err, job.id, jobResult, callback)
124 })
125 }
126
127 private cannotSaveJobError (err, callback) {
128 logger.error('Cannot save new job state.', { error: err })
129 return callback(err)
130 }
131}
132
133// ---------------------------------------------------------------------------
134
135export {
136 JobScheduler
137}
diff --git a/server/lib/oauth-model.js b/server/lib/oauth-model.ts
index 1c12f1b14..00b1afcf5 100644
--- a/server/lib/oauth-model.js
+++ b/server/lib/oauth-model.ts
@@ -1,15 +1,5 @@
1const db = require('../initializers/database') 1const db = require('../initializers/database')
2const logger = require('../helpers/logger') 2import { logger } from '../helpers'
3
4// See https://github.com/oauthjs/node-oauth2-server/wiki/Model-specification for the model specifications
5const OAuthModel = {
6 getAccessToken,
7 getClient,
8 getRefreshToken,
9 getUser,
10 revokeToken,
11 saveToken
12}
13 3
14// --------------------------------------------------------------------------- 4// ---------------------------------------------------------------------------
15 5
@@ -94,4 +84,12 @@ function saveToken (token, client, user) {
94 84
95// --------------------------------------------------------------------------- 85// ---------------------------------------------------------------------------
96 86
97module.exports = OAuthModel 87// See https://github.com/oauthjs/node-oauth2-server/wiki/Model-specification for the model specifications
88export {
89 getAccessToken,
90 getClient,
91 getRefreshToken,
92 getUser,
93 revokeToken,
94 saveToken
95}
diff --git a/server/lib/request/base-request-scheduler.js b/server/lib/request/base-request-scheduler.ts
index 782448340..7fc88b5f1 100644
--- a/server/lib/request/base-request-scheduler.js
+++ b/server/lib/request/base-request-scheduler.ts
@@ -1,19 +1,31 @@
1'use strict' 1import { eachLimit } from 'async/eachLimit'
2 2
3const eachLimit = require('async/eachLimit')
4
5const constants = require('../../initializers/constants')
6const db = require('../../initializers/database') 3const db = require('../../initializers/database')
7const logger = require('../../helpers/logger') 4import { logger, makeSecureRequest } from '../../helpers'
8const requests = require('../../helpers/requests') 5import {
9 6 API_VERSION,
10module.exports = class BaseRequestScheduler { 7 REQUESTS_IN_PARALLEL,
11 constructor (options) { 8 REQUESTS_INTERVAL
9} from '../../initializers'
10
11abstract class BaseRequestScheduler {
12 protected lastRequestTimestamp: number
13 protected timer: NodeJS.Timer
14 protected requestInterval: number
15 protected limitPods: number
16 protected limitPerPod: number
17 protected description: string
18
19 constructor () {
12 this.lastRequestTimestamp = 0 20 this.lastRequestTimestamp = 0
13 this.timer = null 21 this.timer = null
14 this.requestInterval = constants.REQUESTS_INTERVAL 22 this.requestInterval = REQUESTS_INTERVAL
15 } 23 }
16 24
25 abstract getRequestModel ()
26 abstract getRequestToPodModel ()
27 abstract buildRequestObjects (requests: any)
28
17 activate () { 29 activate () {
18 logger.info('Requests scheduler activated.') 30 logger.info('Requests scheduler activated.')
19 this.lastRequestTimestamp = Date.now() 31 this.lastRequestTimestamp = Date.now()
@@ -38,30 +50,34 @@ module.exports = class BaseRequestScheduler {
38 remainingMilliSeconds () { 50 remainingMilliSeconds () {
39 if (this.timer === null) return -1 51 if (this.timer === null) return -1
40 52
41 return constants.REQUESTS_INTERVAL - (Date.now() - this.lastRequestTimestamp) 53 return REQUESTS_INTERVAL - (Date.now() - this.lastRequestTimestamp)
42 } 54 }
43 55
44 remainingRequestsCount (callback) { 56 remainingRequestsCount (callback) {
45 return this.getRequestModel().countTotalRequests(callback) 57 return this.getRequestModel().countTotalRequests(callback)
46 } 58 }
47 59
60 flush (callback) {
61 this.getRequestModel().removeAll(callback)
62 }
63
48 // --------------------------------------------------------------------------- 64 // ---------------------------------------------------------------------------
49 65
50 // Make a requests to friends of a certain type 66 // Make a requests to friends of a certain type
51 makeRequest (toPod, requestEndpoint, requestsToMake, callback) { 67 protected makeRequest (toPod, requestEndpoint, requestsToMake, callback) {
52 if (!callback) callback = function () {} 68 if (!callback) callback = function () { /* empty */ }
53 69
54 const params = { 70 const params = {
55 toPod: toPod, 71 toPod: toPod,
56 sign: true, // Prove our identity 72 sign: true, // Prove our identity
57 method: 'POST', 73 method: 'POST',
58 path: '/api/' + constants.API_VERSION + '/remote/' + requestEndpoint, 74 path: '/api/' + API_VERSION + '/remote/' + requestEndpoint,
59 data: requestsToMake // Requests we need to make 75 data: requestsToMake // Requests we need to make
60 } 76 }
61 77
62 // Make multiple retry requests to all of pods 78 // Make multiple retry requests to all of pods
63 // The function fire some useful callbacks 79 // The function fire some useful callbacks
64 requests.makeSecureRequest(params, (err, res) => { 80 makeSecureRequest(params, (err, res) => {
65 if (err || (res.statusCode !== 200 && res.statusCode !== 201 && res.statusCode !== 204)) { 81 if (err || (res.statusCode !== 200 && res.statusCode !== 201 && res.statusCode !== 204)) {
66 err = err ? err.message : 'Status code not 20x : ' + res.statusCode 82 err = err ? err.message : 'Status code not 20x : ' + res.statusCode
67 logger.error('Error sending secure request to %s pod.', toPod.host, { error: err }) 83 logger.error('Error sending secure request to %s pod.', toPod.host, { error: err })
@@ -74,7 +90,7 @@ module.exports = class BaseRequestScheduler {
74 } 90 }
75 91
76 // Make all the requests of the scheduler 92 // Make all the requests of the scheduler
77 makeRequests () { 93 protected makeRequests () {
78 this.getRequestModel().listWithLimitAndRandom(this.limitPods, this.limitPerPod, (err, requests) => { 94 this.getRequestModel().listWithLimitAndRandom(this.limitPods, this.limitPerPod, (err, requests) => {
79 if (err) { 95 if (err) {
80 logger.error('Cannot get the list of "%s".', this.description, { err: err }) 96 logger.error('Cannot get the list of "%s".', this.description, { err: err })
@@ -95,7 +111,7 @@ module.exports = class BaseRequestScheduler {
95 const goodPods = [] 111 const goodPods = []
96 const badPods = [] 112 const badPods = []
97 113
98 eachLimit(Object.keys(requestsToMakeGrouped), constants.REQUESTS_IN_PARALLEL, (hashKey, callbackEach) => { 114 eachLimit(Object.keys(requestsToMakeGrouped), REQUESTS_IN_PARALLEL, (hashKey, callbackEach) => {
99 const requestToMake = requestsToMakeGrouped[hashKey] 115 const requestToMake = requestsToMakeGrouped[hashKey]
100 const toPod = requestToMake.toPod 116 const toPod = requestToMake.toPod
101 117
@@ -122,15 +138,17 @@ module.exports = class BaseRequestScheduler {
122 }) 138 })
123 } 139 }
124 140
125 flush (callback) { 141 protected afterRequestHook () {
126 this.getRequestModel().removeAll(callback)
127 }
128
129 afterRequestHook () {
130 // Nothing to do, let children reimplement it 142 // Nothing to do, let children reimplement it
131 } 143 }
132 144
133 afterRequestsHook () { 145 protected afterRequestsHook () {
134 // Nothing to do, let children reimplement it 146 // Nothing to do, let children reimplement it
135 } 147 }
136} 148}
149
150// ---------------------------------------------------------------------------
151
152export {
153 BaseRequestScheduler
154}
diff --git a/server/lib/request/index.ts b/server/lib/request/index.ts
new file mode 100644
index 000000000..c98f956db
--- /dev/null
+++ b/server/lib/request/index.ts
@@ -0,0 +1,3 @@
1export * from './request-scheduler'
2export * from './request-video-event-scheduler'
3export * from './request-video-qadu-scheduler'
diff --git a/server/lib/request/request-scheduler.js b/server/lib/request/request-scheduler.ts
index 555ec3e54..2006a6f03 100644
--- a/server/lib/request/request-scheduler.js
+++ b/server/lib/request/request-scheduler.ts
@@ -1,17 +1,18 @@
1'use strict'
2
3const constants = require('../../initializers/constants')
4const BaseRequestScheduler = require('./base-request-scheduler')
5const db = require('../../initializers/database') 1const db = require('../../initializers/database')
6const logger = require('../../helpers/logger') 2import { BaseRequestScheduler } from './base-request-scheduler'
7 3import { logger } from '../../helpers'
8module.exports = class RequestScheduler extends BaseRequestScheduler { 4import {
5 REQUESTS_LIMIT_PODS,
6 REQUESTS_LIMIT_PER_POD
7} from '../../initializers'
8
9class RequestScheduler extends BaseRequestScheduler {
9 constructor () { 10 constructor () {
10 super() 11 super()
11 12
12 // We limit the size of the requests 13 // We limit the size of the requests
13 this.limitPods = constants.REQUESTS_LIMIT_PODS 14 this.limitPods = REQUESTS_LIMIT_PODS
14 this.limitPerPod = constants.REQUESTS_LIMIT_PER_POD 15 this.limitPerPod = REQUESTS_LIMIT_PER_POD
15 16
16 this.description = 'requests' 17 this.description = 'requests'
17 } 18 }
@@ -95,3 +96,9 @@ module.exports = class RequestScheduler extends BaseRequestScheduler {
95 }) 96 })
96 } 97 }
97} 98}
99
100// ---------------------------------------------------------------------------
101
102export {
103 RequestScheduler
104}
diff --git a/server/lib/request/request-video-event-scheduler.js b/server/lib/request/request-video-event-scheduler.ts
index e54d34f4a..6e5306c7d 100644
--- a/server/lib/request/request-video-event-scheduler.js
+++ b/server/lib/request/request-video-event-scheduler.ts
@@ -1,16 +1,18 @@
1'use strict'
2
3const BaseRequestScheduler = require('./base-request-scheduler')
4const constants = require('../../initializers/constants')
5const db = require('../../initializers/database') 1const db = require('../../initializers/database')
6 2import { BaseRequestScheduler } from './base-request-scheduler'
7module.exports = class RequestVideoEventScheduler extends BaseRequestScheduler { 3import {
4 REQUESTS_VIDEO_EVENT_LIMIT_PODS,
5 REQUESTS_VIDEO_EVENT_LIMIT_PER_POD,
6 REQUEST_VIDEO_EVENT_ENDPOINT
7} from '../../initializers'
8
9class RequestVideoEventScheduler extends BaseRequestScheduler {
8 constructor () { 10 constructor () {
9 super() 11 super()
10 12
11 // We limit the size of the requests 13 // We limit the size of the requests
12 this.limitPods = constants.REQUESTS_VIDEO_EVENT_LIMIT_PODS 14 this.limitPods = REQUESTS_VIDEO_EVENT_LIMIT_PODS
13 this.limitPerPod = constants.REQUESTS_VIDEO_EVENT_LIMIT_PER_POD 15 this.limitPerPod = REQUESTS_VIDEO_EVENT_LIMIT_PER_POD
14 16
15 this.description = 'video event requests' 17 this.description = 'video event requests'
16 } 18 }
@@ -45,7 +47,7 @@ module.exports = class RequestVideoEventScheduler extends BaseRequestScheduler {
45 if (!requestsToMakeGrouped[toPodId]) { 47 if (!requestsToMakeGrouped[toPodId]) {
46 requestsToMakeGrouped[toPodId] = { 48 requestsToMakeGrouped[toPodId] = {
47 toPod: eventToProcess.pod, 49 toPod: eventToProcess.pod,
48 endpoint: constants.REQUEST_VIDEO_EVENT_ENDPOINT, 50 endpoint: REQUEST_VIDEO_EVENT_ENDPOINT,
49 ids: [], // request ids, to delete them from the DB in the future 51 ids: [], // request ids, to delete them from the DB in the future
50 datas: [] // requests data 52 datas: [] // requests data
51 } 53 }
@@ -94,7 +96,7 @@ module.exports = class RequestVideoEventScheduler extends BaseRequestScheduler {
94 96
95 if (count === undefined) count = 1 97 if (count === undefined) count = 1
96 98
97 const dbRequestOptions = {} 99 const dbRequestOptions: { transaction?: any } = {}
98 if (transaction) dbRequestOptions.transaction = transaction 100 if (transaction) dbRequestOptions.transaction = transaction
99 101
100 const createQuery = { 102 const createQuery = {
@@ -106,3 +108,9 @@ module.exports = class RequestVideoEventScheduler extends BaseRequestScheduler {
106 return db.RequestVideoEvent.create(createQuery, dbRequestOptions).asCallback(callback) 108 return db.RequestVideoEvent.create(createQuery, dbRequestOptions).asCallback(callback)
107 } 109 }
108} 110}
111
112// ---------------------------------------------------------------------------
113
114export {
115 RequestVideoEventScheduler
116}
diff --git a/server/lib/request/request-video-qadu-scheduler.js b/server/lib/request/request-video-qadu-scheduler.ts
index 17402b556..d81822723 100644
--- a/server/lib/request/request-video-qadu-scheduler.js
+++ b/server/lib/request/request-video-qadu-scheduler.ts
@@ -1,17 +1,20 @@
1'use strict'
2
3const BaseRequestScheduler = require('./base-request-scheduler')
4const constants = require('../../initializers/constants')
5const db = require('../../initializers/database') 1const db = require('../../initializers/database')
6const logger = require('../../helpers/logger') 2import { BaseRequestScheduler } from './base-request-scheduler'
7 3import { logger } from '../../helpers'
8module.exports = class RequestVideoQaduScheduler extends BaseRequestScheduler { 4import {
5 REQUESTS_VIDEO_QADU_LIMIT_PODS,
6 REQUESTS_VIDEO_QADU_LIMIT_PER_POD,
7 REQUEST_VIDEO_QADU_ENDPOINT,
8 REQUEST_VIDEO_QADU_TYPES
9} from '../../initializers'
10
11class RequestVideoQaduScheduler extends BaseRequestScheduler {
9 constructor () { 12 constructor () {
10 super() 13 super()
11 14
12 // We limit the size of the requests 15 // We limit the size of the requests
13 this.limitPods = constants.REQUESTS_VIDEO_QADU_LIMIT_PODS 16 this.limitPods = REQUESTS_VIDEO_QADU_LIMIT_PODS
14 this.limitPerPod = constants.REQUESTS_VIDEO_QADU_LIMIT_PER_POD 17 this.limitPerPod = REQUESTS_VIDEO_QADU_LIMIT_PER_POD
15 18
16 this.description = 'video QADU requests' 19 this.description = 'video QADU requests'
17 } 20 }
@@ -37,7 +40,7 @@ module.exports = class RequestVideoQaduScheduler extends BaseRequestScheduler {
37 if (!requestsToMakeGrouped[hashKey]) { 40 if (!requestsToMakeGrouped[hashKey]) {
38 requestsToMakeGrouped[hashKey] = { 41 requestsToMakeGrouped[hashKey] = {
39 toPod: pod, 42 toPod: pod,
40 endpoint: constants.REQUEST_VIDEO_QADU_ENDPOINT, 43 endpoint: REQUEST_VIDEO_QADU_ENDPOINT,
41 ids: [], // request ids, to delete them from the DB in the future 44 ids: [], // request ids, to delete them from the DB in the future
42 datas: [], // requests data 45 datas: [], // requests data
43 videos: {} 46 videos: {}
@@ -49,15 +52,15 @@ module.exports = class RequestVideoQaduScheduler extends BaseRequestScheduler {
49 if (!videoData) videoData = {} 52 if (!videoData) videoData = {}
50 53
51 switch (request.type) { 54 switch (request.type) {
52 case constants.REQUEST_VIDEO_QADU_TYPES.LIKES: 55 case REQUEST_VIDEO_QADU_TYPES.LIKES:
53 videoData.likes = video.likes 56 videoData.likes = video.likes
54 break 57 break
55 58
56 case constants.REQUEST_VIDEO_QADU_TYPES.DISLIKES: 59 case REQUEST_VIDEO_QADU_TYPES.DISLIKES:
57 videoData.dislikes = video.dislikes 60 videoData.dislikes = video.dislikes
58 break 61 break
59 62
60 case constants.REQUEST_VIDEO_QADU_TYPES.VIEWS: 63 case REQUEST_VIDEO_QADU_TYPES.VIEWS:
61 videoData.views = video.views 64 videoData.views = video.views
62 break 65 break
63 66
@@ -99,7 +102,7 @@ module.exports = class RequestVideoQaduScheduler extends BaseRequestScheduler {
99 const videoId = options.videoId 102 const videoId = options.videoId
100 const transaction = options.transaction 103 const transaction = options.transaction
101 104
102 const dbRequestOptions = {} 105 const dbRequestOptions: { transaction?: any } = {}
103 if (transaction) dbRequestOptions.transaction = transaction 106 if (transaction) dbRequestOptions.transaction = transaction
104 107
105 // Send the update to all our friends 108 // Send the update to all our friends
@@ -115,3 +118,9 @@ module.exports = class RequestVideoQaduScheduler extends BaseRequestScheduler {
115 }) 118 })
116 } 119 }
117} 120}
121
122// ---------------------------------------------------------------------------
123
124export {
125 RequestVideoQaduScheduler
126}
diff --git a/server/middlewares/admin.js b/server/middlewares/admin.ts
index 3288f4c6b..ebafa36a4 100644
--- a/server/middlewares/admin.js
+++ b/server/middlewares/admin.ts
@@ -1,11 +1,5 @@
1'use strict'
2
3const logger = require('../helpers/logger') 1const logger = require('../helpers/logger')
4 2
5const adminMiddleware = {
6 ensureIsAdmin
7}
8
9function ensureIsAdmin (req, res, next) { 3function ensureIsAdmin (req, res, next) {
10 const user = res.locals.oauth.token.user 4 const user = res.locals.oauth.token.user
11 if (user.isAdmin() === false) { 5 if (user.isAdmin() === false) {
@@ -18,4 +12,6 @@ function ensureIsAdmin (req, res, next) {
18 12
19// --------------------------------------------------------------------------- 13// ---------------------------------------------------------------------------
20 14
21module.exports = adminMiddleware 15export {
16 ensureIsAdmin
17}
diff --git a/server/middlewares/index.js b/server/middlewares/index.js
deleted file mode 100644
index 3f253e31b..000000000
--- a/server/middlewares/index.js
+++ /dev/null
@@ -1,25 +0,0 @@
1'use strict'
2
3const adminMiddleware = require('./admin')
4const oauthMiddleware = require('./oauth')
5const paginationMiddleware = require('./pagination')
6const podsMiddleware = require('./pods')
7const validatorsMiddleware = require('./validators')
8const searchMiddleware = require('./search')
9const sortMiddleware = require('./sort')
10const secureMiddleware = require('./secure')
11
12const middlewares = {
13 admin: adminMiddleware,
14 oauth: oauthMiddleware,
15 pagination: paginationMiddleware,
16 pods: podsMiddleware,
17 search: searchMiddleware,
18 secure: secureMiddleware,
19 sort: sortMiddleware,
20 validators: validatorsMiddleware
21}
22
23// ---------------------------------------------------------------------------
24
25module.exports = middlewares
diff --git a/server/middlewares/index.ts b/server/middlewares/index.ts
new file mode 100644
index 000000000..2c1c5fa53
--- /dev/null
+++ b/server/middlewares/index.ts
@@ -0,0 +1,8 @@
1export * from './validators';
2export * from './admin';
3export * from './oauth';
4export * from './pagination';
5export * from './pods';
6export * from './search';
7export * from './secure';
8export * from './sort';
diff --git a/server/middlewares/oauth.js b/server/middlewares/oauth.ts
index 3a02b9b48..31ae1e000 100644
--- a/server/middlewares/oauth.js
+++ b/server/middlewares/oauth.ts
@@ -1,6 +1,4 @@
1'use strict' 1import OAuthServer = require('express-oauth-server')
2
3const OAuthServer = require('express-oauth-server')
4 2
5const constants = require('../initializers/constants') 3const constants = require('../initializers/constants')
6const logger = require('../helpers/logger') 4const logger = require('../helpers/logger')
@@ -11,11 +9,6 @@ const oAuthServer = new OAuthServer({
11 model: require('../lib/oauth-model') 9 model: require('../lib/oauth-model')
12}) 10})
13 11
14const oAuth = {
15 authenticate,
16 token
17}
18
19function authenticate (req, res, next) { 12function authenticate (req, res, next) {
20 oAuthServer.authenticate()(req, res, function (err) { 13 oAuthServer.authenticate()(req, res, function (err) {
21 if (err) { 14 if (err) {
@@ -35,4 +28,7 @@ function token (req, res, next) {
35 28
36// --------------------------------------------------------------------------- 29// ---------------------------------------------------------------------------
37 30
38module.exports = oAuth 31export {
32 authenticate,
33 token
34}
diff --git a/server/middlewares/pagination.js b/server/middlewares/pagination.ts
index a90f60aab..8fe9f9082 100644
--- a/server/middlewares/pagination.js
+++ b/server/middlewares/pagination.ts
@@ -1,14 +1,9 @@
1'use strict'
2
3const constants = require('../initializers/constants') 1const constants = require('../initializers/constants')
4 2
5const paginationMiddleware = {
6 setPagination
7}
8
9function setPagination (req, res, next) { 3function setPagination (req, res, next) {
10 if (!req.query.start) req.query.start = 0 4 if (!req.query.start) req.query.start = 0
11 else req.query.start = parseInt(req.query.start, 10) 5 else req.query.start = parseInt(req.query.start, 10)
6
12 if (!req.query.count) req.query.count = constants.PAGINATION_COUNT_DEFAULT 7 if (!req.query.count) req.query.count = constants.PAGINATION_COUNT_DEFAULT
13 else req.query.count = parseInt(req.query.count, 10) 8 else req.query.count = parseInt(req.query.count, 10)
14 9
@@ -17,4 +12,6 @@ function setPagination (req, res, next) {
17 12
18// --------------------------------------------------------------------------- 13// ---------------------------------------------------------------------------
19 14
20module.exports = paginationMiddleware 15export {
16 setPagination
17}
diff --git a/server/middlewares/pods.js b/server/middlewares/pods.ts
index 2647f9ff0..e405f265e 100644
--- a/server/middlewares/pods.js
+++ b/server/middlewares/pods.ts
@@ -2,11 +2,6 @@
2 2
3const constants = require('../initializers/constants') 3const constants = require('../initializers/constants')
4 4
5const podsMiddleware = {
6 setBodyHostsPort,
7 setBodyHostPort
8}
9
10function setBodyHostsPort (req, res, next) { 5function setBodyHostsPort (req, res, next) {
11 if (!req.body.hosts) return next() 6 if (!req.body.hosts) return next()
12 7
@@ -41,7 +36,10 @@ function setBodyHostPort (req, res, next) {
41 36
42// --------------------------------------------------------------------------- 37// ---------------------------------------------------------------------------
43 38
44module.exports = podsMiddleware 39export {
40 setBodyHostsPort,
41 setBodyHostPort
42}
45 43
46// --------------------------------------------------------------------------- 44// ---------------------------------------------------------------------------
47 45
diff --git a/server/middlewares/search.js b/server/middlewares/search.ts
index bb88faf54..05a2e7442 100644
--- a/server/middlewares/search.js
+++ b/server/middlewares/search.ts
@@ -1,9 +1,3 @@
1'use strict'
2
3const searchMiddleware = {
4 setVideosSearch
5}
6
7function setVideosSearch (req, res, next) { 1function setVideosSearch (req, res, next) {
8 if (!req.query.field) req.query.field = 'name' 2 if (!req.query.field) req.query.field = 'name'
9 3
@@ -12,4 +6,6 @@ function setVideosSearch (req, res, next) {
12 6
13// --------------------------------------------------------------------------- 7// ---------------------------------------------------------------------------
14 8
15module.exports = searchMiddleware 9export {
10 setVideosSearch
11}
diff --git a/server/middlewares/secure.js b/server/middlewares/secure.ts
index 7c5c72508..ee8545028 100644
--- a/server/middlewares/secure.js
+++ b/server/middlewares/secure.ts
@@ -1,13 +1,7 @@
1'use strict'
2
3const db = require('../initializers/database') 1const db = require('../initializers/database')
4const logger = require('../helpers/logger') 2const logger = require('../helpers/logger')
5const peertubeCrypto = require('../helpers/peertube-crypto') 3const peertubeCrypto = require('../helpers/peertube-crypto')
6 4
7const secureMiddleware = {
8 checkSignature
9}
10
11function checkSignature (req, res, next) { 5function checkSignature (req, res, next) {
12 const host = req.body.signature.host 6 const host = req.body.signature.host
13 db.Pod.loadByHost(host, function (err, pod) { 7 db.Pod.loadByHost(host, function (err, pod) {
@@ -49,4 +43,6 @@ function checkSignature (req, res, next) {
49 43
50// --------------------------------------------------------------------------- 44// ---------------------------------------------------------------------------
51 45
52module.exports = secureMiddleware 46export {
47 checkSignature
48}
diff --git a/server/middlewares/sort.js b/server/middlewares/sort.ts
index 39e167265..ab9ccf524 100644
--- a/server/middlewares/sort.js
+++ b/server/middlewares/sort.ts
@@ -1,11 +1,3 @@
1'use strict'
2
3const sortMiddleware = {
4 setUsersSort,
5 setVideoAbusesSort,
6 setVideosSort
7}
8
9function setUsersSort (req, res, next) { 1function setUsersSort (req, res, next) {
10 if (!req.query.sort) req.query.sort = '-createdAt' 2 if (!req.query.sort) req.query.sort = '-createdAt'
11 3
@@ -26,4 +18,8 @@ function setVideosSort (req, res, next) {
26 18
27// --------------------------------------------------------------------------- 19// ---------------------------------------------------------------------------
28 20
29module.exports = sortMiddleware 21export {
22 setUsersSort,
23 setVideoAbusesSort,
24 setVideosSort
25}
diff --git a/server/middlewares/validators/index.js b/server/middlewares/validators/index.js
deleted file mode 100644
index 6c3a9c2b4..000000000
--- a/server/middlewares/validators/index.js
+++ /dev/null
@@ -1,21 +0,0 @@
1'use strict'
2
3const paginationValidators = require('./pagination')
4const podsValidators = require('./pods')
5const remoteValidators = require('./remote')
6const sortValidators = require('./sort')
7const usersValidators = require('./users')
8const videosValidators = require('./videos')
9
10const validators = {
11 pagination: paginationValidators,
12 pods: podsValidators,
13 remote: remoteValidators,
14 sort: sortValidators,
15 users: usersValidators,
16 videos: videosValidators
17}
18
19// ---------------------------------------------------------------------------
20
21module.exports = validators
diff --git a/server/middlewares/validators/index.ts b/server/middlewares/validators/index.ts
new file mode 100644
index 000000000..42ba465ec
--- /dev/null
+++ b/server/middlewares/validators/index.ts
@@ -0,0 +1,6 @@
1export * from './remote'
2export * from './pagination'
3export * from './pods'
4export * from './sort'
5export * from './users'
6export * from './videos'
diff --git a/server/middlewares/validators/pagination.js b/server/middlewares/validators/pagination.ts
index 16682696e..de719c05b 100644
--- a/server/middlewares/validators/pagination.js
+++ b/server/middlewares/validators/pagination.ts
@@ -1,13 +1,7 @@
1'use strict' 1import { checkErrors } from './utils'
2import { logger } from '../../helpers'
2 3
3const checkErrors = require('./utils').checkErrors 4function paginationValidator (req, res, next) {
4const logger = require('../../helpers/logger')
5
6const validatorsPagination = {
7 pagination
8}
9
10function pagination (req, res, next) {
11 req.checkQuery('start', 'Should have a number start').optional().isInt() 5 req.checkQuery('start', 'Should have a number start').optional().isInt()
12 req.checkQuery('count', 'Should have a number count').optional().isInt() 6 req.checkQuery('count', 'Should have a number count').optional().isInt()
13 7
@@ -18,4 +12,6 @@ function pagination (req, res, next) {
18 12
19// --------------------------------------------------------------------------- 13// ---------------------------------------------------------------------------
20 14
21module.exports = validatorsPagination 15export {
16 paginationValidator
17}
diff --git a/server/middlewares/validators/pods.js b/server/middlewares/validators/pods.ts
index 0bf4b1844..fbfd268d0 100644
--- a/server/middlewares/validators/pods.js
+++ b/server/middlewares/validators/pods.ts
@@ -1,20 +1,13 @@
1'use strict'
2
3const checkErrors = require('./utils').checkErrors
4const constants = require('../../initializers/constants')
5const db = require('../../initializers/database') 1const db = require('../../initializers/database')
6const friends = require('../../lib/friends') 2import { checkErrors } from './utils'
7const logger = require('../../helpers/logger') 3import { logger } from '../../helpers'
8const utils = require('../../helpers/utils') 4import { CONFIG } from '../../initializers'
9 5import { hasFriends } from '../../lib'
10const validatorsPod = { 6import { isTestInstance } from '../../helpers'
11 makeFriends,
12 podsAdd
13}
14 7
15function makeFriends (req, res, next) { 8function makeFriendsValidator (req, res, next) {
16 // Force https if the administrator wants to make friends 9 // Force https if the administrator wants to make friends
17 if (utils.isTestInstance() === false && constants.CONFIG.WEBSERVER.SCHEME === 'http') { 10 if (isTestInstance() === false && CONFIG.WEBSERVER.SCHEME === 'http') {
18 return res.status(400).send('Cannot make friends with a non HTTPS webserver.') 11 return res.status(400).send('Cannot make friends with a non HTTPS webserver.')
19 } 12 }
20 13
@@ -23,13 +16,13 @@ function makeFriends (req, res, next) {
23 logger.debug('Checking makeFriends parameters', { parameters: req.body }) 16 logger.debug('Checking makeFriends parameters', { parameters: req.body })
24 17
25 checkErrors(req, res, function () { 18 checkErrors(req, res, function () {
26 friends.hasFriends(function (err, hasFriends) { 19 hasFriends(function (err, heHasFriends) {
27 if (err) { 20 if (err) {
28 logger.error('Cannot know if we have friends.', { error: err }) 21 logger.error('Cannot know if we have friends.', { error: err })
29 res.sendStatus(500) 22 res.sendStatus(500)
30 } 23 }
31 24
32 if (hasFriends === true) { 25 if (heHasFriends === true) {
33 // We need to quit our friends before make new ones 26 // We need to quit our friends before make new ones
34 return res.sendStatus(409) 27 return res.sendStatus(409)
35 } 28 }
@@ -39,7 +32,7 @@ function makeFriends (req, res, next) {
39 }) 32 })
40} 33}
41 34
42function podsAdd (req, res, next) { 35function podsAddValidator (req, res, next) {
43 req.checkBody('host', 'Should have a host').isHostValid() 36 req.checkBody('host', 'Should have a host').isHostValid()
44 req.checkBody('email', 'Should have an email').isEmail() 37 req.checkBody('email', 'Should have an email').isEmail()
45 req.checkBody('publicKey', 'Should have a public key').notEmpty() 38 req.checkBody('publicKey', 'Should have a public key').notEmpty()
@@ -64,4 +57,7 @@ function podsAdd (req, res, next) {
64 57
65// --------------------------------------------------------------------------- 58// ---------------------------------------------------------------------------
66 59
67module.exports = validatorsPod 60export {
61 makeFriendsValidator,
62 podsAddValidator
63}
diff --git a/server/middlewares/validators/remote/index.js b/server/middlewares/validators/remote/index.js
deleted file mode 100644
index 022a2fe50..000000000
--- a/server/middlewares/validators/remote/index.js
+++ /dev/null
@@ -1,13 +0,0 @@
1'use strict'
2
3const remoteSignatureValidators = require('./signature')
4const remoteVideosValidators = require('./videos')
5
6const validators = {
7 signature: remoteSignatureValidators,
8 videos: remoteVideosValidators
9}
10
11// ---------------------------------------------------------------------------
12
13module.exports = validators
diff --git a/server/middlewares/validators/remote/index.ts b/server/middlewares/validators/remote/index.ts
new file mode 100644
index 000000000..d0d7740b1
--- /dev/null
+++ b/server/middlewares/validators/remote/index.ts
@@ -0,0 +1,2 @@
1export * from './signature'
2export * from './videos'
diff --git a/server/middlewares/validators/remote/signature.js b/server/middlewares/validators/remote/signature.ts
index 002232c05..6e3ebe7db 100644
--- a/server/middlewares/validators/remote/signature.js
+++ b/server/middlewares/validators/remote/signature.ts
@@ -1,13 +1,7 @@
1'use strict' 1import { logger } from '../../../helpers'
2import { checkErrors } from '../utils'
2 3
3const checkErrors = require('../utils').checkErrors 4function signatureValidator (req, res, next) {
4const logger = require('../../../helpers/logger')
5
6const validatorsRemoteSignature = {
7 signature
8}
9
10function signature (req, res, next) {
11 req.checkBody('signature.host', 'Should have a signature host').isURL() 5 req.checkBody('signature.host', 'Should have a signature host').isURL()
12 req.checkBody('signature.signature', 'Should have a signature').notEmpty() 6 req.checkBody('signature.signature', 'Should have a signature').notEmpty()
13 7
@@ -18,4 +12,6 @@ function signature (req, res, next) {
18 12
19// --------------------------------------------------------------------------- 13// ---------------------------------------------------------------------------
20 14
21module.exports = validatorsRemoteSignature 15export {
16 signatureValidator
17}
diff --git a/server/middlewares/validators/remote/videos.js b/server/middlewares/validators/remote/videos.ts
index f2c6cba5e..3380c29e2 100644
--- a/server/middlewares/validators/remote/videos.js
+++ b/server/middlewares/validators/remote/videos.ts
@@ -1,15 +1,7 @@
1'use strict' 1import { logger } from '../../../helpers'
2import { checkErrors } from '../utils'
2 3
3const checkErrors = require('../utils').checkErrors 4function remoteVideosValidator (req, res, next) {
4const logger = require('../../../helpers/logger')
5
6const validatorsRemoteVideos = {
7 remoteVideos,
8 remoteQaduVideos,
9 remoteEventsVideos
10}
11
12function remoteVideos (req, res, next) {
13 req.checkBody('data').isEachRemoteRequestVideosValid() 5 req.checkBody('data').isEachRemoteRequestVideosValid()
14 6
15 logger.debug('Checking remoteVideos parameters', { parameters: req.body }) 7 logger.debug('Checking remoteVideos parameters', { parameters: req.body })
@@ -17,7 +9,7 @@ function remoteVideos (req, res, next) {
17 checkErrors(req, res, next) 9 checkErrors(req, res, next)
18} 10}
19 11
20function remoteQaduVideos (req, res, next) { 12function remoteQaduVideosValidator (req, res, next) {
21 req.checkBody('data').isEachRemoteRequestVideosQaduValid() 13 req.checkBody('data').isEachRemoteRequestVideosQaduValid()
22 14
23 logger.debug('Checking remoteQaduVideos parameters', { parameters: req.body }) 15 logger.debug('Checking remoteQaduVideos parameters', { parameters: req.body })
@@ -25,13 +17,18 @@ function remoteQaduVideos (req, res, next) {
25 checkErrors(req, res, next) 17 checkErrors(req, res, next)
26} 18}
27 19
28function remoteEventsVideos (req, res, next) { 20function remoteEventsVideosValidator (req, res, next) {
29 req.checkBody('data').isEachRemoteRequestVideosEventsValid() 21 req.checkBody('data').isEachRemoteRequestVideosEventsValid()
30 22
31 logger.debug('Checking remoteEventsVideos parameters', { parameters: req.body }) 23 logger.debug('Checking remoteEventsVideos parameters', { parameters: req.body })
32 24
33 checkErrors(req, res, next) 25 checkErrors(req, res, next)
34} 26}
27
35// --------------------------------------------------------------------------- 28// ---------------------------------------------------------------------------
36 29
37module.exports = validatorsRemoteVideos 30export {
31 remoteVideosValidator,
32 remoteQaduVideosValidator,
33 remoteEventsVideosValidator
34}
diff --git a/server/middlewares/validators/sort.js b/server/middlewares/validators/sort.ts
index 017d266e6..ebc7333c7 100644
--- a/server/middlewares/validators/sort.js
+++ b/server/middlewares/validators/sort.ts
@@ -1,35 +1,31 @@
1'use strict' 1import { checkErrors } from './utils'
2 2import { logger } from '../../helpers'
3const checkErrors = require('./utils').checkErrors 3import { SORTABLE_COLUMNS } from '../../initializers'
4const constants = require('../../initializers/constants')
5const logger = require('../../helpers/logger')
6
7const validatorsSort = {
8 usersSort,
9 videoAbusesSort,
10 videosSort
11}
12 4
13// Initialize constants here for better performances 5// Initialize constants here for better performances
14const SORTABLE_USERS_COLUMNS = createSortableColumns(constants.SORTABLE_COLUMNS.USERS) 6const SORTABLE_USERS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.USERS)
15const SORTABLE_VIDEO_ABUSES_COLUMNS = createSortableColumns(constants.SORTABLE_COLUMNS.VIDEO_ABUSES) 7const SORTABLE_VIDEO_ABUSES_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEO_ABUSES)
16const SORTABLE_VIDEOS_COLUMNS = createSortableColumns(constants.SORTABLE_COLUMNS.VIDEOS) 8const SORTABLE_VIDEOS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEOS)
17 9
18function usersSort (req, res, next) { 10function usersSortValidator (req, res, next) {
19 checkSort(req, res, next, SORTABLE_USERS_COLUMNS) 11 checkSort(req, res, next, SORTABLE_USERS_COLUMNS)
20} 12}
21 13
22function videoAbusesSort (req, res, next) { 14function videoAbusesSortValidator (req, res, next) {
23 checkSort(req, res, next, SORTABLE_VIDEO_ABUSES_COLUMNS) 15 checkSort(req, res, next, SORTABLE_VIDEO_ABUSES_COLUMNS)
24} 16}
25 17
26function videosSort (req, res, next) { 18function videosSortValidator (req, res, next) {
27 checkSort(req, res, next, SORTABLE_VIDEOS_COLUMNS) 19 checkSort(req, res, next, SORTABLE_VIDEOS_COLUMNS)
28} 20}
29 21
30// --------------------------------------------------------------------------- 22// ---------------------------------------------------------------------------
31 23
32module.exports = validatorsSort 24export {
25 usersSortValidator,
26 videoAbusesSortValidator,
27 videosSortValidator
28}
33 29
34// --------------------------------------------------------------------------- 30// ---------------------------------------------------------------------------
35 31
diff --git a/server/middlewares/validators/users.js b/server/middlewares/validators/users.ts
index 1e7a64793..a9149fe1b 100644
--- a/server/middlewares/validators/users.js
+++ b/server/middlewares/validators/users.ts
@@ -1,17 +1,8 @@
1'use strict'
2
3const checkErrors = require('./utils').checkErrors
4const db = require('../../initializers/database') 1const db = require('../../initializers/database')
5const logger = require('../../helpers/logger') 2import { checkErrors } from './utils'
6 3import { logger } from '../../helpers'
7const validatorsUsers = {
8 usersAdd,
9 usersRemove,
10 usersUpdate,
11 usersVideoRating
12}
13 4
14function usersAdd (req, res, next) { 5function usersAddValidator (req, res, next) {
15 req.checkBody('username', 'Should have a valid username').isUserUsernameValid() 6 req.checkBody('username', 'Should have a valid username').isUserUsernameValid()
16 req.checkBody('password', 'Should have a valid password').isUserPasswordValid() 7 req.checkBody('password', 'Should have a valid password').isUserPasswordValid()
17 req.checkBody('email', 'Should have a valid email').isEmail() 8 req.checkBody('email', 'Should have a valid email').isEmail()
@@ -32,7 +23,7 @@ function usersAdd (req, res, next) {
32 }) 23 })
33} 24}
34 25
35function usersRemove (req, res, next) { 26function usersRemoveValidator (req, res, next) {
36 req.checkParams('id', 'Should have a valid id').notEmpty().isInt() 27 req.checkParams('id', 'Should have a valid id').notEmpty().isInt()
37 28
38 logger.debug('Checking usersRemove parameters', { parameters: req.params }) 29 logger.debug('Checking usersRemove parameters', { parameters: req.params })
@@ -53,7 +44,7 @@ function usersRemove (req, res, next) {
53 }) 44 })
54} 45}
55 46
56function usersUpdate (req, res, next) { 47function usersUpdateValidator (req, res, next) {
57 req.checkParams('id', 'Should have a valid id').notEmpty().isInt() 48 req.checkParams('id', 'Should have a valid id').notEmpty().isInt()
58 // Add old password verification 49 // Add old password verification
59 req.checkBody('password', 'Should have a valid password').optional().isUserPasswordValid() 50 req.checkBody('password', 'Should have a valid password').optional().isUserPasswordValid()
@@ -64,7 +55,7 @@ function usersUpdate (req, res, next) {
64 checkErrors(req, res, next) 55 checkErrors(req, res, next)
65} 56}
66 57
67function usersVideoRating (req, res, next) { 58function usersVideoRatingValidator (req, res, next) {
68 req.checkParams('videoId', 'Should have a valid video id').notEmpty().isUUID(4) 59 req.checkParams('videoId', 'Should have a valid video id').notEmpty().isUUID(4)
69 60
70 logger.debug('Checking usersVideoRating parameters', { parameters: req.params }) 61 logger.debug('Checking usersVideoRating parameters', { parameters: req.params })
@@ -85,4 +76,9 @@ function usersVideoRating (req, res, next) {
85 76
86// --------------------------------------------------------------------------- 77// ---------------------------------------------------------------------------
87 78
88module.exports = validatorsUsers 79export {
80 usersAddValidator,
81 usersRemoveValidator,
82 usersUpdateValidator,
83 usersVideoRatingValidator
84}
diff --git a/server/middlewares/validators/utils.js b/server/middlewares/validators/utils.ts
index 3741b84c6..710e65529 100644
--- a/server/middlewares/validators/utils.js
+++ b/server/middlewares/validators/utils.ts
@@ -1,20 +1,14 @@
1'use strict' 1import { inspect } from 'util'
2 2
3const util = require('util') 3import { logger } from '../../helpers'
4 4
5const logger = require('../../helpers/logger') 5function checkErrors (req, res, next, statusCode?) {
6
7const validatorsUtils = {
8 checkErrors
9}
10
11function checkErrors (req, res, next, statusCode) {
12 if (statusCode === undefined) statusCode = 400 6 if (statusCode === undefined) statusCode = 400
13 const errors = req.validationErrors() 7 const errors = req.validationErrors()
14 8
15 if (errors) { 9 if (errors) {
16 logger.warn('Incorrect request parameters', { path: req.originalUrl, err: errors }) 10 logger.warn('Incorrect request parameters', { path: req.originalUrl, err: errors })
17 return res.status(statusCode).send('There have been validation errors: ' + util.inspect(errors)) 11 return res.status(statusCode).send('There have been validation errors: ' + inspect(errors))
18 } 12 }
19 13
20 return next() 14 return next()
@@ -22,4 +16,6 @@ function checkErrors (req, res, next, statusCode) {
22 16
23// --------------------------------------------------------------------------- 17// ---------------------------------------------------------------------------
24 18
25module.exports = validatorsUtils 19export {
20 checkErrors
21}
diff --git a/server/middlewares/validators/videos.js b/server/middlewares/validators/videos.ts
index f18ca1597..5a49cf73c 100644
--- a/server/middlewares/validators/videos.js
+++ b/server/middlewares/validators/videos.ts
@@ -1,26 +1,9 @@
1'use strict'
2
3const checkErrors = require('./utils').checkErrors
4const constants = require('../../initializers/constants')
5const customVideosValidators = require('../../helpers/custom-validators').videos
6const db = require('../../initializers/database') 1const db = require('../../initializers/database')
7const logger = require('../../helpers/logger') 2import { checkErrors } from './utils'
8 3import { CONSTRAINTS_FIELDS, SEARCHABLE_COLUMNS } from '../../initializers'
9const validatorsVideos = { 4import { logger, isVideoDurationValid } from '../../helpers'
10 videosAdd,
11 videosUpdate,
12 videosGet,
13 videosRemove,
14 videosSearch,
15
16 videoAbuseReport,
17
18 videoRate,
19
20 videosBlacklist
21}
22 5
23function videosAdd (req, res, next) { 6function videosAddValidator (req, res, next) {
24 req.checkBody('videofile', 'Should have a valid file').isVideoFile(req.files) 7 req.checkBody('videofile', 'Should have a valid file').isVideoFile(req.files)
25 req.checkBody('name', 'Should have a valid name').isVideoNameValid() 8 req.checkBody('name', 'Should have a valid name').isVideoNameValid()
26 req.checkBody('category', 'Should have a valid category').isVideoCategoryValid() 9 req.checkBody('category', 'Should have a valid category').isVideoCategoryValid()
@@ -40,8 +23,8 @@ function videosAdd (req, res, next) {
40 return res.status(400).send('Cannot retrieve metadata of the file.') 23 return res.status(400).send('Cannot retrieve metadata of the file.')
41 } 24 }
42 25
43 if (!customVideosValidators.isVideoDurationValid(duration)) { 26 if (!isVideoDurationValid(duration)) {
44 return res.status(400).send('Duration of the video file is too big (max: ' + constants.CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).') 27 return res.status(400).send('Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).')
45 } 28 }
46 29
47 videoFile.duration = duration 30 videoFile.duration = duration
@@ -50,7 +33,7 @@ function videosAdd (req, res, next) {
50 }) 33 })
51} 34}
52 35
53function videosUpdate (req, res, next) { 36function videosUpdateValidator (req, res, next) {
54 req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4) 37 req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
55 req.checkBody('name', 'Should have a valid name').optional().isVideoNameValid() 38 req.checkBody('name', 'Should have a valid name').optional().isVideoNameValid()
56 req.checkBody('category', 'Should have a valid category').optional().isVideoCategoryValid() 39 req.checkBody('category', 'Should have a valid category').optional().isVideoCategoryValid()
@@ -78,7 +61,7 @@ function videosUpdate (req, res, next) {
78 }) 61 })
79} 62}
80 63
81function videosGet (req, res, next) { 64function videosGetValidator (req, res, next) {
82 req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4) 65 req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
83 66
84 logger.debug('Checking videosGet parameters', { parameters: req.params }) 67 logger.debug('Checking videosGet parameters', { parameters: req.params })
@@ -88,7 +71,7 @@ function videosGet (req, res, next) {
88 }) 71 })
89} 72}
90 73
91function videosRemove (req, res, next) { 74function videosRemoveValidator (req, res, next) {
92 req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4) 75 req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
93 76
94 logger.debug('Checking videosRemove parameters', { parameters: req.params }) 77 logger.debug('Checking videosRemove parameters', { parameters: req.params })
@@ -105,8 +88,8 @@ function videosRemove (req, res, next) {
105 }) 88 })
106} 89}
107 90
108function videosSearch (req, res, next) { 91function videosSearchValidator (req, res, next) {
109 const searchableColumns = constants.SEARCHABLE_COLUMNS.VIDEOS 92 const searchableColumns = SEARCHABLE_COLUMNS.VIDEOS
110 req.checkParams('value', 'Should have a valid search').notEmpty() 93 req.checkParams('value', 'Should have a valid search').notEmpty()
111 req.checkQuery('field', 'Should have correct searchable column').optional().isIn(searchableColumns) 94 req.checkQuery('field', 'Should have correct searchable column').optional().isIn(searchableColumns)
112 95
@@ -115,7 +98,7 @@ function videosSearch (req, res, next) {
115 checkErrors(req, res, next) 98 checkErrors(req, res, next)
116} 99}
117 100
118function videoAbuseReport (req, res, next) { 101function videoAbuseReportValidator (req, res, next) {
119 req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4) 102 req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
120 req.checkBody('reason', 'Should have a valid reason').isVideoAbuseReasonValid() 103 req.checkBody('reason', 'Should have a valid reason').isVideoAbuseReasonValid()
121 104
@@ -126,7 +109,7 @@ function videoAbuseReport (req, res, next) {
126 }) 109 })
127} 110}
128 111
129function videoRate (req, res, next) { 112function videoRateValidator (req, res, next) {
130 req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4) 113 req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
131 req.checkBody('rating', 'Should have a valid rate type').isVideoRatingTypeValid() 114 req.checkBody('rating', 'Should have a valid rate type').isVideoRatingTypeValid()
132 115
@@ -137,7 +120,7 @@ function videoRate (req, res, next) {
137 }) 120 })
138} 121}
139 122
140function videosBlacklist (req, res, next) { 123function videosBlacklistValidator (req, res, next) {
141 req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4) 124 req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
142 125
143 logger.debug('Checking videosBlacklist parameters', { parameters: req.params }) 126 logger.debug('Checking videosBlacklist parameters', { parameters: req.params })
@@ -151,7 +134,19 @@ function videosBlacklist (req, res, next) {
151 134
152// --------------------------------------------------------------------------- 135// ---------------------------------------------------------------------------
153 136
154module.exports = validatorsVideos 137export {
138 videosAddValidator,
139 videosUpdateValidator,
140 videosGetValidator,
141 videosRemoveValidator,
142 videosSearchValidator,
143
144 videoAbuseReportValidator,
145
146 videoRateValidator,
147
148 videosBlacklistValidator
149}
155 150
156// --------------------------------------------------------------------------- 151// ---------------------------------------------------------------------------
157 152
diff --git a/server/models/application.js b/server/models/application.ts
index 64e1a0540..38a57e327 100644
--- a/server/models/application.js
+++ b/server/models/application.ts
@@ -1,5 +1,3 @@
1'use strict'
2
3module.exports = function (sequelize, DataTypes) { 1module.exports = function (sequelize, DataTypes) {
4 const Application = sequelize.define('Application', 2 const Application = sequelize.define('Application',
5 { 3 {
@@ -38,7 +36,7 @@ function loadMigrationVersion (callback) {
38} 36}
39 37
40function updateMigrationVersion (newVersion, transaction, callback) { 38function updateMigrationVersion (newVersion, transaction, callback) {
41 const options = { 39 const options: { where?: any, transaction?: any } = {
42 where: {} 40 where: {}
43 } 41 }
44 42
diff --git a/server/models/author.js b/server/models/author.ts
index 34b013097..4a7396929 100644
--- a/server/models/author.js
+++ b/server/models/author.ts
@@ -1,6 +1,4 @@
1'use strict' 1import { isUserUsernameValid } from '../helpers'
2
3const customUsersValidators = require('../helpers/custom-validators').users
4 2
5module.exports = function (sequelize, DataTypes) { 3module.exports = function (sequelize, DataTypes) {
6 const Author = sequelize.define('Author', 4 const Author = sequelize.define('Author',
@@ -10,7 +8,7 @@ module.exports = function (sequelize, DataTypes) {
10 allowNull: false, 8 allowNull: false,
11 validate: { 9 validate: {
12 usernameValid: function (value) { 10 usernameValid: function (value) {
13 const res = customUsersValidators.isUserUsernameValid(value) 11 const res = isUserUsernameValid(value)
14 if (res === false) throw new Error('Username is not valid.') 12 if (res === false) throw new Error('Username is not valid.')
15 } 13 }
16 } 14 }
@@ -76,7 +74,7 @@ function findOrCreateAuthor (name, podId, userId, transaction, callback) {
76 userId 74 userId
77 } 75 }
78 76
79 const query = { 77 const query: any = {
80 where: author, 78 where: author,
81 defaults: author 79 defaults: author
82 } 80 }
diff --git a/server/models/job.js b/server/models/job.ts
index 949f88d44..6843e399b 100644
--- a/server/models/job.js
+++ b/server/models/job.ts
@@ -1,8 +1,6 @@
1'use strict' 1import { values } from 'lodash'
2 2
3const values = require('lodash/values') 3import { JOB_STATES } from '../initializers'
4
5const constants = require('../initializers/constants')
6 4
7// --------------------------------------------------------------------------- 5// ---------------------------------------------------------------------------
8 6
@@ -10,7 +8,7 @@ module.exports = function (sequelize, DataTypes) {
10 const Job = sequelize.define('Job', 8 const Job = sequelize.define('Job',
11 { 9 {
12 state: { 10 state: {
13 type: DataTypes.ENUM(values(constants.JOB_STATES)), 11 type: DataTypes.ENUM(values(JOB_STATES)),
14 allowNull: false 12 allowNull: false
15 }, 13 },
16 handlerName: { 14 handlerName: {
diff --git a/server/models/oauth-client.js b/server/models/oauth-client.ts
index 021a34007..3198a85ef 100644
--- a/server/models/oauth-client.js
+++ b/server/models/oauth-client.ts
@@ -1,5 +1,3 @@
1'use strict'
2
3module.exports = function (sequelize, DataTypes) { 1module.exports = function (sequelize, DataTypes) {
4 const OAuthClient = sequelize.define('OAuthClient', 2 const OAuthClient = sequelize.define('OAuthClient',
5 { 3 {
diff --git a/server/models/oauth-token.js b/server/models/oauth-token.ts
index 68e7c9ff7..74c9180eb 100644
--- a/server/models/oauth-token.js
+++ b/server/models/oauth-token.ts
@@ -1,6 +1,4 @@
1'use strict' 1import { logger } from '../helpers'
2
3const logger = require('../helpers/logger')
4 2
5// --------------------------------------------------------------------------- 3// ---------------------------------------------------------------------------
6 4
diff --git a/server/models/pod.js b/server/models/pod.ts
index 8e2d488e1..0e0262978 100644
--- a/server/models/pod.js
+++ b/server/models/pod.ts
@@ -1,12 +1,8 @@
1'use strict' 1import { each, waterfall } from 'async'
2import { map } from 'lodash'
2 3
3const each = require('async/each') 4import { FRIEND_SCORE, PODS_SCORE } from '../initializers'
4const map = require('lodash/map') 5import { logger, isHostValid } from '../helpers'
5const waterfall = require('async/waterfall')
6
7const constants = require('../initializers/constants')
8const logger = require('../helpers/logger')
9const customPodsValidators = require('../helpers/custom-validators').pods
10 6
11// --------------------------------------------------------------------------- 7// ---------------------------------------------------------------------------
12 8
@@ -18,7 +14,7 @@ module.exports = function (sequelize, DataTypes) {
18 allowNull: false, 14 allowNull: false,
19 validate: { 15 validate: {
20 isHost: function (value) { 16 isHost: function (value) {
21 const res = customPodsValidators.isHostValid(value) 17 const res = isHostValid(value)
22 if (res === false) throw new Error('Host not valid.') 18 if (res === false) throw new Error('Host not valid.')
23 } 19 }
24 } 20 }
@@ -29,11 +25,11 @@ module.exports = function (sequelize, DataTypes) {
29 }, 25 },
30 score: { 26 score: {
31 type: DataTypes.INTEGER, 27 type: DataTypes.INTEGER,
32 defaultValue: constants.FRIEND_SCORE.BASE, 28 defaultValue: FRIEND_SCORE.BASE,
33 allowNull: false, 29 allowNull: false,
34 validate: { 30 validate: {
35 isInt: true, 31 isInt: true,
36 max: constants.FRIEND_SCORE.MAX 32 max: FRIEND_SCORE.MAX
37 } 33 }
38 }, 34 },
39 email: { 35 email: {
@@ -106,7 +102,7 @@ function countAll (callback) {
106} 102}
107 103
108function incrementScores (ids, value, callback) { 104function incrementScores (ids, value, callback) {
109 if (!callback) callback = function () {} 105 if (!callback) callback = function () { /* empty */ }
110 106
111 const update = { 107 const update = {
112 score: this.sequelize.literal('score +' + value) 108 score: this.sequelize.literal('score +' + value)
@@ -135,7 +131,7 @@ function listAllIds (transaction, callback) {
135 transaction = null 131 transaction = null
136 } 132 }
137 133
138 const query = { 134 const query: any = {
139 attributes: [ 'id' ] 135 attributes: [ 'id' ]
140 } 136 }
141 137
@@ -223,13 +219,13 @@ function updatePodsScore (goodPods, badPods) {
223 logger.info('Updating %d good pods and %d bad pods scores.', goodPods.length, badPods.length) 219 logger.info('Updating %d good pods and %d bad pods scores.', goodPods.length, badPods.length)
224 220
225 if (goodPods.length !== 0) { 221 if (goodPods.length !== 0) {
226 this.incrementScores(goodPods, constants.PODS_SCORE.BONUS, function (err) { 222 this.incrementScores(goodPods, PODS_SCORE.BONUS, function (err) {
227 if (err) logger.error('Cannot increment scores of good pods.', { error: err }) 223 if (err) logger.error('Cannot increment scores of good pods.', { error: err })
228 }) 224 })
229 } 225 }
230 226
231 if (badPods.length !== 0) { 227 if (badPods.length !== 0) {
232 this.incrementScores(badPods, constants.PODS_SCORE.MALUS, function (err) { 228 this.incrementScores(badPods, PODS_SCORE.MALUS, function (err) {
233 if (err) logger.error('Cannot decrement scores of bad pods.', { error: err }) 229 if (err) logger.error('Cannot decrement scores of bad pods.', { error: err })
234 removeBadPods.call(self) 230 removeBadPods.call(self)
235 }) 231 })
@@ -255,7 +251,7 @@ function removeBadPods () {
255 }, 251 },
256 252
257 function removeTheseBadPods (pods, callback) { 253 function removeTheseBadPods (pods, callback) {
258 each(pods, function (pod, callbackEach) { 254 each(pods, function (pod: any, callbackEach) {
259 pod.destroy().asCallback(callbackEach) 255 pod.destroy().asCallback(callbackEach)
260 }, function (err) { 256 }, function (err) {
261 return callback(err, pods.length) 257 return callback(err, pods.length)
diff --git a/server/models/request-to-pod.js b/server/models/request-to-pod.ts
index 0e01a842e..479202e40 100644
--- a/server/models/request-to-pod.js
+++ b/server/models/request-to-pod.ts
@@ -1,7 +1,3 @@
1'use strict'
2
3// ---------------------------------------------------------------------------
4
5module.exports = function (sequelize, DataTypes) { 1module.exports = function (sequelize, DataTypes) {
6 const RequestToPod = sequelize.define('RequestToPod', {}, { 2 const RequestToPod = sequelize.define('RequestToPod', {}, {
7 indexes: [ 3 indexes: [
@@ -27,7 +23,7 @@ module.exports = function (sequelize, DataTypes) {
27// --------------------------------------------------------------------------- 23// ---------------------------------------------------------------------------
28 24
29function removeByRequestIdsAndPod (requestsIds, podId, callback) { 25function removeByRequestIdsAndPod (requestsIds, podId, callback) {
30 if (!callback) callback = function () {} 26 if (!callback) callback = function () { /* empty */ }
31 27
32 const query = { 28 const query = {
33 where: { 29 where: {
diff --git a/server/models/request-video-event.js b/server/models/request-video-event.ts
index 9ebeaec90..c61525029 100644
--- a/server/models/request-video-event.js
+++ b/server/models/request-video-event.ts
@@ -1,13 +1,11 @@
1'use strict'
2
3/* 1/*
4 Request Video events (likes, dislikes, views...) 2 Request Video events (likes, dislikes, views...)
5*/ 3*/
6 4
7const values = require('lodash/values') 5import { values } from 'lodash'
8 6
9const constants = require('../initializers/constants') 7import { REQUEST_VIDEO_EVENT_TYPES } from '../initializers'
10const customVideosValidators = require('../helpers/custom-validators').videos 8import { isVideoEventCountValid } from '../helpers'
11 9
12// --------------------------------------------------------------------------- 10// ---------------------------------------------------------------------------
13 11
@@ -15,7 +13,7 @@ module.exports = function (sequelize, DataTypes) {
15 const RequestVideoEvent = sequelize.define('RequestVideoEvent', 13 const RequestVideoEvent = sequelize.define('RequestVideoEvent',
16 { 14 {
17 type: { 15 type: {
18 type: DataTypes.ENUM(values(constants.REQUEST_VIDEO_EVENT_TYPES)), 16 type: DataTypes.ENUM(values(REQUEST_VIDEO_EVENT_TYPES)),
19 allowNull: false 17 allowNull: false
20 }, 18 },
21 count: { 19 count: {
@@ -23,7 +21,7 @@ module.exports = function (sequelize, DataTypes) {
23 allowNull: false, 21 allowNull: false,
24 validate: { 22 validate: {
25 countValid: function (value) { 23 countValid: function (value) {
26 const res = customVideosValidators.isVideoEventCountValid(value) 24 const res = isVideoEventCountValid(value)
27 if (res === false) throw new Error('Video event count is not valid.') 25 if (res === false) throw new Error('Video event count is not valid.')
28 } 26 }
29 } 27 }
diff --git a/server/models/request-video-qadu.js b/server/models/request-video-qadu.ts
index 5d88738aa..2b1ed07c9 100644
--- a/server/models/request-video-qadu.js
+++ b/server/models/request-video-qadu.ts
@@ -1,5 +1,3 @@
1'use strict'
2
3/* 1/*
4 Request Video for Quick And Dirty Updates like: 2 Request Video for Quick And Dirty Updates like:
5 - views 3 - views
@@ -11,9 +9,9 @@
11 So we put it an independant request scheduler. 9 So we put it an independant request scheduler.
12*/ 10*/
13 11
14const values = require('lodash/values') 12import { values } from 'lodash'
15 13
16const constants = require('../initializers/constants') 14import { REQUEST_VIDEO_QADU_TYPES } from '../initializers'
17 15
18// --------------------------------------------------------------------------- 16// ---------------------------------------------------------------------------
19 17
@@ -21,7 +19,7 @@ module.exports = function (sequelize, DataTypes) {
21 const RequestVideoQadu = sequelize.define('RequestVideoQadu', 19 const RequestVideoQadu = sequelize.define('RequestVideoQadu',
22 { 20 {
23 type: { 21 type: {
24 type: DataTypes.ENUM(values(constants.REQUEST_VIDEO_QADU_TYPES)), 22 type: DataTypes.ENUM(values(REQUEST_VIDEO_QADU_TYPES)),
25 allowNull: false 23 allowNull: false
26 } 24 }
27 }, 25 },
diff --git a/server/models/request.js b/server/models/request.ts
index 3a047f7ee..672f79d11 100644
--- a/server/models/request.js
+++ b/server/models/request.ts
@@ -1,8 +1,6 @@
1'use strict' 1import { values } from 'lodash'
2 2
3const values = require('lodash/values') 3import { REQUEST_ENDPOINTS } from '../initializers'
4
5const constants = require('../initializers/constants')
6 4
7// --------------------------------------------------------------------------- 5// ---------------------------------------------------------------------------
8 6
@@ -14,7 +12,7 @@ module.exports = function (sequelize, DataTypes) {
14 allowNull: false 12 allowNull: false
15 }, 13 },
16 endpoint: { 14 endpoint: {
17 type: DataTypes.ENUM(values(constants.REQUEST_ENDPOINTS)), 15 type: DataTypes.ENUM(values(REQUEST_ENDPOINTS)),
18 allowNull: false 16 allowNull: false
19 } 17 }
20 }, 18 },
@@ -100,7 +98,7 @@ function removeAll (callback) {
100} 98}
101 99
102function removeWithEmptyTo (callback) { 100function removeWithEmptyTo (callback) {
103 if (!callback) callback = function () {} 101 if (!callback) callback = function () { /* empty */ }
104 102
105 const query = { 103 const query = {
106 where: { 104 where: {
diff --git a/server/models/tag.js b/server/models/tag.ts
index 145e090c1..85a0442d2 100644
--- a/server/models/tag.js
+++ b/server/models/tag.ts
@@ -1,6 +1,4 @@
1'use strict' 1import { each } from 'async'
2
3const each = require('async/each')
4 2
5// --------------------------------------------------------------------------- 3// ---------------------------------------------------------------------------
6 4
@@ -51,7 +49,7 @@ function findOrCreateTags (tags, transaction, callback) {
51 const tagInstances = [] 49 const tagInstances = []
52 50
53 each(tags, function (tag, callbackEach) { 51 each(tags, function (tag, callbackEach) {
54 const query = { 52 const query: any = {
55 where: { 53 where: {
56 name: tag 54 name: tag
57 }, 55 },
diff --git a/server/models/user-video-rate.js b/server/models/user-video-rate.ts
index 84007d70c..6603c7862 100644
--- a/server/models/user-video-rate.js
+++ b/server/models/user-video-rate.ts
@@ -1,13 +1,10 @@
1'use strict'
2
3/* 1/*
4 User rates per video. 2 User rates per video.
5 3
6*/ 4*/
5import { values } from 'lodash'
7 6
8const values = require('lodash/values') 7import { VIDEO_RATE_TYPES } from '../initializers'
9
10const constants = require('../initializers/constants')
11 8
12// --------------------------------------------------------------------------- 9// ---------------------------------------------------------------------------
13 10
@@ -15,7 +12,7 @@ module.exports = function (sequelize, DataTypes) {
15 const UserVideoRate = sequelize.define('UserVideoRate', 12 const UserVideoRate = sequelize.define('UserVideoRate',
16 { 13 {
17 type: { 14 type: {
18 type: DataTypes.ENUM(values(constants.VIDEO_RATE_TYPES)), 15 type: DataTypes.ENUM(values(VIDEO_RATE_TYPES)),
19 allowNull: false 16 allowNull: false
20 } 17 }
21 }, 18 },
@@ -70,7 +67,7 @@ function load (userId, videoId, transaction, callback) {
70 } 67 }
71 } 68 }
72 69
73 const options = {} 70 const options: any = {}
74 if (transaction) options.transaction = transaction 71 if (transaction) options.transaction = transaction
75 72
76 return this.findOne(query, options).asCallback(callback) 73 return this.findOne(query, options).asCallback(callback)
diff --git a/server/models/user.js b/server/models/user.ts
index 8f9c2bf65..d63a50cc4 100644
--- a/server/models/user.js
+++ b/server/models/user.ts
@@ -1,11 +1,14 @@
1'use strict' 1import { values } from 'lodash'
2 2
3const values = require('lodash/values') 3import { getSort } from './utils'
4 4import { USER_ROLES } from '../initializers'
5const modelUtils = require('./utils') 5import {
6const constants = require('../initializers/constants') 6 cryptPassword,
7const peertubeCrypto = require('../helpers/peertube-crypto') 7 comparePassword,
8const customUsersValidators = require('../helpers/custom-validators').users 8 isUserPasswordValid,
9 isUserUsernameValid,
10 isUserDisplayNSFWValid
11} from '../helpers'
9 12
10// --------------------------------------------------------------------------- 13// ---------------------------------------------------------------------------
11 14
@@ -17,7 +20,7 @@ module.exports = function (sequelize, DataTypes) {
17 allowNull: false, 20 allowNull: false,
18 validate: { 21 validate: {
19 passwordValid: function (value) { 22 passwordValid: function (value) {
20 const res = customUsersValidators.isUserPasswordValid(value) 23 const res = isUserPasswordValid(value)
21 if (res === false) throw new Error('Password not valid.') 24 if (res === false) throw new Error('Password not valid.')
22 } 25 }
23 } 26 }
@@ -27,7 +30,7 @@ module.exports = function (sequelize, DataTypes) {
27 allowNull: false, 30 allowNull: false,
28 validate: { 31 validate: {
29 usernameValid: function (value) { 32 usernameValid: function (value) {
30 const res = customUsersValidators.isUserUsernameValid(value) 33 const res = isUserUsernameValid(value)
31 if (res === false) throw new Error('Username not valid.') 34 if (res === false) throw new Error('Username not valid.')
32 } 35 }
33 } 36 }
@@ -45,13 +48,13 @@ module.exports = function (sequelize, DataTypes) {
45 defaultValue: false, 48 defaultValue: false,
46 validate: { 49 validate: {
47 nsfwValid: function (value) { 50 nsfwValid: function (value) {
48 const res = customUsersValidators.isUserDisplayNSFWValid(value) 51 const res = isUserDisplayNSFWValid(value)
49 if (res === false) throw new Error('Display NSFW is not valid.') 52 if (res === false) throw new Error('Display NSFW is not valid.')
50 } 53 }
51 } 54 }
52 }, 55 },
53 role: { 56 role: {
54 type: DataTypes.ENUM(values(constants.USER_ROLES)), 57 type: DataTypes.ENUM(values(USER_ROLES)),
55 allowNull: false 58 allowNull: false
56 } 59 }
57 }, 60 },
@@ -93,7 +96,7 @@ module.exports = function (sequelize, DataTypes) {
93} 96}
94 97
95function beforeCreateOrUpdate (user, options, next) { 98function beforeCreateOrUpdate (user, options, next) {
96 peertubeCrypto.cryptPassword(user.password, function (err, hash) { 99 cryptPassword(user.password, function (err, hash) {
97 if (err) return next(err) 100 if (err) return next(err)
98 101
99 user.password = hash 102 user.password = hash
@@ -105,7 +108,7 @@ function beforeCreateOrUpdate (user, options, next) {
105// ------------------------------ METHODS ------------------------------ 108// ------------------------------ METHODS ------------------------------
106 109
107function isPasswordMatch (password, callback) { 110function isPasswordMatch (password, callback) {
108 return peertubeCrypto.comparePassword(password, this.password, callback) 111 return comparePassword(password, this.password, callback)
109} 112}
110 113
111function toFormatedJSON () { 114function toFormatedJSON () {
@@ -120,7 +123,7 @@ function toFormatedJSON () {
120} 123}
121 124
122function isAdmin () { 125function isAdmin () {
123 return this.role === constants.USER_ROLES.ADMIN 126 return this.role === USER_ROLES.ADMIN
124} 127}
125 128
126// ------------------------------ STATICS ------------------------------ 129// ------------------------------ STATICS ------------------------------
@@ -159,7 +162,7 @@ function listForApi (start, count, sort, callback) {
159 const query = { 162 const query = {
160 offset: start, 163 offset: start,
161 limit: count, 164 limit: count,
162 order: [ modelUtils.getSort(sort) ] 165 order: [ getSort(sort) ]
163 } 166 }
164 167
165 return this.findAndCountAll(query).asCallback(function (err, result) { 168 return this.findAndCountAll(query).asCallback(function (err, result) {
diff --git a/server/models/utils.js b/server/models/utils.ts
index 49636b3d8..601811913 100644
--- a/server/models/utils.js
+++ b/server/models/utils.ts
@@ -1,9 +1,3 @@
1'use strict'
2
3const utils = {
4 getSort
5}
6
7// Translate for example "-name" to [ 'name', 'DESC' ] 1// Translate for example "-name" to [ 'name', 'DESC' ]
8function getSort (value) { 2function getSort (value) {
9 let field 3 let field
@@ -22,4 +16,6 @@ function getSort (value) {
22 16
23// --------------------------------------------------------------------------- 17// ---------------------------------------------------------------------------
24 18
25module.exports = utils 19export {
20 getSort
21}
diff --git a/server/models/video-abuse.js b/server/models/video-abuse.ts
index 67cead3af..2a18a293d 100644
--- a/server/models/video-abuse.js
+++ b/server/models/video-abuse.ts
@@ -1,8 +1,6 @@
1'use strict' 1import { CONFIG } from '../initializers'
2 2import { isVideoAbuseReporterUsernameValid, isVideoAbuseReasonValid } from '../helpers'
3const constants = require('../initializers/constants') 3import { getSort } from './utils'
4const modelUtils = require('./utils')
5const customVideosValidators = require('../helpers/custom-validators').videos
6 4
7module.exports = function (sequelize, DataTypes) { 5module.exports = function (sequelize, DataTypes) {
8 const VideoAbuse = sequelize.define('VideoAbuse', 6 const VideoAbuse = sequelize.define('VideoAbuse',
@@ -12,7 +10,7 @@ module.exports = function (sequelize, DataTypes) {
12 allowNull: false, 10 allowNull: false,
13 validate: { 11 validate: {
14 reporterUsernameValid: function (value) { 12 reporterUsernameValid: function (value) {
15 const res = customVideosValidators.isVideoAbuseReporterUsernameValid(value) 13 const res = isVideoAbuseReporterUsernameValid(value)
16 if (res === false) throw new Error('Video abuse reporter username is not valid.') 14 if (res === false) throw new Error('Video abuse reporter username is not valid.')
17 } 15 }
18 } 16 }
@@ -22,7 +20,7 @@ module.exports = function (sequelize, DataTypes) {
22 allowNull: false, 20 allowNull: false,
23 validate: { 21 validate: {
24 reasonValid: function (value) { 22 reasonValid: function (value) {
25 const res = customVideosValidators.isVideoAbuseReasonValid(value) 23 const res = isVideoAbuseReasonValid(value)
26 if (res === false) throw new Error('Video abuse reason is not valid.') 24 if (res === false) throw new Error('Video abuse reason is not valid.')
27 } 25 }
28 } 26 }
@@ -75,7 +73,7 @@ function listForApi (start, count, sort, callback) {
75 const query = { 73 const query = {
76 offset: start, 74 offset: start,
77 limit: count, 75 limit: count,
78 order: [ modelUtils.getSort(sort) ], 76 order: [ getSort(sort) ],
79 include: [ 77 include: [
80 { 78 {
81 model: this.sequelize.models.Pod, 79 model: this.sequelize.models.Pod,
@@ -98,7 +96,7 @@ function toFormatedJSON () {
98 reporterPodHost = this.Pod.host 96 reporterPodHost = this.Pod.host
99 } else { 97 } else {
100 // It means it's our video 98 // It means it's our video
101 reporterPodHost = constants.CONFIG.WEBSERVER.HOST 99 reporterPodHost = CONFIG.WEBSERVER.HOST
102 } 100 }
103 101
104 const json = { 102 const json = {
diff --git a/server/models/video-blacklist.js b/server/models/video-blacklist.ts
index 02ea15760..1f00702c7 100644
--- a/server/models/video-blacklist.js
+++ b/server/models/video-blacklist.ts
@@ -1,6 +1,4 @@
1'use strict' 1import { getSort } from './utils'
2
3const modelUtils = require('./utils')
4 2
5// --------------------------------------------------------------------------- 3// ---------------------------------------------------------------------------
6 4
@@ -64,7 +62,7 @@ function listForApi (start, count, sort, callback) {
64 const query = { 62 const query = {
65 offset: start, 63 offset: start,
66 limit: count, 64 limit: count,
67 order: [ modelUtils.getSort(sort) ] 65 order: [ getSort(sort) ]
68 } 66 }
69 67
70 return this.findAndCountAll(query).asCallback(function (err, result) { 68 return this.findAndCountAll(query).asCallback(function (err, result) {
diff --git a/server/models/video-tag.js b/server/models/video-tag.ts
index cd9277a6e..83ff6053f 100644
--- a/server/models/video-tag.js
+++ b/server/models/video-tag.ts
@@ -1,7 +1,3 @@
1'use strict'
2
3// ---------------------------------------------------------------------------
4
5module.exports = function (sequelize, DataTypes) { 1module.exports = function (sequelize, DataTypes) {
6 const VideoTag = sequelize.define('VideoTag', {}, { 2 const VideoTag = sequelize.define('VideoTag', {}, {
7 indexes: [ 3 indexes: [
diff --git a/server/models/video.js b/server/models/video.ts
index da4ddb420..1e29f1355 100644
--- a/server/models/video.js
+++ b/server/models/video.ts
@@ -1,24 +1,38 @@
1'use strict' 1import safeBuffer = require('safe-buffer')
2 2const Buffer = safeBuffer.Buffer
3const Buffer = require('safe-buffer').Buffer 3import createTorrent = require('create-torrent')
4const createTorrent = require('create-torrent') 4import ffmpeg = require('fluent-ffmpeg')
5const ffmpeg = require('fluent-ffmpeg') 5import fs = require('fs')
6const fs = require('fs') 6import magnetUtil = require('magnet-uri')
7const magnetUtil = require('magnet-uri') 7import { map, values } from 'lodash'
8const map = require('lodash/map') 8import { parallel, series } from 'async'
9const parallel = require('async/parallel') 9import parseTorrent = require('parse-torrent')
10const series = require('async/series') 10import { join } from 'path'
11const parseTorrent = require('parse-torrent') 11
12const pathUtils = require('path')
13const values = require('lodash/values')
14
15const constants = require('../initializers/constants')
16const logger = require('../helpers/logger')
17const friends = require('../lib/friends')
18const modelUtils = require('./utils')
19const customVideosValidators = require('../helpers/custom-validators').videos
20const db = require('../initializers/database') 12const db = require('../initializers/database')
21const jobScheduler = require('../lib/jobs/job-scheduler') 13import {
14 logger,
15 isVideoNameValid,
16 isVideoCategoryValid,
17 isVideoLicenceValid,
18 isVideoLanguageValid,
19 isVideoNSFWValid,
20 isVideoDescriptionValid,
21 isVideoInfoHashValid,
22 isVideoDurationValid
23} from '../helpers'
24import {
25 CONSTRAINTS_FIELDS,
26 CONFIG,
27 REMOTE_SCHEME,
28 STATIC_PATHS,
29 VIDEO_CATEGORIES,
30 VIDEO_LICENCES,
31 VIDEO_LANGUAGES,
32 THUMBNAILS_SIZE
33} from '../initializers'
34import { JobScheduler, removeVideoToFriends } from '../lib'
35import { getSort } from './utils'
22 36
23// --------------------------------------------------------------------------- 37// ---------------------------------------------------------------------------
24 38
@@ -38,13 +52,13 @@ module.exports = function (sequelize, DataTypes) {
38 allowNull: false, 52 allowNull: false,
39 validate: { 53 validate: {
40 nameValid: function (value) { 54 nameValid: function (value) {
41 const res = customVideosValidators.isVideoNameValid(value) 55 const res = isVideoNameValid(value)
42 if (res === false) throw new Error('Video name is not valid.') 56 if (res === false) throw new Error('Video name is not valid.')
43 } 57 }
44 } 58 }
45 }, 59 },
46 extname: { 60 extname: {
47 type: DataTypes.ENUM(values(constants.CONSTRAINTS_FIELDS.VIDEOS.EXTNAME)), 61 type: DataTypes.ENUM(values(CONSTRAINTS_FIELDS.VIDEOS.EXTNAME)),
48 allowNull: false 62 allowNull: false
49 }, 63 },
50 remoteId: { 64 remoteId: {
@@ -59,7 +73,7 @@ module.exports = function (sequelize, DataTypes) {
59 allowNull: false, 73 allowNull: false,
60 validate: { 74 validate: {
61 categoryValid: function (value) { 75 categoryValid: function (value) {
62 const res = customVideosValidators.isVideoCategoryValid(value) 76 const res = isVideoCategoryValid(value)
63 if (res === false) throw new Error('Video category is not valid.') 77 if (res === false) throw new Error('Video category is not valid.')
64 } 78 }
65 } 79 }
@@ -70,7 +84,7 @@ module.exports = function (sequelize, DataTypes) {
70 defaultValue: null, 84 defaultValue: null,
71 validate: { 85 validate: {
72 licenceValid: function (value) { 86 licenceValid: function (value) {
73 const res = customVideosValidators.isVideoLicenceValid(value) 87 const res = isVideoLicenceValid(value)
74 if (res === false) throw new Error('Video licence is not valid.') 88 if (res === false) throw new Error('Video licence is not valid.')
75 } 89 }
76 } 90 }
@@ -80,7 +94,7 @@ module.exports = function (sequelize, DataTypes) {
80 allowNull: true, 94 allowNull: true,
81 validate: { 95 validate: {
82 languageValid: function (value) { 96 languageValid: function (value) {
83 const res = customVideosValidators.isVideoLanguageValid(value) 97 const res = isVideoLanguageValid(value)
84 if (res === false) throw new Error('Video language is not valid.') 98 if (res === false) throw new Error('Video language is not valid.')
85 } 99 }
86 } 100 }
@@ -90,7 +104,7 @@ module.exports = function (sequelize, DataTypes) {
90 allowNull: false, 104 allowNull: false,
91 validate: { 105 validate: {
92 nsfwValid: function (value) { 106 nsfwValid: function (value) {
93 const res = customVideosValidators.isVideoNSFWValid(value) 107 const res = isVideoNSFWValid(value)
94 if (res === false) throw new Error('Video nsfw attribute is not valid.') 108 if (res === false) throw new Error('Video nsfw attribute is not valid.')
95 } 109 }
96 } 110 }
@@ -100,7 +114,7 @@ module.exports = function (sequelize, DataTypes) {
100 allowNull: false, 114 allowNull: false,
101 validate: { 115 validate: {
102 descriptionValid: function (value) { 116 descriptionValid: function (value) {
103 const res = customVideosValidators.isVideoDescriptionValid(value) 117 const res = isVideoDescriptionValid(value)
104 if (res === false) throw new Error('Video description is not valid.') 118 if (res === false) throw new Error('Video description is not valid.')
105 } 119 }
106 } 120 }
@@ -110,7 +124,7 @@ module.exports = function (sequelize, DataTypes) {
110 allowNull: false, 124 allowNull: false,
111 validate: { 125 validate: {
112 infoHashValid: function (value) { 126 infoHashValid: function (value) {
113 const res = customVideosValidators.isVideoInfoHashValid(value) 127 const res = isVideoInfoHashValid(value)
114 if (res === false) throw new Error('Video info hash is not valid.') 128 if (res === false) throw new Error('Video info hash is not valid.')
115 } 129 }
116 } 130 }
@@ -120,7 +134,7 @@ module.exports = function (sequelize, DataTypes) {
120 allowNull: false, 134 allowNull: false,
121 validate: { 135 validate: {
122 durationValid: function (value) { 136 durationValid: function (value) {
123 const res = customVideosValidators.isVideoDurationValid(value) 137 const res = isVideoDurationValid(value)
124 if (res === false) throw new Error('Video duration is not valid.') 138 if (res === false) throw new Error('Video duration is not valid.')
125 } 139 }
126 } 140 }
@@ -233,7 +247,7 @@ function beforeCreate (video, options, next) {
233 const tasks = [] 247 const tasks = []
234 248
235 if (video.isOwned()) { 249 if (video.isOwned()) {
236 const videoPath = pathUtils.join(constants.CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename()) 250 const videoPath = join(CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename())
237 251
238 tasks.push( 252 tasks.push(
239 function createVideoTorrent (callback) { 253 function createVideoTorrent (callback) {
@@ -249,14 +263,14 @@ function beforeCreate (video, options, next) {
249 } 263 }
250 ) 264 )
251 265
252 if (constants.CONFIG.TRANSCODING.ENABLED === true) { 266 if (CONFIG.TRANSCODING.ENABLED === true) {
253 tasks.push( 267 tasks.push(
254 function createVideoTranscoderJob (callback) { 268 function createVideoTranscoderJob (callback) {
255 const dataInput = { 269 const dataInput = {
256 id: video.id 270 id: video.id
257 } 271 }
258 272
259 jobScheduler.createJob(options.transaction, 'videoTranscoder', dataInput, callback) 273 JobScheduler.Instance.createJob(options.transaction, 'videoTranscoder', dataInput, callback)
260 } 274 }
261 ) 275 )
262 } 276 }
@@ -295,7 +309,7 @@ function afterDestroy (video, options, next) {
295 remoteId: video.id 309 remoteId: video.id
296 } 310 }
297 311
298 friends.removeVideoToFriends(params) 312 removeVideoToFriends(params)
299 313
300 return callback() 314 return callback()
301 } 315 }
@@ -332,19 +346,20 @@ function associate (models) {
332} 346}
333 347
334function generateMagnetUri () { 348function generateMagnetUri () {
335 let baseUrlHttp, baseUrlWs 349 let baseUrlHttp
350 let baseUrlWs
336 351
337 if (this.isOwned()) { 352 if (this.isOwned()) {
338 baseUrlHttp = constants.CONFIG.WEBSERVER.URL 353 baseUrlHttp = CONFIG.WEBSERVER.URL
339 baseUrlWs = constants.CONFIG.WEBSERVER.WS + '://' + constants.CONFIG.WEBSERVER.HOSTNAME + ':' + constants.CONFIG.WEBSERVER.PORT 354 baseUrlWs = CONFIG.WEBSERVER.WS + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
340 } else { 355 } else {
341 baseUrlHttp = constants.REMOTE_SCHEME.HTTP + '://' + this.Author.Pod.host 356 baseUrlHttp = REMOTE_SCHEME.HTTP + '://' + this.Author.Pod.host
342 baseUrlWs = constants.REMOTE_SCHEME.WS + '://' + this.Author.Pod.host 357 baseUrlWs = REMOTE_SCHEME.WS + '://' + this.Author.Pod.host
343 } 358 }
344 359
345 const xs = baseUrlHttp + constants.STATIC_PATHS.TORRENTS + this.getTorrentName() 360 const xs = baseUrlHttp + STATIC_PATHS.TORRENTS + this.getTorrentName()
346 const announce = baseUrlWs + '/tracker/socket' 361 const announce = baseUrlWs + '/tracker/socket'
347 const urlList = [ baseUrlHttp + constants.STATIC_PATHS.WEBSEED + this.getVideoFilename() ] 362 const urlList = [ baseUrlHttp + STATIC_PATHS.WEBSEED + this.getVideoFilename() ]
348 363
349 const magnetHash = { 364 const magnetHash = {
350 xs, 365 xs,
@@ -395,19 +410,19 @@ function toFormatedJSON () {
395 podHost = this.Author.Pod.host 410 podHost = this.Author.Pod.host
396 } else { 411 } else {
397 // It means it's our video 412 // It means it's our video
398 podHost = constants.CONFIG.WEBSERVER.HOST 413 podHost = CONFIG.WEBSERVER.HOST
399 } 414 }
400 415
401 // Maybe our pod is not up to date and there are new categories since our version 416 // Maybe our pod is not up to date and there are new categories since our version
402 let categoryLabel = constants.VIDEO_CATEGORIES[this.category] 417 let categoryLabel = VIDEO_CATEGORIES[this.category]
403 if (!categoryLabel) categoryLabel = 'Misc' 418 if (!categoryLabel) categoryLabel = 'Misc'
404 419
405 // Maybe our pod is not up to date and there are new licences since our version 420 // Maybe our pod is not up to date and there are new licences since our version
406 let licenceLabel = constants.VIDEO_LICENCES[this.licence] 421 let licenceLabel = VIDEO_LICENCES[this.licence]
407 if (!licenceLabel) licenceLabel = 'Unknown' 422 if (!licenceLabel) licenceLabel = 'Unknown'
408 423
409 // Language is an optional attribute 424 // Language is an optional attribute
410 let languageLabel = constants.VIDEO_LANGUAGES[this.language] 425 let languageLabel = VIDEO_LANGUAGES[this.language]
411 if (!languageLabel) languageLabel = 'Unknown' 426 if (!languageLabel) languageLabel = 'Unknown'
412 427
413 const json = { 428 const json = {
@@ -430,7 +445,7 @@ function toFormatedJSON () {
430 likes: this.likes, 445 likes: this.likes,
431 dislikes: this.dislikes, 446 dislikes: this.dislikes,
432 tags: map(this.Tags, 'name'), 447 tags: map(this.Tags, 'name'),
433 thumbnailPath: pathUtils.join(constants.STATIC_PATHS.THUMBNAILS, this.getThumbnailName()), 448 thumbnailPath: join(STATIC_PATHS.THUMBNAILS, this.getThumbnailName()),
434 createdAt: this.createdAt, 449 createdAt: this.createdAt,
435 updatedAt: this.updatedAt 450 updatedAt: this.updatedAt
436 } 451 }
@@ -442,7 +457,7 @@ function toAddRemoteJSON (callback) {
442 const self = this 457 const self = this
443 458
444 // Get thumbnail data to send to the other pod 459 // Get thumbnail data to send to the other pod
445 const thumbnailPath = pathUtils.join(constants.CONFIG.STORAGE.THUMBNAILS_DIR, this.getThumbnailName()) 460 const thumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, this.getThumbnailName())
446 fs.readFile(thumbnailPath, function (err, thumbnailData) { 461 fs.readFile(thumbnailPath, function (err, thumbnailData) {
447 if (err) { 462 if (err) {
448 logger.error('Cannot read the thumbnail of the video') 463 logger.error('Cannot read the thumbnail of the video')
@@ -501,15 +516,15 @@ function toUpdateRemoteJSON (callback) {
501function transcodeVideofile (finalCallback) { 516function transcodeVideofile (finalCallback) {
502 const video = this 517 const video = this
503 518
504 const videosDirectory = constants.CONFIG.STORAGE.VIDEOS_DIR 519 const videosDirectory = CONFIG.STORAGE.VIDEOS_DIR
505 const newExtname = '.mp4' 520 const newExtname = '.mp4'
506 const videoInputPath = pathUtils.join(videosDirectory, video.getVideoFilename()) 521 const videoInputPath = join(videosDirectory, video.getVideoFilename())
507 const videoOutputPath = pathUtils.join(videosDirectory, video.id + '-transcoded' + newExtname) 522 const videoOutputPath = join(videosDirectory, video.id + '-transcoded' + newExtname)
508 523
509 ffmpeg(videoInputPath) 524 ffmpeg(videoInputPath)
510 .output(videoOutputPath) 525 .output(videoOutputPath)
511 .videoCodec('libx264') 526 .videoCodec('libx264')
512 .outputOption('-threads ' + constants.CONFIG.TRANSCODING.THREADS) 527 .outputOption('-threads ' + CONFIG.TRANSCODING.THREADS)
513 .outputOption('-movflags faststart') 528 .outputOption('-movflags faststart')
514 .on('error', finalCallback) 529 .on('error', finalCallback)
515 .on('end', function () { 530 .on('end', function () {
@@ -522,12 +537,12 @@ function transcodeVideofile (finalCallback) {
522 // Important to do this before getVideoFilename() to take in account the new file extension 537 // Important to do this before getVideoFilename() to take in account the new file extension
523 video.set('extname', newExtname) 538 video.set('extname', newExtname)
524 539
525 const newVideoPath = pathUtils.join(videosDirectory, video.getVideoFilename()) 540 const newVideoPath = join(videosDirectory, video.getVideoFilename())
526 fs.rename(videoOutputPath, newVideoPath, callback) 541 fs.rename(videoOutputPath, newVideoPath, callback)
527 }, 542 },
528 543
529 function torrent (callback) { 544 function torrent (callback) {
530 const newVideoPath = pathUtils.join(videosDirectory, video.getVideoFilename()) 545 const newVideoPath = join(videosDirectory, video.getVideoFilename())
531 createTorrentFromVideo(video, newVideoPath, callback) 546 createTorrentFromVideo(video, newVideoPath, callback)
532 }, 547 },
533 548
@@ -557,7 +572,7 @@ function generateThumbnailFromData (video, thumbnailData, callback) {
557 // Creating the thumbnail for a remote video 572 // Creating the thumbnail for a remote video
558 573
559 const thumbnailName = video.getThumbnailName() 574 const thumbnailName = video.getThumbnailName()
560 const thumbnailPath = pathUtils.join(constants.CONFIG.STORAGE.THUMBNAILS_DIR, thumbnailName) 575 const thumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, thumbnailName)
561 fs.writeFile(thumbnailPath, Buffer.from(thumbnailData, 'binary'), function (err) { 576 fs.writeFile(thumbnailPath, Buffer.from(thumbnailData, 'binary'), function (err) {
562 if (err) return callback(err) 577 if (err) return callback(err)
563 578
@@ -583,7 +598,7 @@ function listForApi (start, count, sort, callback) {
583 offset: start, 598 offset: start,
584 limit: count, 599 limit: count,
585 distinct: true, // For the count, a video can have many tags 600 distinct: true, // For the count, a video can have many tags
586 order: [ modelUtils.getSort(sort), [ this.sequelize.models.Tag, 'name', 'ASC' ] ], 601 order: [ getSort(sort), [ this.sequelize.models.Tag, 'name', 'ASC' ] ],
587 include: [ 602 include: [
588 { 603 {
589 model: this.sequelize.models.Author, 604 model: this.sequelize.models.Author,
@@ -683,28 +698,28 @@ function loadAndPopulateAuthorAndPodAndTags (id, callback) {
683} 698}
684 699
685function searchAndPopulateAuthorAndPodAndTags (value, field, start, count, sort, callback) { 700function searchAndPopulateAuthorAndPodAndTags (value, field, start, count, sort, callback) {
686 const podInclude = { 701 const podInclude: any = {
687 model: this.sequelize.models.Pod, 702 model: this.sequelize.models.Pod,
688 required: false 703 required: false
689 } 704 }
690 705
691 const authorInclude = { 706 const authorInclude: any = {
692 model: this.sequelize.models.Author, 707 model: this.sequelize.models.Author,
693 include: [ 708 include: [
694 podInclude 709 podInclude
695 ] 710 ]
696 } 711 }
697 712
698 const tagInclude = { 713 const tagInclude: any = {
699 model: this.sequelize.models.Tag 714 model: this.sequelize.models.Tag
700 } 715 }
701 716
702 const query = { 717 const query: any = {
703 where: createBaseVideosWhere.call(this), 718 where: createBaseVideosWhere.call(this),
704 offset: start, 719 offset: start,
705 limit: count, 720 limit: count,
706 distinct: true, // For the count, a video can have many tags 721 distinct: true, // For the count, a video can have many tags
707 order: [ modelUtils.getSort(sort), [ this.sequelize.models.Tag, 'name', 'ASC' ] ] 722 order: [ getSort(sort), [ this.sequelize.models.Tag, 'name', 'ASC' ] ]
708 } 723 }
709 724
710 // Make an exact search with the magnet 725 // Make an exact search with the magnet
@@ -766,39 +781,39 @@ function createBaseVideosWhere () {
766} 781}
767 782
768function removeThumbnail (video, callback) { 783function removeThumbnail (video, callback) {
769 const thumbnailPath = pathUtils.join(constants.CONFIG.STORAGE.THUMBNAILS_DIR, video.getThumbnailName()) 784 const thumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, video.getThumbnailName())
770 fs.unlink(thumbnailPath, callback) 785 fs.unlink(thumbnailPath, callback)
771} 786}
772 787
773function removeFile (video, callback) { 788function removeFile (video, callback) {
774 const filePath = pathUtils.join(constants.CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename()) 789 const filePath = join(CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename())
775 fs.unlink(filePath, callback) 790 fs.unlink(filePath, callback)
776} 791}
777 792
778function removeTorrent (video, callback) { 793function removeTorrent (video, callback) {
779 const torrenPath = pathUtils.join(constants.CONFIG.STORAGE.TORRENTS_DIR, video.getTorrentName()) 794 const torrenPath = join(CONFIG.STORAGE.TORRENTS_DIR, video.getTorrentName())
780 fs.unlink(torrenPath, callback) 795 fs.unlink(torrenPath, callback)
781} 796}
782 797
783function removePreview (video, callback) { 798function removePreview (video, callback) {
784 // Same name than video thumnail 799 // Same name than video thumnail
785 fs.unlink(constants.CONFIG.STORAGE.PREVIEWS_DIR + video.getPreviewName(), callback) 800 fs.unlink(CONFIG.STORAGE.PREVIEWS_DIR + video.getPreviewName(), callback)
786} 801}
787 802
788function createTorrentFromVideo (video, videoPath, callback) { 803function createTorrentFromVideo (video, videoPath, callback) {
789 const options = { 804 const options = {
790 announceList: [ 805 announceList: [
791 [ constants.CONFIG.WEBSERVER.WS + '://' + constants.CONFIG.WEBSERVER.HOSTNAME + ':' + constants.CONFIG.WEBSERVER.PORT + '/tracker/socket' ] 806 [ CONFIG.WEBSERVER.WS + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT + '/tracker/socket' ]
792 ], 807 ],
793 urlList: [ 808 urlList: [
794 constants.CONFIG.WEBSERVER.URL + constants.STATIC_PATHS.WEBSEED + video.getVideoFilename() 809 CONFIG.WEBSERVER.URL + STATIC_PATHS.WEBSEED + video.getVideoFilename()
795 ] 810 ]
796 } 811 }
797 812
798 createTorrent(videoPath, options, function (err, torrent) { 813 createTorrent(videoPath, options, function (err, torrent) {
799 if (err) return callback(err) 814 if (err) return callback(err)
800 815
801 const filePath = pathUtils.join(constants.CONFIG.STORAGE.TORRENTS_DIR, video.getTorrentName()) 816 const filePath = join(CONFIG.STORAGE.TORRENTS_DIR, video.getTorrentName())
802 fs.writeFile(filePath, torrent, function (err) { 817 fs.writeFile(filePath, torrent, function (err) {
803 if (err) return callback(err) 818 if (err) return callback(err)
804 819
@@ -810,15 +825,15 @@ function createTorrentFromVideo (video, videoPath, callback) {
810} 825}
811 826
812function createPreview (video, videoPath, callback) { 827function createPreview (video, videoPath, callback) {
813 generateImage(video, videoPath, constants.CONFIG.STORAGE.PREVIEWS_DIR, video.getPreviewName(), callback) 828 generateImage(video, videoPath, CONFIG.STORAGE.PREVIEWS_DIR, video.getPreviewName(), callback)
814} 829}
815 830
816function createThumbnail (video, videoPath, callback) { 831function createThumbnail (video, videoPath, callback) {
817 generateImage(video, videoPath, constants.CONFIG.STORAGE.THUMBNAILS_DIR, video.getThumbnailName(), constants.THUMBNAILS_SIZE, callback) 832 generateImage(video, videoPath, CONFIG.STORAGE.THUMBNAILS_DIR, video.getThumbnailName(), THUMBNAILS_SIZE, callback)
818} 833}
819 834
820function generateImage (video, videoPath, folder, imageName, size, callback) { 835function generateImage (video, videoPath, folder, imageName, size, callback?) {
821 const options = { 836 const options: any = {
822 filename: imageName, 837 filename: imageName,
823 count: 1, 838 count: 1,
824 folder 839 folder
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 000000000..039881230
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,19 @@
1{
2 "compilerOptions": {
3 "module": "commonjs",
4 "target": "es5",
5 "noImplicitAny": false,
6 "sourceMap": false,
7 "outDir": "./dist",
8 "lib": [
9 "es2015"
10 ],
11 "types": [
12 "node"
13 ]
14 },
15 "exclude": [
16 "node_modules",
17 "client"
18 ]
19}
diff --git a/tslint.json b/tslint.json
new file mode 100644
index 000000000..888779856
--- /dev/null
+++ b/tslint.json
@@ -0,0 +1,3 @@
1{
2 "extends": "tslint-config-standard"
3}
diff --git a/yarn.lock b/yarn.lock
index 284cdb444..c0ce443b3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,34 +2,88 @@
2# yarn lockfile v1 2# yarn lockfile v1
3 3
4 4
5"@types/bluebird@~3.0.36": 5"@types/async@^2.0.40":
6 version "2.0.40"
7 resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.40.tgz#ac02de68e66c004a61b7cb16df8b1db3a254cca9"
8
9"@types/bcrypt@^1.0.0":
10 version "1.0.0"
11 resolved "https://registry.yarnpkg.com/@types/bcrypt/-/bcrypt-1.0.0.tgz#2c523da191db7d41c06d17de235335c985effe9b"
12
13"@types/bluebird@*", "@types/bluebird@~3.0.36":
6 version "3.0.37" 14 version "3.0.37"
7 resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.0.37.tgz#2e76b394aa9bea40d04241a31c0887a260283388" 15 resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.0.37.tgz#2e76b394aa9bea40d04241a31c0887a260283388"
8 16
17"@types/body-parser@^1.16.3":
18 version "1.16.3"
19 resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.16.3.tgz#bc2b9a181f2fa85c80f1ecacd8a05cf1414b85a3"
20 dependencies:
21 "@types/express" "*"
22 "@types/node" "*"
23
24"@types/config@^0.0.32":
25 version "0.0.32"
26 resolved "https://registry.yarnpkg.com/@types/config/-/config-0.0.32.tgz#c106055802d78e234e28374adc4dad460d098558"
27
9"@types/express-serve-static-core@*": 28"@types/express-serve-static-core@*":
10 version "4.0.44" 29 version "4.0.44"
11 resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.0.44.tgz#a1c3bd5d80e93c72fba91a03f5412c47f21d4ae7" 30 resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.0.44.tgz#a1c3bd5d80e93c72fba91a03f5412c47f21d4ae7"
12 dependencies: 31 dependencies:
13 "@types/node" "*" 32 "@types/node" "*"
14 33
15"@types/express@~4.0.34": 34"@types/express@*", "@types/express@^4.0.35", "@types/express@~4.0.34":
16 version "4.0.35" 35 version "4.0.35"
17 resolved "https://registry.yarnpkg.com/@types/express/-/express-4.0.35.tgz#6267c7b60a51fac473467b3c4a02cd1e441805fe" 36 resolved "https://registry.yarnpkg.com/@types/express/-/express-4.0.35.tgz#6267c7b60a51fac473467b3c4a02cd1e441805fe"
18 dependencies: 37 dependencies:
19 "@types/express-serve-static-core" "*" 38 "@types/express-serve-static-core" "*"
20 "@types/serve-static" "*" 39 "@types/serve-static" "*"
21 40
41"@types/form-data@*":
42 version "0.0.33"
43 resolved "https://registry.yarnpkg.com/@types/form-data/-/form-data-0.0.33.tgz#c9ac85b2a5fd18435b8c85d9ecb50e6d6c893ff8"
44 dependencies:
45 "@types/node" "*"
46
22"@types/geojson@^1.0.0": 47"@types/geojson@^1.0.0":
23 version "1.0.2" 48 version "1.0.2"
24 resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-1.0.2.tgz#b02d10ab028e2928ac592a051aaa4981a1941d03" 49 resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-1.0.2.tgz#b02d10ab028e2928ac592a051aaa4981a1941d03"
25 50
51"@types/lodash@*", "@types/lodash@^4.14.64":
52 version "4.14.64"
53 resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.64.tgz#979cf3a3d4a368670840bf9b3e448dc33ffe84ee"
54
26"@types/mime@*": 55"@types/mime@*":
27 version "0.0.29" 56 version "0.0.29"
28 resolved "https://registry.yarnpkg.com/@types/mime/-/mime-0.0.29.tgz#fbcfd330573b912ef59eeee14602bface630754b" 57 resolved "https://registry.yarnpkg.com/@types/mime/-/mime-0.0.29.tgz#fbcfd330573b912ef59eeee14602bface630754b"
29 58
30"@types/node@*": 59"@types/mkdirp@^0.3.29":
31 version "7.0.14" 60 version "0.3.29"
32 resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.14.tgz#1470fa002a113316ac9d9ad163fc738c7a0de2a4" 61 resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.3.29.tgz#7f2ad7ec55f914482fc9b1ec4bb1ae6028d46066"
62
63"@types/morgan@^1.7.32":
64 version "1.7.32"
65 resolved "https://registry.yarnpkg.com/@types/morgan/-/morgan-1.7.32.tgz#fab1ece4dae172e1a377d563d33e3634fa04927d"
66 dependencies:
67 "@types/express" "*"
68
69"@types/node@*", "@types/node@^7.0.18":
70 version "7.0.18"
71 resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.18.tgz#cd67f27d3dc0cfb746f0bdd5e086c4c5d55be173"
72
73"@types/request@^0.0.43":
74 version "0.0.43"
75 resolved "https://registry.yarnpkg.com/@types/request/-/request-0.0.43.tgz#fcc59cfd88e63034e813c6884a0aade2d0f7e935"
76 dependencies:
77 "@types/form-data" "*"
78 "@types/node" "*"
79
80"@types/sequelize@3":
81 version "3.4.48"
82 resolved "https://registry.yarnpkg.com/@types/sequelize/-/sequelize-3.4.48.tgz#f88fac7cc4717d2e87f20f69ebb64aa869e7e4d1"
83 dependencies:
84 "@types/bluebird" "*"
85 "@types/lodash" "*"
86 "@types/validator" "*"
33 87
34"@types/serve-static@*": 88"@types/serve-static@*":
35 version "1.7.31" 89 version "1.7.31"
@@ -38,6 +92,22 @@
38 "@types/express-serve-static-core" "*" 92 "@types/express-serve-static-core" "*"
39 "@types/mime" "*" 93 "@types/mime" "*"
40 94
95"@types/validator@*":
96 version "6.2.0"
97 resolved "https://registry.yarnpkg.com/@types/validator/-/validator-6.2.0.tgz#020322fe1929f69889eb675a1bdb5a98394b71f0"
98
99"@types/winston@^2.3.2":
100 version "2.3.2"
101 resolved "https://registry.yarnpkg.com/@types/winston/-/winston-2.3.2.tgz#c162547cb47c0b8a450e681bb9fa7041cd80edfa"
102 dependencies:
103 "@types/node" "*"
104
105"@types/ws@^0.0.41":
106 version "0.0.41"
107 resolved "https://registry.yarnpkg.com/@types/ws/-/ws-0.0.41.tgz#88a7e0cd1605bd6ea773110954671394c690db1a"
108 dependencies:
109 "@types/node" "*"
110
41abbrev@1: 111abbrev@1:
42 version "1.1.0" 112 version "1.1.0"
43 resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" 113 resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f"
@@ -198,7 +268,7 @@ aws4@^1.2.1:
198 version "1.6.0" 268 version "1.6.0"
199 resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" 269 resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
200 270
201babel-code-frame@^6.16.0: 271babel-code-frame@^6.16.0, babel-code-frame@^6.22.0:
202 version "6.22.0" 272 version "6.22.0"
203 resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" 273 resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4"
204 dependencies: 274 dependencies:
@@ -523,6 +593,10 @@ colors@1.0.x:
523 version "1.0.3" 593 version "1.0.3"
524 resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" 594 resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
525 595
596colors@^1.1.2:
597 version "1.1.2"
598 resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
599
526combined-stream@^1.0.5, combined-stream@~1.0.5: 600combined-stream@^1.0.5, combined-stream@~1.0.5:
527 version "1.0.5" 601 version "1.0.5"
528 resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" 602 resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
@@ -785,7 +859,7 @@ dicer@0.2.5:
785 readable-stream "1.1.x" 859 readable-stream "1.1.x"
786 streamsearch "0.1.2" 860 streamsearch "0.1.2"
787 861
788diff@3.2.0: 862diff@3.2.0, diff@^3.2.0:
789 version "3.2.0" 863 version "3.2.0"
790 resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" 864 resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
791 865
@@ -796,6 +870,13 @@ doctrine@1.5.0, doctrine@^1.2.2:
796 esutils "^2.0.2" 870 esutils "^2.0.2"
797 isarray "^1.0.0" 871 isarray "^1.0.0"
798 872
873doctrine@^0.7.2:
874 version "0.7.2"
875 resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-0.7.2.tgz#7cb860359ba3be90e040b26b729ce4bfa654c523"
876 dependencies:
877 esutils "^1.1.6"
878 isarray "0.0.1"
879
799doctrine@^2.0.0: 880doctrine@^2.0.0:
800 version "2.0.0" 881 version "2.0.0"
801 resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" 882 resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63"
@@ -1057,6 +1138,10 @@ estraverse@~4.1.0:
1057 version "4.1.1" 1138 version "4.1.1"
1058 resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.1.1.tgz#f6caca728933a850ef90661d0e17982ba47111a2" 1139 resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.1.1.tgz#f6caca728933a850ef90661d0e17982ba47111a2"
1059 1140
1141esutils@^1.1.6:
1142 version "1.1.6"
1143 resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.1.6.tgz#c01ccaa9ae4b897c6d0c3e210ae52f3c7a844375"
1144
1060esutils@^2.0.2: 1145esutils@^2.0.2:
1061 version "2.0.2" 1146 version "2.0.2"
1062 resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" 1147 resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
@@ -1200,6 +1285,12 @@ find-up@^2.0.0:
1200 dependencies: 1285 dependencies:
1201 locate-path "^2.0.0" 1286 locate-path "^2.0.0"
1202 1287
1288findup-sync@~0.3.0:
1289 version "0.3.0"
1290 resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.3.0.tgz#37930aa5d816b777c03445e1966cc6790a4c0b16"
1291 dependencies:
1292 glob "~5.0.0"
1293
1203flat-cache@^1.2.1: 1294flat-cache@^1.2.1:
1204 version "1.2.2" 1295 version "1.2.2"
1205 resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96" 1296 resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96"
@@ -1333,7 +1424,7 @@ github-from-package@0.0.0:
1333 version "0.0.0" 1424 version "0.0.0"
1334 resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" 1425 resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce"
1335 1426
1336glob@7.1.1, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5: 1427glob@7.1.1, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1:
1337 version "7.1.1" 1428 version "7.1.1"
1338 resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" 1429 resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
1339 dependencies: 1430 dependencies:
@@ -1344,6 +1435,16 @@ glob@7.1.1, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5:
1344 once "^1.3.0" 1435 once "^1.3.0"
1345 path-is-absolute "^1.0.0" 1436 path-is-absolute "^1.0.0"
1346 1437
1438glob@~5.0.0:
1439 version "5.0.15"
1440 resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
1441 dependencies:
1442 inflight "^1.0.4"
1443 inherits "2"
1444 minimatch "2 || 3"
1445 once "^1.3.0"
1446 path-is-absolute "^1.0.0"
1447
1347globals@^9.14.0: 1448globals@^9.14.0:
1348 version "9.17.0" 1449 version "9.17.0"
1349 resolved "https://registry.yarnpkg.com/globals/-/globals-9.17.0.tgz#0c0ca696d9b9bb694d2e5470bd37777caad50286" 1450 resolved "https://registry.yarnpkg.com/globals/-/globals-9.17.0.tgz#0c0ca696d9b9bb694d2e5470bd37777caad50286"
@@ -1862,7 +1963,7 @@ mime@1.3.4, mime@^1.3.4:
1862 version "1.3.4" 1963 version "1.3.4"
1863 resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" 1964 resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53"
1864 1965
1865minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3: 1966"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3:
1866 version "3.0.3" 1967 version "3.0.3"
1867 resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" 1968 resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774"
1868 dependencies: 1969 dependencies:
@@ -2101,7 +2202,7 @@ openssl-wrapper@^0.3.4:
2101 version "0.3.4" 2202 version "0.3.4"
2102 resolved "https://registry.yarnpkg.com/openssl-wrapper/-/openssl-wrapper-0.3.4.tgz#c01ec98e4dcd2b5dfe0b693f31827200e3b81b07" 2203 resolved "https://registry.yarnpkg.com/openssl-wrapper/-/openssl-wrapper-0.3.4.tgz#c01ec98e4dcd2b5dfe0b693f31827200e3b81b07"
2103 2204
2104optimist@0.6.1: 2205optimist@0.6.1, optimist@~0.6.0:
2105 version "0.6.1" 2206 version "0.6.1"
2106 resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" 2207 resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
2107 dependencies: 2208 dependencies:
@@ -2533,7 +2634,7 @@ resolve-from@^1.0.0:
2533 version "1.0.1" 2634 version "1.0.1"
2534 resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" 2635 resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
2535 2636
2536resolve@^1.1.6, resolve@^1.1.7: 2637resolve@^1.1.6, resolve@^1.1.7, resolve@^1.3.2:
2537 version "1.3.3" 2638 version "1.3.3"
2538 resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5" 2639 resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5"
2539 dependencies: 2640 dependencies:
@@ -2616,7 +2717,7 @@ semver@4.3.2:
2616 version "4.3.2" 2717 version "4.3.2"
2617 resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.2.tgz#c7a07158a80bedd052355b770d82d6640f803be7" 2718 resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.2.tgz#c7a07158a80bedd052355b770d82d6640f803be7"
2618 2719
2619semver@5.3.0, semver@^5.0.1, semver@~5.3.0: 2720semver@5.3.0, semver@^5.0.1, semver@^5.3.0, semver@~5.3.0:
2620 version "5.3.0" 2721 version "5.3.0"
2621 resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" 2722 resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
2622 2723
@@ -3080,6 +3181,43 @@ tryit@^1.0.1:
3080 version "1.0.3" 3181 version "1.0.3"
3081 resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" 3182 resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb"
3082 3183
3184tslib@^1.0.0, tslib@^1.6.0:
3185 version "1.7.0"
3186 resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.7.0.tgz#6e8366695f72961252b35167b0dd4fbeeafba491"
3187
3188tslint-config-standard@^5.0.2:
3189 version "5.0.2"
3190 resolved "https://registry.yarnpkg.com/tslint-config-standard/-/tslint-config-standard-5.0.2.tgz#e98fd5c412a6b973798366dc2c85508cf0ed740f"
3191 dependencies:
3192 tslint-eslint-rules "^4.0.0"
3193
3194tslint-eslint-rules@^4.0.0:
3195 version "4.0.0"
3196 resolved "https://registry.yarnpkg.com/tslint-eslint-rules/-/tslint-eslint-rules-4.0.0.tgz#4e0e59ecd5701c9a48c66ed47bdcafb1c635d27b"
3197 dependencies:
3198 doctrine "^0.7.2"
3199 tslib "^1.0.0"
3200 tsutils "^1.4.0"
3201
3202tslint@^5.2.0:
3203 version "5.2.0"
3204 resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.2.0.tgz#16a2addf20cb748385f544e9a0edab086bc34114"
3205 dependencies:
3206 babel-code-frame "^6.22.0"
3207 colors "^1.1.2"
3208 diff "^3.2.0"
3209 findup-sync "~0.3.0"
3210 glob "^7.1.1"
3211 optimist "~0.6.0"
3212 resolve "^1.3.2"
3213 semver "^5.3.0"
3214 tslib "^1.6.0"
3215 tsutils "^1.8.0"
3216
3217tsutils@^1.4.0, tsutils@^1.8.0:
3218 version "1.8.0"
3219 resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-1.8.0.tgz#bf8118ed8e80cd5c9fc7d75728c7963d44ed2f52"
3220
3083tunnel-agent@^0.4.3: 3221tunnel-agent@^0.4.3:
3084 version "0.4.3" 3222 version "0.4.3"
3085 resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" 3223 resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb"
@@ -3125,6 +3263,10 @@ typedarray@^0.0.6:
3125 version "0.0.6" 3263 version "0.0.6"
3126 resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" 3264 resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
3127 3265
3266typescript@~2.2.0:
3267 version "2.2.2"
3268 resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.2.2.tgz#606022508479b55ffa368b58fee963a03dfd7b0c"
3269
3128uid-number@~0.0.6: 3270uid-number@~0.0.6:
3129 version "0.0.6" 3271 version "0.0.6"
3130 resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" 3272 resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"