diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | package.json | 16 | ||||
-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.js | 22 | ||||
-rw-r--r-- | server/controllers/api/config.ts | 22 | ||||
-rw-r--r-- | server/controllers/api/index.js | 35 | ||||
-rw-r--r-- | server/controllers/api/index.ts | 33 | ||||
-rw-r--r-- | server/controllers/api/pods.js | 109 | ||||
-rw-r--r-- | server/controllers/api/pods.ts | 118 | ||||
-rw-r--r-- | server/controllers/api/remote/index.js | 18 | ||||
-rw-r--r-- | server/controllers/api/remote/index.ts | 18 | ||||
-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.js | 11 | ||||
-rw-r--r-- | server/controllers/index.ts | 3 | ||||
-rw-r--r-- | server/controllers/static.js | 45 | ||||
-rw-r--r-- | server/controllers/static.ts | 49 | ||||
-rw-r--r-- | server/helpers/custom-validators/index.js | 19 | ||||
-rw-r--r-- | server/helpers/custom-validators/index.ts | 6 | ||||
-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.js | 11 | ||||
-rw-r--r-- | server/helpers/custom-validators/remote/index.ts | 1 | ||||
-rw-r--r-- | server/helpers/custom-validators/remote/videos.js | 118 | ||||
-rw-r--r-- | server/helpers/custom-validators/remote/videos.ts | 138 | ||||
-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.ts | 6 | ||||
-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.ts | 6 | ||||
-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.ts | 4 | ||||
-rw-r--r-- | server/lib/jobs/handlers/index.js | 7 | ||||
-rw-r--r-- | server/lib/jobs/handlers/index.ts | 9 | ||||
-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.ts | 1 | ||||
-rw-r--r-- | server/lib/jobs/job-scheduler.js | 129 | ||||
-rw-r--r-- | server/lib/jobs/job-scheduler.ts | 137 | ||||
-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.ts | 3 | ||||
-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.js | 25 | ||||
-rw-r--r-- | server/middlewares/index.ts | 8 | ||||
-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.js | 21 | ||||
-rw-r--r-- | server/middlewares/validators/index.ts | 6 | ||||
-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.js | 13 | ||||
-rw-r--r-- | server/middlewares/validators/remote/index.ts | 2 | ||||
-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.json | 19 | ||||
-rw-r--r-- | tslint.json | 3 | ||||
-rw-r--r-- | yarn.lock | 166 |
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": { |
@@ -1,14 +1,14 @@ | |||
1 | 'use strict' | ||
2 | |||
3 | // ----------- Node modules ----------- | 1 | // ----------- Node modules ----------- |
4 | const bodyParser = require('body-parser') | 2 | import bodyParser = require('body-parser') |
5 | const express = require('express') | 3 | import express = require('express') |
6 | const expressValidator = require('express-validator') | 4 | const expressValidator = require('express-validator') |
7 | const http = require('http') | 5 | import http = require('http') |
8 | const morgan = require('morgan') | 6 | import morgan = require('morgan') |
9 | const path = require('path') | 7 | import path = require('path') |
10 | const TrackerServer = require('bittorrent-tracker').Server | 8 | import bittorrentTracker = require('bittorrent-tracker') |
11 | const WebSocketServer = require('ws').Server | 9 | import { Server as WebSocketServer } from 'ws' |
10 | |||
11 | const TrackerServer = bittorrentTracker.Server | ||
12 | 12 | ||
13 | process.title = 'peertube' | 13 | process.title = 'peertube' |
14 | 14 | ||
@@ -16,70 +16,62 @@ process.title = 'peertube' | |||
16 | const app = express() | 16 | const app = express() |
17 | 17 | ||
18 | // ----------- Database ----------- | 18 | // ----------- Database ----------- |
19 | const 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) |
20 | const logger = require('./server/helpers/logger') | 20 | import { logger } from './server/helpers/logger' |
21 | import { API_VERSION, CONFIG } from './server/initializers/constants' | ||
21 | // Initialize database and models | 22 | // Initialize database and models |
22 | const db = require('./server/initializers/database') | 23 | const db = require('./server/initializers/database') |
23 | db.init(onDatabaseInitDone) | 24 | db.init(onDatabaseInitDone) |
24 | 25 | ||
25 | // ----------- Checker ----------- | 26 | // ----------- Checker ----------- |
26 | const checker = require('./server/initializers/checker') | 27 | import { checkMissedConfig, checkFFmpeg, checkConfig } from './server/initializers/checker' |
27 | 28 | ||
28 | const missed = checker.checkMissedConfig() | 29 | const missed = checkMissedConfig() |
29 | if (missed.length !== 0) { | 30 | if (missed.length !== 0) { |
30 | throw new Error('Miss some configurations keys : ' + missed) | 31 | throw new Error('Miss some configurations keys : ' + missed) |
31 | } | 32 | } |
32 | checker.checkFFmpeg(function (err) { | 33 | checkFFmpeg(function (err) { |
33 | if (err) { | 34 | if (err) { |
34 | throw err | 35 | throw err |
35 | } | 36 | } |
36 | }) | 37 | }) |
37 | 38 | ||
38 | const errorMessage = checker.checkConfig() | 39 | const errorMessage = checkConfig() |
39 | if (errorMessage !== null) { | 40 | if (errorMessage !== null) { |
40 | throw new Error(errorMessage) | 41 | throw new Error(errorMessage) |
41 | } | 42 | } |
42 | 43 | ||
43 | // ----------- PeerTube modules ----------- | 44 | // ----------- PeerTube modules ----------- |
44 | const customValidators = require('./server/helpers/custom-validators') | 45 | import { migrate, installApplication } from './server/initializers' |
45 | const friends = require('./server/lib/friends') | 46 | import { JobScheduler, activateSchedulers } from './server/lib' |
46 | const installer = require('./server/initializers/installer') | 47 | import * as customValidators from './server/helpers/custom-validators' |
47 | const migrator = require('./server/initializers/migrator') | 48 | import { apiRouter, clientsRouter, staticRouter } from './server/controllers' |
48 | const jobScheduler = require('./server/lib/jobs/job-scheduler') | ||
49 | const 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 |
56 | app.use(morgan('combined', { stream: logger.stream })) | 55 | // app.use(morgan('combined', { stream: logger.stream })) |
57 | // For body requests | 56 | // For body requests |
58 | app.use(bodyParser.json({ limit: '500kb' })) | 57 | app.use(bodyParser.json({ limit: '500kb' })) |
59 | app.use(bodyParser.urlencoded({ extended: false })) | 58 | app.use(bodyParser.urlencoded({ extended: false })) |
60 | // Validate some params for the API | 59 | // Validate some params for the API |
61 | app.use(expressValidator({ | 60 | app.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 |
75 | const apiRoute = '/api/' + constants.API_VERSION | 67 | const apiRoute = '/api/' + API_VERSION |
76 | app.use(apiRoute, routes.api) | 68 | app.use(apiRoute, apiRouter) |
77 | 69 | ||
78 | // Client files | 70 | // Client files |
79 | app.use('/', routes.client) | 71 | app.use('/', clientsRouter) |
80 | 72 | ||
81 | // Static files | 73 | // Static files |
82 | app.use('/', routes.static) | 74 | app.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) |
85 | app.use('/*', function (req, res, next) { | 77 | app.use('/*', function (req, res, next) { |
@@ -104,7 +96,7 @@ trackerServer.on('warning', function (err) { | |||
104 | }) | 96 | }) |
105 | 97 | ||
106 | const server = http.createServer(app) | 98 | const server = http.createServer(app) |
107 | const wss = new WebSocketServer({server: server, path: '/tracker/socket'}) | 99 | const wss = new WebSocketServer({ server: server, path: '/tracker/socket' }) |
108 | wss.on('connection', function (ws) { | 100 | wss.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 |
115 | app.use(function (req, res, next) { | 107 | app.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 | ||
128 | function onDatabaseInitDone () { | 120 | function 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 | |||
154 | module.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' | 1 | import express = require('express') |
2 | 2 | ||
3 | const express = require('express') | 3 | import { CONFIG } from '../../initializers'; |
4 | 4 | import { logger } from '../../helpers' | |
5 | const constants = require('../../initializers/constants') | ||
6 | const db = require('../../initializers/database') | 5 | const db = require('../../initializers/database') |
7 | const logger = require('../../helpers/logger') | ||
8 | 6 | ||
9 | const router = express.Router() | 7 | const clientsRouter = express.Router() |
10 | 8 | ||
11 | router.get('/local', getLocalClient) | 9 | clientsRouter.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 |
14 | function getLocalClient (req, res, next) { | 12 | function 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 | ||
41 | module.exports = router | 39 | export { |
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 | |||
3 | const express = require('express') | ||
4 | |||
5 | const constants = require('../../initializers/constants') | ||
6 | |||
7 | const router = express.Router() | ||
8 | |||
9 | router.get('/', getConfig) | ||
10 | |||
11 | // Get the client credentials for the PeerTube front end | ||
12 | function getConfig (req, res, next) { | ||
13 | res.json({ | ||
14 | signup: { | ||
15 | enabled: constants.CONFIG.SIGNUP.ENABLED | ||
16 | } | ||
17 | }) | ||
18 | } | ||
19 | |||
20 | // --------------------------------------------------------------------------- | ||
21 | |||
22 | module.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 @@ | |||
1 | import express = require('express') | ||
2 | |||
3 | import { CONFIG } from '../../initializers'; | ||
4 | |||
5 | const configRouter = express.Router() | ||
6 | |||
7 | configRouter.get('/', getConfig) | ||
8 | |||
9 | // Get the client credentials for the PeerTube front end | ||
10 | function getConfig (req, res, next) { | ||
11 | res.json({ | ||
12 | signup: { | ||
13 | enabled: CONFIG.SIGNUP.ENABLED | ||
14 | } | ||
15 | }) | ||
16 | } | ||
17 | |||
18 | // --------------------------------------------------------------------------- | ||
19 | |||
20 | export { | ||
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 | |||
3 | const express = require('express') | ||
4 | |||
5 | const utils = require('../../helpers/utils') | ||
6 | |||
7 | const router = express.Router() | ||
8 | |||
9 | const clientsController = require('./clients') | ||
10 | const configController = require('./config') | ||
11 | const podsController = require('./pods') | ||
12 | const remoteController = require('./remote') | ||
13 | const requestsController = require('./requests') | ||
14 | const usersController = require('./users') | ||
15 | const videosController = require('./videos') | ||
16 | |||
17 | router.use('/clients', clientsController) | ||
18 | router.use('/config', configController) | ||
19 | router.use('/pods', podsController) | ||
20 | router.use('/remote', remoteController) | ||
21 | router.use('/requests', requestsController) | ||
22 | router.use('/users', usersController) | ||
23 | router.use('/videos', videosController) | ||
24 | router.use('/ping', pong) | ||
25 | router.use('/*', utils.badRequest) | ||
26 | |||
27 | // --------------------------------------------------------------------------- | ||
28 | |||
29 | module.exports = router | ||
30 | |||
31 | // --------------------------------------------------------------------------- | ||
32 | |||
33 | function 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 @@ | |||
1 | import express = require('express') | ||
2 | |||
3 | import { badRequest } from '../../helpers' | ||
4 | |||
5 | import { clientsRouter } from './clients' | ||
6 | import { configRouter } from './config' | ||
7 | import { podsRouter } from './pods' | ||
8 | import { remoteRouter } from './remote' | ||
9 | import { requestsRouter } from './requests' | ||
10 | import { usersRouter } from './users' | ||
11 | import { videosRouter } from './videos' | ||
12 | |||
13 | const apiRouter = express.Router() | ||
14 | |||
15 | apiRouter.use('/clients', clientsRouter) | ||
16 | apiRouter.use('/config', configRouter) | ||
17 | apiRouter.use('/pods', podsRouter) | ||
18 | apiRouter.use('/remote', remoteRouter) | ||
19 | apiRouter.use('/requests', requestsRouter) | ||
20 | apiRouter.use('/users', usersRouter) | ||
21 | apiRouter.use('/videos', videosRouter) | ||
22 | apiRouter.use('/ping', pong) | ||
23 | apiRouter.use('/*', badRequest) | ||
24 | |||
25 | // --------------------------------------------------------------------------- | ||
26 | |||
27 | export { apiRouter } | ||
28 | |||
29 | // --------------------------------------------------------------------------- | ||
30 | |||
31 | function 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 | |||
3 | const express = require('express') | ||
4 | const waterfall = require('async/waterfall') | ||
5 | |||
6 | const db = require('../../initializers/database') | ||
7 | const constants = require('../../initializers/constants') | ||
8 | const logger = require('../../helpers/logger') | ||
9 | const peertubeCrypto = require('../../helpers/peertube-crypto') | ||
10 | const utils = require('../../helpers/utils') | ||
11 | const friends = require('../../lib/friends') | ||
12 | const middlewares = require('../../middlewares') | ||
13 | const admin = middlewares.admin | ||
14 | const oAuth = middlewares.oauth | ||
15 | const podsMiddleware = middlewares.pods | ||
16 | const validators = middlewares.validators.pods | ||
17 | |||
18 | const router = express.Router() | ||
19 | |||
20 | router.get('/', listPods) | ||
21 | router.post('/', | ||
22 | podsMiddleware.setBodyHostPort, // We need to modify the host before running the validator! | ||
23 | validators.podsAdd, | ||
24 | addPods | ||
25 | ) | ||
26 | router.post('/makefriends', | ||
27 | oAuth.authenticate, | ||
28 | admin.ensureIsAdmin, | ||
29 | validators.makeFriends, | ||
30 | podsMiddleware.setBodyHostsPort, | ||
31 | makeFriends | ||
32 | ) | ||
33 | router.get('/quitfriends', | ||
34 | oAuth.authenticate, | ||
35 | admin.ensureIsAdmin, | ||
36 | quitFriends | ||
37 | ) | ||
38 | |||
39 | // --------------------------------------------------------------------------- | ||
40 | |||
41 | module.exports = router | ||
42 | |||
43 | // --------------------------------------------------------------------------- | ||
44 | |||
45 | function 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 | |||
80 | function 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 | |||
88 | function 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 | |||
103 | function 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 @@ | |||
1 | import express = require('express') | ||
2 | import { waterfall } from 'async' | ||
3 | |||
4 | const db = require('../../initializers/database') | ||
5 | import { CONFIG } from '../../initializers' | ||
6 | import { | ||
7 | logger, | ||
8 | getMyPublicCert, | ||
9 | getFormatedObjects | ||
10 | } from '../../helpers' | ||
11 | import { | ||
12 | sendOwnedVideosToPod, | ||
13 | makeFriends, | ||
14 | quitFriends | ||
15 | } from '../../lib' | ||
16 | import { | ||
17 | podsAddValidator, | ||
18 | authenticate, | ||
19 | ensureIsAdmin, | ||
20 | makeFriendsValidator, | ||
21 | setBodyHostPort, | ||
22 | setBodyHostsPort | ||
23 | } from '../../middlewares' | ||
24 | |||
25 | const podsRouter = express.Router() | ||
26 | |||
27 | podsRouter.get('/', listPods) | ||
28 | podsRouter.post('/', | ||
29 | setBodyHostPort, // We need to modify the host before running the validator! | ||
30 | podsAddValidator, | ||
31 | addPods | ||
32 | ) | ||
33 | podsRouter.post('/makefriends', | ||
34 | authenticate, | ||
35 | ensureIsAdmin, | ||
36 | makeFriendsValidator, | ||
37 | setBodyHostsPort, | ||
38 | makeFriends | ||
39 | ) | ||
40 | podsRouter.get('/quitfriends', | ||
41 | authenticate, | ||
42 | ensureIsAdmin, | ||
43 | quitFriends | ||
44 | ) | ||
45 | |||
46 | // --------------------------------------------------------------------------- | ||
47 | |||
48 | export { | ||
49 | podsRouter | ||
50 | } | ||
51 | |||
52 | // --------------------------------------------------------------------------- | ||
53 | |||
54 | function 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 | |||
89 | function 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 | |||
97 | function 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 | |||
112 | function 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 | |||
3 | const express = require('express') | ||
4 | |||
5 | const utils = require('../../../helpers/utils') | ||
6 | |||
7 | const router = express.Router() | ||
8 | |||
9 | const podsRemoteController = require('./pods') | ||
10 | const videosRemoteController = require('./videos') | ||
11 | |||
12 | router.use('/pods', podsRemoteController) | ||
13 | router.use('/videos', videosRemoteController) | ||
14 | router.use('/*', utils.badRequest) | ||
15 | |||
16 | // --------------------------------------------------------------------------- | ||
17 | |||
18 | module.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 @@ | |||
1 | import express = require('express') | ||
2 | |||
3 | import { badRequest } from '../../../helpers' | ||
4 | |||
5 | import { remotePodsRouter } from './pods' | ||
6 | import { remoteVideosRouter } from './videos' | ||
7 | |||
8 | const remoteRouter = express.Router() | ||
9 | |||
10 | remoteRouter.use('/pods', remotePodsRouter) | ||
11 | remoteRouter.use('/videos', remoteVideosRouter) | ||
12 | remoteRouter.use('/*', badRequest) | ||
13 | |||
14 | // --------------------------------------------------------------------------- | ||
15 | |||
16 | export { | ||
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' | 1 | import express = require('express') |
2 | 2 | import { waterfall } from 'async/waterfall' | |
3 | const express = require('express') | ||
4 | const waterfall = require('async/waterfall') | ||
5 | 3 | ||
6 | const db = require('../../../initializers/database') | 4 | const db = require('../../../initializers/database') |
7 | const middlewares = require('../../../middlewares') | 5 | import { checkSignature, signatureValidator } from '../../../middlewares' |
8 | const checkSignature = middlewares.secure.checkSignature | ||
9 | const signatureValidator = middlewares.validators.remote.signature | ||
10 | 6 | ||
11 | const router = express.Router() | 7 | const remotePodsRouter = express.Router() |
12 | 8 | ||
13 | // Post because this is a secured request | 9 | // Post because this is a secured request |
14 | router.post('/remove', | 10 | remotePodsRouter.post('/remove', |
15 | signatureValidator.signature, | 11 | signatureValidator, |
16 | checkSignature, | 12 | checkSignature, |
17 | removePods | 13 | removePods |
18 | ) | 14 | ) |
19 | 15 | ||
20 | // --------------------------------------------------------------------------- | 16 | // --------------------------------------------------------------------------- |
21 | 17 | ||
22 | module.exports = router | 18 | export { |
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' | 1 | import express = require('express') |
2 | 2 | import { eachSeries, waterfall } from 'async' | |
3 | const eachSeries = require('async/eachSeries') | ||
4 | const express = require('express') | ||
5 | const waterfall = require('async/waterfall') | ||
6 | 3 | ||
7 | const db = require('../../../initializers/database') | 4 | const db = require('../../../initializers/database') |
8 | const constants = require('../../../initializers/constants') | 5 | import { |
9 | const middlewares = require('../../../middlewares') | 6 | REQUEST_ENDPOINT_ACTIONS, |
10 | const secureMiddleware = middlewares.secure | 7 | REQUEST_ENDPOINTS, |
11 | const videosValidators = middlewares.validators.remote.videos | 8 | REQUEST_VIDEO_EVENT_TYPES, |
12 | const signatureValidators = middlewares.validators.remote.signature | 9 | REQUEST_VIDEO_QADU_TYPES |
13 | const logger = require('../../../helpers/logger') | 10 | } from '../../../initializers' |
14 | const friends = require('../../../lib/friends') | 11 | import { |
15 | const databaseUtils = require('../../../helpers/database-utils') | 12 | checkSignature, |
16 | 13 | signatureValidator, | |
17 | const ENDPOINT_ACTIONS = constants.REQUEST_ENDPOINT_ACTIONS[constants.REQUEST_ENDPOINTS.VIDEOS] | 14 | remoteVideosValidator, |
15 | remoteQaduVideosValidator, | ||
16 | remoteEventsVideosValidator | ||
17 | } from '../../../middlewares' | ||
18 | import { | ||
19 | logger, | ||
20 | commitTransaction, | ||
21 | retryTransactionWrapper, | ||
22 | rollbackTransaction, | ||
23 | startSerializableTransaction | ||
24 | } from '../../../helpers' | ||
25 | import { quickAndDirtyUpdatesVideoToFriends } from '../../../lib' | ||
26 | |||
27 | const 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 |
20 | const functionsHash = {} | 30 | const functionsHash = {} |
@@ -23,32 +33,34 @@ functionsHash[ENDPOINT_ACTIONS.UPDATE] = updateRemoteVideoRetryWrapper | |||
23 | functionsHash[ENDPOINT_ACTIONS.REMOVE] = removeRemoteVideo | 33 | functionsHash[ENDPOINT_ACTIONS.REMOVE] = removeRemoteVideo |
24 | functionsHash[ENDPOINT_ACTIONS.REPORT_ABUSE] = reportAbuseRemoteVideo | 34 | functionsHash[ENDPOINT_ACTIONS.REPORT_ABUSE] = reportAbuseRemoteVideo |
25 | 35 | ||
26 | const router = express.Router() | 36 | const remoteVideosRouter = express.Router() |
27 | 37 | ||
28 | router.post('/', | 38 | remoteVideosRouter.post('/', |
29 | signatureValidators.signature, | 39 | signatureValidator, |
30 | secureMiddleware.checkSignature, | 40 | checkSignature, |
31 | videosValidators.remoteVideos, | 41 | remoteVideosValidator, |
32 | remoteVideos | 42 | remoteVideos |
33 | ) | 43 | ) |
34 | 44 | ||
35 | router.post('/qadu', | 45 | remoteVideosRouter.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 | ||
42 | router.post('/events', | 52 | remoteVideosRouter.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 | ||
51 | module.exports = router | 61 | export { |
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 | ||
119 | function processVideosEvents (eventData, fromPod, finalCallback) { | 131 | function 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 | ||
198 | function quickAndDirtyUpdateVideo (videoData, fromPod, finalCallback) { | 210 | function 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 | ||
255 | function addRemoteVideo (videoToCreateData, fromPod, finalCallback) { | 267 | function 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 | ||
372 | function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) { | 384 | function 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' | 1 | import express = require('express') |
2 | import { parallel } from 'async' | ||
2 | 3 | ||
3 | const express = require('express') | 4 | import { |
4 | const parallel = require('async/parallel') | 5 | getRequestScheduler, |
6 | getRequestVideoQaduScheduler, | ||
7 | getRequestVideoEventScheduler | ||
8 | } from '../../lib' | ||
9 | import { authenticate, ensureIsAdmin } from '../../middlewares' | ||
5 | 10 | ||
6 | const friends = require('../../lib/friends') | 11 | const requestsRouter = express.Router() |
7 | const middlewares = require('../../middlewares') | ||
8 | const admin = middlewares.admin | ||
9 | const oAuth = middlewares.oauth | ||
10 | 12 | ||
11 | const router = express.Router() | 13 | requestsRouter.get('/stats', |
12 | 14 | authenticate, | |
13 | router.get('/stats', | 15 | ensureIsAdmin, |
14 | oAuth.authenticate, | ||
15 | admin.ensureIsAdmin, | ||
16 | getStatsRequests | 16 | getStatsRequests |
17 | ) | 17 | ) |
18 | 18 | ||
19 | // --------------------------------------------------------------------------- | 19 | // --------------------------------------------------------------------------- |
20 | 20 | ||
21 | module.exports = router | 21 | export { |
22 | requestsRouter | ||
23 | } | ||
22 | 24 | ||
23 | // --------------------------------------------------------------------------- | 25 | // --------------------------------------------------------------------------- |
24 | 26 | ||
25 | function getStatsRequests (req, res, next) { | 27 | function 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' | 1 | import express = require('express') |
2 | import { waterfall } from 'async' | ||
2 | 3 | ||
3 | const express = require('express') | ||
4 | const waterfall = require('async/waterfall') | ||
5 | |||
6 | const constants = require('../../initializers/constants') | ||
7 | const db = require('../../initializers/database') | 4 | const db = require('../../initializers/database') |
8 | const logger = require('../../helpers/logger') | 5 | import { CONFIG, USER_ROLES } from '../../initializers' |
9 | const utils = require('../../helpers/utils') | 6 | import { logger, getFormatedObjects } from '../../helpers' |
10 | const middlewares = require('../../middlewares') | 7 | import { |
11 | const admin = middlewares.admin | 8 | authenticate, |
12 | const oAuth = middlewares.oauth | 9 | ensureIsAdmin, |
13 | const pagination = middlewares.pagination | 10 | usersAddValidator, |
14 | const sort = middlewares.sort | 11 | usersUpdateValidator, |
15 | const validatorsPagination = middlewares.validators.pagination | 12 | usersRemoveValidator, |
16 | const validatorsSort = middlewares.validators.sort | 13 | usersVideoRatingValidator, |
17 | const validatorsUsers = middlewares.validators.users | 14 | paginationValidator, |
18 | 15 | setPagination, | |
19 | const router = express.Router() | 16 | usersSortValidator, |
20 | 17 | setUsersSort, | |
21 | router.get('/me', | 18 | token |
22 | oAuth.authenticate, | 19 | } from '../../middlewares' |
20 | |||
21 | const usersRouter = express.Router() | ||
22 | |||
23 | usersRouter.get('/me', | ||
24 | authenticate, | ||
23 | getUserInformation | 25 | getUserInformation |
24 | ) | 26 | ) |
25 | 27 | ||
26 | router.get('/me/videos/:videoId/rating', | 28 | usersRouter.get('/me/videos/:videoId/rating', |
27 | oAuth.authenticate, | 29 | authenticate, |
28 | validatorsUsers.usersVideoRating, | 30 | usersVideoRatingValidator, |
29 | getUserVideoRating | 31 | getUserVideoRating |
30 | ) | 32 | ) |
31 | 33 | ||
32 | router.get('/', | 34 | usersRouter.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 | ||
40 | router.post('/', | 42 | usersRouter.post('/', |
41 | oAuth.authenticate, | 43 | authenticate, |
42 | admin.ensureIsAdmin, | 44 | ensureIsAdmin, |
43 | validatorsUsers.usersAdd, | 45 | usersAddValidator, |
44 | createUser | 46 | createUser |
45 | ) | 47 | ) |
46 | 48 | ||
47 | router.post('/register', | 49 | usersRouter.post('/register', |
48 | ensureRegistrationEnabled, | 50 | ensureRegistrationEnabled, |
49 | validatorsUsers.usersAdd, | 51 | usersAddValidator, |
50 | createUser | 52 | createUser |
51 | ) | 53 | ) |
52 | 54 | ||
53 | router.put('/:id', | 55 | usersRouter.put('/:id', |
54 | oAuth.authenticate, | 56 | authenticate, |
55 | validatorsUsers.usersUpdate, | 57 | usersUpdateValidator, |
56 | updateUser | 58 | updateUser |
57 | ) | 59 | ) |
58 | 60 | ||
59 | router.delete('/:id', | 61 | usersRouter.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 | ||
66 | router.post('/token', oAuth.token, success) | 68 | usersRouter.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 | ||
71 | module.exports = router | 73 | export { |
74 | usersRouter | ||
75 | } | ||
72 | 76 | ||
73 | // --------------------------------------------------------------------------- | 77 | // --------------------------------------------------------------------------- |
74 | 78 | ||
75 | function ensureRegistrationEnabled (req, res, next) { | 79 | function 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' | 1 | import express = require('express') |
2 | 2 | import { waterfall } from 'async' | |
3 | const express = require('express') | ||
4 | const waterfall = require('async/waterfall') | ||
5 | 3 | ||
6 | const db = require('../../../initializers/database') | 4 | const db = require('../../../initializers/database') |
7 | const logger = require('../../../helpers/logger') | 5 | import friends = require('../../../lib/friends') |
8 | const friends = require('../../../lib/friends') | 6 | import { |
9 | const middlewares = require('../../../middlewares') | 7 | logger, |
10 | const admin = middlewares.admin | 8 | getFormatedObjects, |
11 | const oAuth = middlewares.oauth | 9 | retryTransactionWrapper, |
12 | const pagination = middlewares.pagination | 10 | startSerializableTransaction, |
13 | const validators = middlewares.validators | 11 | commitTransaction, |
14 | const validatorsPagination = validators.pagination | 12 | rollbackTransaction |
15 | const validatorsSort = validators.sort | 13 | } from '../../../helpers' |
16 | const validatorsVideos = validators.videos | 14 | import { |
17 | const sort = middlewares.sort | 15 | authenticate, |
18 | const databaseUtils = require('../../../helpers/database-utils') | 16 | ensureIsAdmin, |
19 | const utils = require('../../../helpers/utils') | 17 | paginationValidator, |
20 | 18 | videoAbuseReportValidator, | |
21 | const router = express.Router() | 19 | videoAbusesSortValidator, |
22 | 20 | setVideoAbusesSort, | |
23 | router.get('/abuse', | 21 | setPagination |
24 | oAuth.authenticate, | 22 | } from '../../../middlewares' |
25 | admin.ensureIsAdmin, | 23 | |
26 | validatorsPagination.pagination, | 24 | const abuseVideoRouter = express.Router() |
27 | validatorsSort.videoAbusesSort, | 25 | |
28 | sort.setVideoAbusesSort, | 26 | abuseVideoRouter.get('/abuse', |
29 | pagination.setPagination, | 27 | authenticate, |
28 | ensureIsAdmin, | ||
29 | paginationValidator, | ||
30 | videoAbusesSortValidator, | ||
31 | setVideoAbusesSort, | ||
32 | setPagination, | ||
30 | listVideoAbuses | 33 | listVideoAbuses |
31 | ) | 34 | ) |
32 | router.post('/:id/abuse', | 35 | abuseVideoRouter.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 | ||
40 | module.exports = router | 43 | export { |
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' | 1 | import express = require('express') |
2 | |||
3 | const express = require('express') | ||
4 | 2 | ||
5 | const db = require('../../../initializers/database') | 3 | const db = require('../../../initializers/database') |
6 | const logger = require('../../../helpers/logger') | 4 | import { logger } from '../../../helpers' |
7 | const middlewares = require('../../../middlewares') | 5 | import { |
8 | const admin = middlewares.admin | 6 | authenticate, |
9 | const oAuth = middlewares.oauth | 7 | ensureIsAdmin, |
10 | const validators = middlewares.validators | 8 | videosBlacklistValidator |
11 | const validatorsVideos = validators.videos | 9 | } from '../../../middlewares' |
12 | 10 | ||
13 | const router = express.Router() | 11 | const blacklistRouter = express.Router() |
14 | 12 | ||
15 | router.post('/:id/blacklist', | 13 | blacklistRouter.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 | ||
24 | module.exports = router | 22 | export { |
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' | 1 | import express = require('express') |
2 | import fs = require('fs') | ||
3 | import multer = require('multer') | ||
4 | import path = require('path') | ||
5 | import { waterfall } from 'async' | ||
2 | 6 | ||
3 | const express = require('express') | ||
4 | const fs = require('fs') | ||
5 | const multer = require('multer') | ||
6 | const path = require('path') | ||
7 | const waterfall = require('async/waterfall') | ||
8 | |||
9 | const constants = require('../../../initializers/constants') | ||
10 | const db = require('../../../initializers/database') | 7 | const db = require('../../../initializers/database') |
11 | const logger = require('../../../helpers/logger') | 8 | import { |
12 | const friends = require('../../../lib/friends') | 9 | CONFIG, |
13 | const middlewares = require('../../../middlewares') | 10 | REQUEST_VIDEO_QADU_TYPES, |
14 | const oAuth = middlewares.oauth | 11 | REQUEST_VIDEO_EVENT_TYPES, |
15 | const pagination = middlewares.pagination | 12 | VIDEO_CATEGORIES, |
16 | const validators = middlewares.validators | 13 | VIDEO_LICENCES, |
17 | const validatorsPagination = validators.pagination | 14 | VIDEO_LANGUAGES |
18 | const validatorsSort = validators.sort | 15 | } from '../../../initializers' |
19 | const validatorsVideos = validators.videos | 16 | import { |
20 | const search = middlewares.search | 17 | addEventToRemoteVideo, |
21 | const sort = middlewares.sort | 18 | quickAndDirtyUpdateVideoToFriends, |
22 | const databaseUtils = require('../../../helpers/database-utils') | 19 | addVideoToFriends, |
23 | const utils = require('../../../helpers/utils') | 20 | updateVideoToFriends |
24 | 21 | } from '../../../lib' | |
25 | const abuseController = require('./abuse') | 22 | import { |
26 | const blacklistController = require('./blacklist') | 23 | authenticate, |
27 | const rateController = require('./rate') | 24 | paginationValidator, |
28 | 25 | videosSortValidator, | |
29 | const router = express.Router() | 26 | setVideosSort, |
27 | setPagination, | ||
28 | setVideosSearch, | ||
29 | videosUpdateValidator, | ||
30 | videosSearchValidator, | ||
31 | videosAddValidator, | ||
32 | videosGetValidator, | ||
33 | videosRemoveValidator | ||
34 | } from '../../../middlewares' | ||
35 | import { | ||
36 | logger, | ||
37 | commitTransaction, | ||
38 | retryTransactionWrapper, | ||
39 | rollbackTransaction, | ||
40 | startSerializableTransaction, | ||
41 | generateRandomString, | ||
42 | getFormatedObjects | ||
43 | } from '../../../helpers' | ||
44 | |||
45 | import { abuseVideoRouter } from './abuse' | ||
46 | import { blacklistRouter } from './blacklist' | ||
47 | import { rateVideoRouter } from './rate' | ||
48 | |||
49 | const videosRouter = express.Router() | ||
30 | 50 | ||
31 | // multer configuration | 51 | // multer configuration |
32 | const storage = multer.diskStorage({ | 52 | const 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 | ||
49 | const reqFiles = multer({ storage: storage }).fields([{ name: 'videofile', maxCount: 1 }]) | 69 | const reqFiles = multer({ storage: storage }).fields([{ name: 'videofile', maxCount: 1 }]) |
50 | 70 | ||
51 | router.use('/', abuseController) | 71 | videosRouter.use('/', abuseVideoRouter) |
52 | router.use('/', blacklistController) | 72 | videosRouter.use('/', blacklistRouter) |
53 | router.use('/', rateController) | 73 | videosRouter.use('/', rateVideoRouter) |
54 | 74 | ||
55 | router.get('/categories', listVideoCategories) | 75 | videosRouter.get('/categories', listVideoCategories) |
56 | router.get('/licences', listVideoLicences) | 76 | videosRouter.get('/licences', listVideoLicences) |
57 | router.get('/languages', listVideoLanguages) | 77 | videosRouter.get('/languages', listVideoLanguages) |
58 | 78 | ||
59 | router.get('/', | 79 | videosRouter.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 | ) |
66 | router.put('/:id', | 86 | videosRouter.put('/:id', |
67 | oAuth.authenticate, | 87 | authenticate, |
68 | reqFiles, | 88 | reqFiles, |
69 | validatorsVideos.videosUpdate, | 89 | videosUpdateValidator, |
70 | updateVideoRetryWrapper | 90 | updateVideoRetryWrapper |
71 | ) | 91 | ) |
72 | router.post('/', | 92 | videosRouter.post('/', |
73 | oAuth.authenticate, | 93 | authenticate, |
74 | reqFiles, | 94 | reqFiles, |
75 | validatorsVideos.videosAdd, | 95 | videosAddValidator, |
76 | addVideoRetryWrapper | 96 | addVideoRetryWrapper |
77 | ) | 97 | ) |
78 | router.get('/:id', | 98 | videosRouter.get('/:id', |
79 | validatorsVideos.videosGet, | 99 | videosGetValidator, |
80 | getVideo | 100 | getVideo |
81 | ) | 101 | ) |
82 | 102 | ||
83 | router.delete('/:id', | 103 | videosRouter.delete('/:id', |
84 | oAuth.authenticate, | 104 | authenticate, |
85 | validatorsVideos.videosRemove, | 105 | videosRemoveValidator, |
86 | removeVideo | 106 | removeVideo |
87 | ) | 107 | ) |
88 | 108 | ||
89 | router.get('/search/:value', | 109 | videosRouter.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 | ||
101 | module.exports = router | 121 | export { |
122 | videosRouter | ||
123 | } | ||
102 | 124 | ||
103 | // --------------------------------------------------------------------------- | 125 | // --------------------------------------------------------------------------- |
104 | 126 | ||
105 | function listVideoCategories (req, res, next) { | 127 | function listVideoCategories (req, res, next) { |
106 | res.json(constants.VIDEO_CATEGORIES) | 128 | res.json(VIDEO_CATEGORIES) |
107 | } | 129 | } |
108 | 130 | ||
109 | function listVideoLicences (req, res, next) { | 131 | function listVideoLicences (req, res, next) { |
110 | res.json(constants.VIDEO_LICENCES) | 132 | res.json(VIDEO_LICENCES) |
111 | } | 133 | } |
112 | 134 | ||
113 | function listVideoLanguages (req, res, next) { | 135 | function 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' | 1 | import express = require('express') |
2 | import { waterfall } from 'async' | ||
2 | 3 | ||
3 | const express = require('express') | ||
4 | const waterfall = require('async/waterfall') | ||
5 | |||
6 | const constants = require('../../../initializers/constants') | ||
7 | const db = require('../../../initializers/database') | 4 | const db = require('../../../initializers/database') |
8 | const logger = require('../../../helpers/logger') | 5 | import { |
9 | const friends = require('../../../lib/friends') | 6 | logger, |
10 | const middlewares = require('../../../middlewares') | 7 | retryTransactionWrapper, |
11 | const oAuth = middlewares.oauth | 8 | startSerializableTransaction, |
12 | const validators = middlewares.validators | 9 | commitTransaction, |
13 | const validatorsVideos = validators.videos | 10 | rollbackTransaction |
14 | const databaseUtils = require('../../../helpers/database-utils') | 11 | } from '../../../helpers' |
15 | 12 | import { | |
16 | const router = express.Router() | 13 | VIDEO_RATE_TYPES, |
17 | 14 | REQUEST_VIDEO_EVENT_TYPES, | |
18 | router.put('/:id/rate', | 15 | REQUEST_VIDEO_QADU_TYPES |
19 | oAuth.authenticate, | 16 | } from '../../../initializers' |
20 | validatorsVideos.videoRate, | 17 | import { |
18 | addEventsToRemoteVideo, | ||
19 | quickAndDirtyUpdatesVideoToFriends | ||
20 | } from '../../../lib' | ||
21 | import { | ||
22 | authenticate, | ||
23 | videoRateValidator | ||
24 | } from '../../../middlewares' | ||
25 | |||
26 | const rateVideoRouter = express.Router() | ||
27 | |||
28 | rateVideoRouter.put('/:id/rate', | ||
29 | authenticate, | ||
30 | videoRateValidator, | ||
21 | rateVideoRetryWrapper | 31 | rateVideoRetryWrapper |
22 | ) | 32 | ) |
23 | 33 | ||
24 | // --------------------------------------------------------------------------- | 34 | // --------------------------------------------------------------------------- |
25 | 35 | ||
26 | module.exports = router | 36 | export { |
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' | 1 | import { parallel } from 'async' |
2 | import express = require('express') | ||
3 | import fs = require('fs') | ||
4 | import { join } from 'path' | ||
5 | import expressValidator = require('express-validator') | ||
6 | // TODO: use .validator when express-validator typing will have validator field | ||
7 | const validator = expressValidator['validator'] | ||
2 | 8 | ||
3 | const parallel = require('async/parallel') | ||
4 | const express = require('express') | ||
5 | const fs = require('fs') | ||
6 | const path = require('path') | ||
7 | const validator = require('express-validator').validator | ||
8 | |||
9 | const constants = require('../initializers/constants') | ||
10 | const db = require('../initializers/database') | 9 | const db = require('../initializers/database') |
10 | import { | ||
11 | CONFIG, | ||
12 | REMOTE_SCHEME, | ||
13 | STATIC_PATHS, | ||
14 | STATIC_MAX_AGE | ||
15 | } from '../initializers' | ||
11 | 16 | ||
12 | const router = express.Router() | 17 | const clientsRouter = express.Router() |
13 | 18 | ||
19 | // TODO: move to constants | ||
14 | const opengraphComment = '<!-- opengraph tags -->' | 20 | const opengraphComment = '<!-- opengraph tags -->' |
15 | const distPath = path.join(__dirname, '..', '..', 'client/dist') | 21 | const distPath = join(__dirname, '..', '..', 'client/dist') |
16 | const embedPath = path.join(distPath, 'standalone/videos/embed.html') | 22 | const embedPath = join(distPath, 'standalone/videos/embed.html') |
17 | const indexPath = path.join(distPath, 'index.html') | 23 | const 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 |
21 | router.use('/videos/watch/:id', generateWatchHtmlPage) | 27 | clientsRouter.use('/videos/watch/:id', generateWatchHtmlPage) |
22 | 28 | ||
23 | router.use('/videos/embed', function (req, res, next) { | 29 | clientsRouter.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 |
28 | router.use('/client', express.static(distPath, { maxAge: constants.STATIC_MAX_AGE })) | 34 | clientsRouter.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 |
31 | router.use('/client/*', function (req, res, next) { | 37 | clientsRouter.use('/client/*', function (req, res, next) { |
32 | res.sendStatus(404) | 38 | res.sendStatus(404) |
33 | }) | 39 | }) |
34 | 40 | ||
35 | // --------------------------------------------------------------------------- | 41 | // --------------------------------------------------------------------------- |
36 | 42 | ||
37 | module.exports = router | 43 | export { |
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 | |||
3 | const apiController = require('./api/') | ||
4 | const clientController = require('./client') | ||
5 | const staticController = require('./static') | ||
6 | |||
7 | module.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 @@ | |||
1 | export * from './static'; | ||
2 | export * from './client'; | ||
3 | export * 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 | |||
3 | const express = require('express') | ||
4 | const cors = require('cors') | ||
5 | |||
6 | const constants = require('../initializers/constants') | ||
7 | |||
8 | const router = express.Router() | ||
9 | |||
10 | /* | ||
11 | Cors is very important to let other pods access torrent and video files | ||
12 | */ | ||
13 | |||
14 | const torrentsPhysicalPath = constants.CONFIG.STORAGE.TORRENTS_DIR | ||
15 | router.use( | ||
16 | constants.STATIC_PATHS.TORRENTS, | ||
17 | cors(), | ||
18 | express.static(torrentsPhysicalPath, { maxAge: constants.STATIC_MAX_AGE }) | ||
19 | ) | ||
20 | |||
21 | // Videos path for webseeding | ||
22 | const videosPhysicalPath = constants.CONFIG.STORAGE.VIDEOS_DIR | ||
23 | router.use( | ||
24 | constants.STATIC_PATHS.WEBSEED, | ||
25 | cors(), | ||
26 | express.static(videosPhysicalPath, { maxAge: constants.STATIC_MAX_AGE }) | ||
27 | ) | ||
28 | |||
29 | // Thumbnails path for express | ||
30 | const thumbnailsPhysicalPath = constants.CONFIG.STORAGE.THUMBNAILS_DIR | ||
31 | router.use( | ||
32 | constants.STATIC_PATHS.THUMBNAILS, | ||
33 | express.static(thumbnailsPhysicalPath, { maxAge: constants.STATIC_MAX_AGE }) | ||
34 | ) | ||
35 | |||
36 | // Video previews path for express | ||
37 | const previewsPhysicalPath = constants.CONFIG.STORAGE.PREVIEWS_DIR | ||
38 | router.use( | ||
39 | constants.STATIC_PATHS.PREVIEWS, | ||
40 | express.static(previewsPhysicalPath, { maxAge: constants.STATIC_MAX_AGE }) | ||
41 | ) | ||
42 | |||
43 | // --------------------------------------------------------------------------- | ||
44 | |||
45 | module.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 @@ | |||
1 | import express = require('express') | ||
2 | import cors = require('cors') | ||
3 | |||
4 | import { | ||
5 | CONFIG, | ||
6 | STATIC_MAX_AGE, | ||
7 | STATIC_PATHS | ||
8 | } from '../initializers' | ||
9 | |||
10 | const staticRouter = express.Router() | ||
11 | |||
12 | /* | ||
13 | Cors is very important to let other pods access torrent and video files | ||
14 | */ | ||
15 | |||
16 | const torrentsPhysicalPath = CONFIG.STORAGE.TORRENTS_DIR | ||
17 | staticRouter.use( | ||
18 | STATIC_PATHS.TORRENTS, | ||
19 | cors(), | ||
20 | express.static(torrentsPhysicalPath, { maxAge: STATIC_MAX_AGE }) | ||
21 | ) | ||
22 | |||
23 | // Videos path for webseeding | ||
24 | const videosPhysicalPath = CONFIG.STORAGE.VIDEOS_DIR | ||
25 | staticRouter.use( | ||
26 | STATIC_PATHS.WEBSEED, | ||
27 | cors(), | ||
28 | express.static(videosPhysicalPath, { maxAge: STATIC_MAX_AGE }) | ||
29 | ) | ||
30 | |||
31 | // Thumbnails path for express | ||
32 | const thumbnailsPhysicalPath = CONFIG.STORAGE.THUMBNAILS_DIR | ||
33 | staticRouter.use( | ||
34 | STATIC_PATHS.THUMBNAILS, | ||
35 | express.static(thumbnailsPhysicalPath, { maxAge: STATIC_MAX_AGE }) | ||
36 | ) | ||
37 | |||
38 | // Video previews path for express | ||
39 | const previewsPhysicalPath = CONFIG.STORAGE.PREVIEWS_DIR | ||
40 | staticRouter.use( | ||
41 | STATIC_PATHS.PREVIEWS, | ||
42 | express.static(previewsPhysicalPath, { maxAge: STATIC_MAX_AGE }) | ||
43 | ) | ||
44 | |||
45 | // --------------------------------------------------------------------------- | ||
46 | |||
47 | export { | ||
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 | |||
3 | const miscValidators = require('./misc') | ||
4 | const podsValidators = require('./pods') | ||
5 | const remoteValidators = require('./remote') | ||
6 | const usersValidators = require('./users') | ||
7 | const videosValidators = require('./videos') | ||
8 | |||
9 | const validators = { | ||
10 | misc: miscValidators, | ||
11 | pods: podsValidators, | ||
12 | remote: remoteValidators, | ||
13 | users: usersValidators, | ||
14 | videos: videosValidators | ||
15 | } | ||
16 | |||
17 | // --------------------------------------------------------------------------- | ||
18 | |||
19 | module.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 @@ | |||
1 | export * from './remote' | ||
2 | export * from './misc' | ||
3 | export * from './pods' | ||
4 | export * from './pods' | ||
5 | export * from './users' | ||
6 | export * 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 | |||
3 | const miscValidators = { | ||
4 | exists, | ||
5 | isArray | ||
6 | } | ||
7 | |||
8 | function exists (value) { | 1 | function 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 | ||
18 | module.exports = miscValidators | 11 | export { |
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' | 1 | import expressValidator = require('express-validator') |
2 | // TODO: use .validator when express-validator typing will have validator field | ||
3 | const validator = expressValidator['validator'] | ||
2 | 4 | ||
3 | const validator = require('express-validator').validator | 5 | import { isArray } from './misc' |
4 | |||
5 | const miscValidators = require('./misc') | ||
6 | |||
7 | const podsValidators = { | ||
8 | isEachUniqueHostValid, | ||
9 | isHostValid | ||
10 | } | ||
11 | 6 | ||
12 | function isHostValid (host) { | 7 | function isHostValid (host) { |
13 | return validator.isURL(host) && host.split('://').length === 1 | 8 | return validator.isURL(host) && host.split('://').length === 1 |
14 | } | 9 | } |
15 | 10 | ||
16 | function isEachUniqueHostValid (hosts) { | 11 | function 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 | ||
26 | module.exports = podsValidators | 21 | export { |
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 | |||
3 | const remoteVideosValidators = require('./videos') | ||
4 | |||
5 | const validators = { | ||
6 | videos: remoteVideosValidators | ||
7 | } | ||
8 | |||
9 | // --------------------------------------------------------------------------- | ||
10 | |||
11 | module.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 | |||
3 | const has = require('lodash/has') | ||
4 | const values = require('lodash/values') | ||
5 | |||
6 | const constants = require('../../../initializers/constants') | ||
7 | const videosValidators = require('../videos') | ||
8 | const miscValidators = require('../misc') | ||
9 | |||
10 | const ENDPOINT_ACTIONS = constants.REQUEST_ENDPOINT_ACTIONS[constants.REQUEST_ENDPOINTS.VIDEOS] | ||
11 | |||
12 | const remoteVideosValidators = { | ||
13 | isEachRemoteRequestVideosValid, | ||
14 | isEachRemoteRequestVideosQaduValid, | ||
15 | isEachRemoteRequestVideosEventsValid | ||
16 | } | ||
17 | |||
18 | function 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 | |||
48 | function 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 | |||
64 | function 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 | |||
81 | module.exports = remoteVideosValidators | ||
82 | |||
83 | // --------------------------------------------------------------------------- | ||
84 | |||
85 | function 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 | |||
104 | function isRequestTypeAddValid (value) { | ||
105 | return value === ENDPOINT_ACTIONS.ADD | ||
106 | } | ||
107 | |||
108 | function isRequestTypeUpdateValid (value) { | ||
109 | return value === ENDPOINT_ACTIONS.UPDATE | ||
110 | } | ||
111 | |||
112 | function isRequestTypeRemoveValid (value) { | ||
113 | return value === ENDPOINT_ACTIONS.REMOVE | ||
114 | } | ||
115 | |||
116 | function 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 @@ | |||
1 | import { has, values } from 'lodash' | ||
2 | |||
3 | import { | ||
4 | REQUEST_ENDPOINTS, | ||
5 | REQUEST_ENDPOINT_ACTIONS, | ||
6 | REQUEST_VIDEO_EVENT_TYPES | ||
7 | } from '../../../initializers' | ||
8 | import { isArray } from '../misc' | ||
9 | import { | ||
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 | |||
32 | const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS] | ||
33 | |||
34 | function 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 | |||
64 | function 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 | |||
80 | function 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 | |||
97 | export { | ||
98 | isEachRemoteRequestVideosValid, | ||
99 | isEachRemoteRequestVideosQaduValid, | ||
100 | isEachRemoteRequestVideosEventsValid | ||
101 | } | ||
102 | |||
103 | // --------------------------------------------------------------------------- | ||
104 | |||
105 | function 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 | |||
124 | function isRequestTypeAddValid (value) { | ||
125 | return value === ENDPOINT_ACTIONS.ADD | ||
126 | } | ||
127 | |||
128 | function isRequestTypeUpdateValid (value) { | ||
129 | return value === ENDPOINT_ACTIONS.UPDATE | ||
130 | } | ||
131 | |||
132 | function isRequestTypeRemoveValid (value) { | ||
133 | return value === ENDPOINT_ACTIONS.REMOVE | ||
134 | } | ||
135 | |||
136 | function 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' | 1 | import { values } from 'lodash' |
2 | import expressValidator = require('express-validator') | ||
3 | // TODO: use .validator when express-validator typing will have validator field | ||
4 | const validator = expressValidator['validator'] | ||
2 | 5 | ||
3 | const validator = require('express-validator').validator | 6 | import { CONSTRAINTS_FIELDS, USER_ROLES } from '../../initializers' |
4 | const values = require('lodash/values') | 7 | const USERS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.USERS |
5 | |||
6 | const constants = require('../../initializers/constants') | ||
7 | const USERS_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.USERS | ||
8 | |||
9 | const usersValidators = { | ||
10 | isUserPasswordValid, | ||
11 | isUserRoleValid, | ||
12 | isUserUsernameValid, | ||
13 | isUserDisplayNSFWValid | ||
14 | } | ||
15 | 8 | ||
16 | function isUserPasswordValid (value) { | 9 | function isUserPasswordValid (value) { |
17 | return validator.isLength(value, USERS_CONSTRAINTS_FIELDS.PASSWORD) | 10 | return validator.isLength(value, USERS_CONSTRAINTS_FIELDS.PASSWORD) |
18 | } | 11 | } |
19 | 12 | ||
20 | function isUserRoleValid (value) { | 13 | function isUserRoleValid (value) { |
21 | return values(constants.USER_ROLES).indexOf(value) !== -1 | 14 | return values(USER_ROLES).indexOf(value) !== -1 |
22 | } | 15 | } |
23 | 16 | ||
24 | function isUserUsernameValid (value) { | 17 | function isUserUsernameValid (value) { |
@@ -33,4 +26,9 @@ function isUserDisplayNSFWValid (value) { | |||
33 | 26 | ||
34 | // --------------------------------------------------------------------------- | 27 | // --------------------------------------------------------------------------- |
35 | 28 | ||
36 | module.exports = usersValidators | 29 | export { |
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' | 1 | import { values } from 'lodash' |
2 | 2 | import expressValidator = require('express-validator') | |
3 | const validator = require('express-validator').validator | 3 | // TODO: use .validator when express-validator typing will have validator field |
4 | const values = require('lodash/values') | 4 | const validator = expressValidator['validator'] |
5 | 5 | ||
6 | const constants = require('../../initializers/constants') | 6 | import { |
7 | const usersValidators = require('./users') | 7 | CONSTRAINTS_FIELDS, |
8 | const miscValidators = require('./misc') | 8 | VIDEO_CATEGORIES, |
9 | const VIDEOS_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.VIDEOS | 9 | VIDEO_LICENCES, |
10 | const VIDEO_ABUSES_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.VIDEO_ABUSES | 10 | VIDEO_LANGUAGES, |
11 | const VIDEO_EVENTS_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.VIDEO_EVENTS | 11 | VIDEO_RATE_TYPES |
12 | 12 | } from '../../initializers' | |
13 | const videosValidators = { | 13 | import { isUserUsernameValid } from './users' |
14 | isVideoAuthorValid, | 14 | import { isArray } from './misc' |
15 | isVideoDateValid, | 15 | |
16 | isVideoCategoryValid, | 16 | const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS |
17 | isVideoLicenceValid, | 17 | const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES |
18 | isVideoLanguageValid, | 18 | const 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 | ||
39 | function isVideoAuthorValid (value) { | 20 | function isVideoAuthorValid (value) { |
40 | return usersValidators.isUserUsernameValid(value) | 21 | return isUserUsernameValid(value) |
41 | } | 22 | } |
42 | 23 | ||
43 | function isVideoDateValid (value) { | 24 | function isVideoDateValid (value) { |
@@ -45,15 +26,15 @@ function isVideoDateValid (value) { | |||
45 | } | 26 | } |
46 | 27 | ||
47 | function isVideoCategoryValid (value) { | 28 | function isVideoCategoryValid (value) { |
48 | return constants.VIDEO_CATEGORIES[value] !== undefined | 29 | return VIDEO_CATEGORIES[value] !== undefined |
49 | } | 30 | } |
50 | 31 | ||
51 | function isVideoLicenceValid (value) { | 32 | function isVideoLicenceValid (value) { |
52 | return constants.VIDEO_LICENCES[value] !== undefined | 33 | return VIDEO_LICENCES[value] !== undefined |
53 | } | 34 | } |
54 | 35 | ||
55 | function isVideoLanguageValid (value) { | 36 | function isVideoLanguageValid (value) { |
56 | return value === null || constants.VIDEO_LANGUAGES[value] !== undefined | 37 | return value === null || VIDEO_LANGUAGES[value] !== undefined |
57 | } | 38 | } |
58 | 39 | ||
59 | function isVideoNSFWValid (value) { | 40 | function isVideoNSFWValid (value) { |
@@ -81,7 +62,7 @@ function isVideoNameValid (value) { | |||
81 | } | 62 | } |
82 | 63 | ||
83 | function isVideoTagsValid (tags) { | 64 | function 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 | ||
107 | function isVideoAbuseReporterUsernameValid (value) { | 88 | function isVideoAbuseReporterUsernameValid (value) { |
108 | return usersValidators.isUserUsernameValid(value) | 89 | return isUserUsernameValid(value) |
109 | } | 90 | } |
110 | 91 | ||
111 | function isVideoViewsValid (value) { | 92 | function isVideoViewsValid (value) { |
@@ -125,7 +106,7 @@ function isVideoEventCountValid (value) { | |||
125 | } | 106 | } |
126 | 107 | ||
127 | function isVideoRatingTypeValid (value) { | 108 | function 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 | ||
131 | function isVideoFile (value, files) { | 112 | function isVideoFile (value, files) { |
@@ -145,4 +126,28 @@ function isVideoFile (value, files) { | |||
145 | 126 | ||
146 | // --------------------------------------------------------------------------- | 127 | // --------------------------------------------------------------------------- |
147 | 128 | ||
148 | module.exports = videosValidators | 129 | export { |
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 | 2 | import retry = require('async/retry') | |
3 | const retry = require('async/retry') | ||
4 | 3 | ||
5 | const db = require('../initializers/database') | 4 | const db = require('../initializers/database') |
6 | const logger = require('./logger') | 5 | import { logger } from './logger' |
7 | |||
8 | const utils = { | ||
9 | commitTransaction, | ||
10 | retryTransactionWrapper, | ||
11 | rollbackTransaction, | ||
12 | startSerializableTransaction, | ||
13 | transactionRetryer | ||
14 | } | ||
15 | 6 | ||
16 | function commitTransaction (t, callback) { | 7 | function commitTransaction (t, callback) { |
17 | return t.commit().asCallback(callback) | 8 | return t.commit().asCallback(callback) |
@@ -33,7 +24,7 @@ function rollbackTransaction (err, t, callback) { | |||
33 | function retryTransactionWrapper (functionToRetry, options, finalCallback) { | 24 | function 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 | ||
72 | module.exports = utils | 63 | export { |
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 @@ | |||
1 | export * from './logger' | ||
2 | export * from './custom-validators' | ||
3 | export * from './database-utils' | ||
4 | export * from './peertube-crypto' | ||
5 | export * from './requests' | ||
6 | export * 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' | 2 | import mkdirp = require('mkdirp') |
3 | import path = require('path') | ||
4 | import winston = require('winston') | ||
3 | 5 | ||
4 | const mkdirp = require('mkdirp') | 6 | // Do not use barrel (dependencies issues) |
5 | const path = require('path') | 7 | import { CONFIG } from '../initializers/constants' |
6 | const winston = require('winston') | ||
7 | winston.emitErrs = true | ||
8 | 8 | ||
9 | const constants = require('../initializers/constants') | 9 | const label = CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT |
10 | |||
11 | const 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 |
14 | mkdirp.sync(constants.CONFIG.STORAGE.LOG_DIR) | 12 | mkdirp.sync(CONFIG.STORAGE.LOG_DIR) |
15 | 13 | ||
16 | const logger = new winston.Logger({ | 14 | const 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 | ||
41 | logger.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 | ||
49 | module.exports = logger | 48 | export { 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' | 1 | import crypto = require('crypto') |
2 | 2 | import bcrypt = require('bcrypt') | |
3 | const crypto = require('crypto') | 3 | import fs = require('fs') |
4 | const bcrypt = require('bcrypt') | 4 | import openssl = require('openssl-wrapper') |
5 | const fs = require('fs') | 5 | import { join } from 'path' |
6 | const openssl = require('openssl-wrapper') | 6 | |
7 | const pathUtils = require('path') | 7 | import { |
8 | 8 | SIGNATURE_ALGORITHM, | |
9 | const constants = require('../initializers/constants') | 9 | SIGNATURE_ENCODING, |
10 | const logger = require('./logger') | 10 | PRIVATE_CERT_NAME, |
11 | 11 | CONFIG, | |
12 | const peertubeCrypto = { | 12 | BCRYPT_SALT_SIZE, |
13 | checkSignature, | 13 | PUBLIC_CERT_NAME |
14 | comparePassword, | 14 | } from '../initializers' |
15 | createCertsIfNotExist, | 15 | import { logger } from './logger' |
16 | cryptPassword, | ||
17 | getMyPrivateCert, | ||
18 | getMyPublicCert, | ||
19 | sign | ||
20 | } | ||
21 | 16 | ||
22 | function checkSignature (publicKey, data, hexSignature) { | 17 | function 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 | ||
43 | function sign (data) { | 38 | function 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 | ||
90 | function cryptPassword (password, callback) { | 85 | function 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 | ||
100 | function getMyPrivateCert (callback) { | 95 | function 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 | ||
105 | function getMyPublicCert (callback) { | 100 | function 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 | ||
112 | module.exports = peertubeCrypto | 107 | export { |
108 | checkSignature, | ||
109 | comparePassword, | ||
110 | createCertsIfNotExist, | ||
111 | cryptPassword, | ||
112 | getMyPrivateCert, | ||
113 | getMyPublicCert, | ||
114 | sign | ||
115 | } | ||
113 | 116 | ||
114 | // --------------------------------------------------------------------------- | 117 | // --------------------------------------------------------------------------- |
115 | 118 | ||
116 | function certsExist (callback) { | 119 | function 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' | 1 | import replay = require('request-replay') |
2 | import request = require('request') | ||
2 | 3 | ||
3 | const replay = require('request-replay') | 4 | import { |
4 | const request = require('request') | 5 | RETRY_REQUESTS, |
5 | 6 | REMOTE_SCHEME, | |
6 | const constants = require('../initializers/constants') | 7 | CONFIG |
7 | const peertubeCrypto = require('./peertube-crypto') | 8 | } from '../initializers' |
8 | 9 | import { sign } from './peertube-crypto' | |
9 | const requests = { | ||
10 | makeRetryRequest, | ||
11 | makeSecureRequest | ||
12 | } | ||
13 | 10 | ||
14 | function makeRetryRequest (params, callback) { | 11 | function 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 | ||
26 | function makeSecureRequest (params, callback) { | 23 | function 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 | ||
68 | module.exports = requests | 62 | export { |
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' | 1 | import { pseudoRandomBytes } from 'crypto' |
2 | 2 | ||
3 | const crypto = require('crypto') | 3 | import { logger } from './logger' |
4 | |||
5 | const logger = require('./logger') | ||
6 | |||
7 | const utils = { | ||
8 | badRequest, | ||
9 | createEmptyCallback, | ||
10 | cleanForExit, | ||
11 | generateRandomString, | ||
12 | isTestInstance, | ||
13 | getFormatedObjects | ||
14 | } | ||
15 | 4 | ||
16 | function badRequest (req, res, next) { | 5 | function badRequest (req, res, next) { |
17 | res.type('json').status(400).end() | 6 | res.type('json').status(400).end() |
18 | } | 7 | } |
19 | 8 | ||
20 | function generateRandomString (size, callback) { | 9 | function 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 | ||
58 | module.exports = utils | 47 | export { |
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' | 1 | import config = require('config') |
2 | 2 | ||
3 | const config = require('config') | ||
4 | |||
5 | const constants = require('./constants') | ||
6 | const db = require('./database') | 3 | const db = require('./database') |
7 | 4 | import { CONFIG } from './constants' | |
8 | const 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 |
17 | function checkConfig () { | 7 | function 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 | ||
88 | module.exports = checker | 78 | export { |
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' | 1 | import config = require('config') |
2 | 2 | import { join } from 'path' | |
3 | const config = require('config') | ||
4 | const path = require('path') | ||
5 | 3 | ||
6 | // --------------------------------------------------------------------------- | 4 | // --------------------------------------------------------------------------- |
7 | 5 | ||
@@ -36,38 +34,40 @@ const OAUTH_LIFETIME = { | |||
36 | 34 | ||
37 | const CONFIG = { | 35 | const 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 | } |
73 | CONFIG.WEBSERVER.URL = CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT | 73 | CONFIG.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 | ||
291 | module.exports = { | 291 | export { |
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' | 1 | import fs = require('fs') |
2 | import { join } from 'path' | ||
3 | import Sequelize = require('sequelize') | ||
2 | 4 | ||
3 | const fs = require('fs') | 5 | import { CONFIG } from './constants' |
4 | const path = require('path') | 6 | // Do not use barrel, we need to load database first |
5 | const Sequelize = require('sequelize') | 7 | import { logger } from '../helpers/logger' |
8 | import { isTestInstance } from '../helpers/utils' | ||
6 | 9 | ||
7 | const constants = require('../initializers/constants') | 10 | const dbname = CONFIG.DATABASE.DBNAME |
8 | const logger = require('../helpers/logger') | 11 | const username = CONFIG.DATABASE.USERNAME |
9 | const utils = require('../helpers/utils') | 12 | const password = CONFIG.DATABASE.PASSWORD |
10 | 13 | ||
11 | const database = {} | 14 | const database: any = {} |
12 | |||
13 | const dbname = constants.CONFIG.DATABASE.DBNAME | ||
14 | const username = constants.CONFIG.DATABASE.USERNAME | ||
15 | const password = constants.CONFIG.DATABASE.PASSWORD | ||
16 | 15 | ||
17 | const sequelize = new Sequelize(dbname, username, password, { | 16 | const 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 | ||
33 | database.sequelize = sequelize | 32 | database.sequelize = sequelize |
34 | database.Sequelize = Sequelize | ||
35 | database.init = init | ||
36 | |||
37 | // --------------------------------------------------------------------------- | ||
38 | 33 | ||
39 | module.exports = database | 34 | database.init = function (silent, callback) { |
40 | |||
41 | // --------------------------------------------------------------------------- | ||
42 | |||
43 | function 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 | |||
72 | module.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! | ||
2 | export * from './constants' | ||
3 | export * from './database' | ||
4 | export * from './checker' | ||
5 | export * from './installer' | ||
6 | export * 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' | 1 | import { join } from 'path' |
2 | import config = require('config') | ||
3 | import { each, series } from 'async' | ||
4 | import mkdirp = require('mkdirp') | ||
5 | import passwordGenerator = require('password-generator') | ||
2 | 6 | ||
3 | const config = require('config') | ||
4 | const each = require('async/each') | ||
5 | const mkdirp = require('mkdirp') | ||
6 | const passwordGenerator = require('password-generator') | ||
7 | const path = require('path') | ||
8 | const series = require('async/series') | ||
9 | |||
10 | const checker = require('./checker') | ||
11 | const constants = require('./constants') | ||
12 | const db = require('./database') | 7 | const db = require('./database') |
13 | const logger = require('../helpers/logger') | 8 | import { USER_ROLES, CONFIG, LAST_MIGRATION_VERSION } from './constants' |
14 | const peertubeCrypto = require('../helpers/peertube-crypto') | 9 | import { clientsExist, usersExist } from './checker' |
15 | 10 | import { logger, createCertsIfNotExist } from '../helpers' | |
16 | const installer = { | ||
17 | installApplication | ||
18 | } | ||
19 | 11 | ||
20 | function installApplication (callback) { | 12 | function 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 | ||
47 | module.exports = installer | 39 | export { |
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 | ||
60 | function createOAuthClientIfNotExist (callback) { | 54 | function 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 | ||
88 | function createOAuthAdminIfNotExist (callback) { | 82 | function 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' | 1 | import { waterfall } from 'async' |
2 | |||
3 | const waterfall = require('async/waterfall') | ||
4 | 2 | ||
5 | // utils = { transaction, queryInterface, sequelize, Sequelize } | 3 | // utils = { transaction, queryInterface, sequelize, Sequelize } |
6 | exports.up = function (utils, finalCallback) { | 4 | function 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 | ||
39 | exports.down = function (options, callback) { | 37 | function down (options, callback) { |
40 | throw new Error('Not implemented.') | 38 | throw new Error('Not implemented.') |
41 | } | 39 | } |
40 | |||
41 | export { | ||
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' | 1 | import { waterfall } from 'async' |
2 | |||
3 | const waterfall = require('async/waterfall') | ||
4 | 2 | ||
5 | // utils = { transaction, queryInterface, sequelize, Sequelize } | 3 | // utils = { transaction, queryInterface, sequelize, Sequelize } |
6 | exports.up = function (utils, finalCallback) { | 4 | function 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 | ||
39 | exports.down = function (options, callback) { | 37 | function down (options, callback) { |
40 | throw new Error('Not implemented.') | 38 | throw new Error('Not implemented.') |
41 | } | 39 | } |
40 | |||
41 | export { | ||
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 } |
4 | exports.up = function (utils, finalCallback) { | 2 | function 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 | ||
17 | exports.down = function (options, callback) { | 15 | function down (options, callback) { |
18 | throw new Error('Not implemented.') | 16 | throw new Error('Not implemented.') |
19 | } | 17 | } |
18 | |||
19 | export { | ||
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 } |
4 | exports.up = function (utils, finalCallback) { | 2 | function 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 | ||
17 | exports.down = function (options, callback) { | 15 | function down (options, callback) { |
18 | throw new Error('Not implemented.') | 16 | throw new Error('Not implemented.') |
19 | } | 17 | } |
18 | |||
19 | export { | ||
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 } |
4 | exports.up = function (utils, finalCallback) { | 2 | function 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 | ||
17 | exports.down = function (options, callback) { | 15 | function down (options, callback) { |
18 | throw new Error('Not implemented.') | 16 | throw new Error('Not implemented.') |
19 | } | 17 | } |
18 | |||
19 | export { | ||
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' | 1 | import { waterfall } from 'async' |
2 | |||
3 | const waterfall = require('async/waterfall') | ||
4 | 2 | ||
5 | // utils = { transaction, queryInterface, sequelize, Sequelize } | 3 | // utils = { transaction, queryInterface, sequelize, Sequelize } |
6 | exports.up = function (utils, finalCallback) { | 4 | function 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 | ||
32 | exports.down = function (options, callback) { | 30 | function down (options, callback) { |
33 | throw new Error('Not implemented.') | 31 | throw new Error('Not implemented.') |
34 | } | 32 | } |
33 | |||
34 | export { | ||
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' | 1 | import { waterfall } from 'async' |
2 | |||
3 | const waterfall = require('async/waterfall') | ||
4 | 2 | ||
5 | // utils = { transaction, queryInterface, sequelize, Sequelize } | 3 | // utils = { transaction, queryInterface, sequelize, Sequelize } |
6 | exports.up = function (utils, finalCallback) { | 4 | function 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 | ||
32 | exports.down = function (options, callback) { | 30 | function down (options, callback) { |
33 | throw new Error('Not implemented.') | 31 | throw new Error('Not implemented.') |
34 | } | 32 | } |
33 | |||
34 | export { | ||
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' | 1 | import { waterfall } from 'async' |
2 | |||
3 | const waterfall = require('async/waterfall') | ||
4 | 2 | ||
5 | // utils = { transaction, queryInterface, sequelize, Sequelize } | 3 | // utils = { transaction, queryInterface, sequelize, Sequelize } |
6 | exports.up = function (utils, finalCallback) { | 4 | function 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 | ||
32 | exports.down = function (options, callback) { | 30 | function down (options, callback) { |
33 | throw new Error('Not implemented.') | 31 | throw new Error('Not implemented.') |
34 | } | 32 | } |
33 | |||
34 | export { | ||
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 } |
4 | exports.up = function (utils, finalCallback) { | 2 | function 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 | ||
17 | exports.down = function (options, callback) { | 15 | function down (options, callback) { |
18 | throw new Error('Not implemented.') | 16 | throw new Error('Not implemented.') |
19 | } | 17 | } |
18 | |||
19 | export { | ||
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 } |
4 | exports.up = function (utils, finalCallback) { | 2 | function 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 | ||
17 | exports.down = function (options, callback) { | 15 | function down (options, callback) { |
18 | throw new Error('Not implemented.') | 16 | throw new Error('Not implemented.') |
19 | } | 17 | } |
18 | |||
19 | export { | ||
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' | 1 | import { waterfall, eachSeries } from 'async' |
2 | import fs = require('fs') | ||
3 | import path = require('path') | ||
2 | 4 | ||
3 | const waterfall = require('async/waterfall') | ||
4 | const eachSeries = require('async/eachSeries') | ||
5 | const fs = require('fs') | ||
6 | const path = require('path') | ||
7 | |||
8 | const constants = require('./constants') | ||
9 | const db = require('./database') | 5 | const db = require('./database') |
10 | const logger = require('../helpers/logger') | 6 | import { LAST_MIGRATION_VERSION } from './constants' |
11 | 7 | import { logger } from '../helpers' | |
12 | const migrator = { | ||
13 | migrate: migrate | ||
14 | } | ||
15 | 8 | ||
16 | function migrate (finalCallback) { | 9 | function 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 | ||
78 | module.exports = migrator | 71 | export { |
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' | 1 | import { each, eachLimit, eachSeries, series, waterfall } from 'async' |
2 | import request = require('request') | ||
2 | 3 | ||
3 | const each = require('async/each') | ||
4 | const eachLimit = require('async/eachLimit') | ||
5 | const eachSeries = require('async/eachSeries') | ||
6 | const series = require('async/series') | ||
7 | const request = require('request') | ||
8 | const waterfall = require('async/waterfall') | ||
9 | |||
10 | const constants = require('../initializers/constants') | ||
11 | const db = require('../initializers/database') | 4 | const db = require('../initializers/database') |
12 | const logger = require('../helpers/logger') | 5 | import { |
13 | const peertubeCrypto = require('../helpers/peertube-crypto') | 6 | API_VERSION, |
14 | const requests = require('../helpers/requests') | 7 | CONFIG, |
15 | const utils = require('../helpers/utils') | 8 | REQUESTS_IN_PARALLEL, |
16 | const RequestScheduler = require('./request/request-scheduler') | 9 | REQUEST_ENDPOINTS, |
17 | const RequestVideoQaduScheduler = require('./request/request-video-qadu-scheduler') | 10 | REQUEST_ENDPOINT_ACTIONS, |
18 | const RequestVideoEventScheduler = require('./request/request-video-event-scheduler') | 11 | REMOTE_SCHEME |
19 | 12 | } from '../initializers' | |
20 | const ENDPOINT_ACTIONS = constants.REQUEST_ENDPOINT_ACTIONS[constants.REQUEST_ENDPOINTS.VIDEOS] | 13 | import { |
14 | logger, | ||
15 | getMyPublicCert, | ||
16 | makeSecureRequest, | ||
17 | makeRetryRequest, | ||
18 | createEmptyCallback | ||
19 | } from '../helpers' | ||
20 | import { | ||
21 | RequestScheduler, | ||
22 | RequestVideoQaduScheduler, | ||
23 | RequestVideoEventScheduler | ||
24 | } from './request' | ||
25 | |||
26 | const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS] | ||
21 | 27 | ||
22 | const requestScheduler = new RequestScheduler() | 28 | const requestScheduler = new RequestScheduler() |
23 | const requestVideoQaduScheduler = new RequestVideoQaduScheduler() | 29 | const requestVideoQaduScheduler = new RequestVideoQaduScheduler() |
24 | const requestVideoEventScheduler = new RequestVideoEventScheduler() | 30 | const requestVideoEventScheduler = new RequestVideoEventScheduler() |
25 | 31 | ||
26 | const friends = { | 32 | function 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 | |||
45 | function 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 () { | |||
51 | function addVideoToFriends (videoData, transaction, callback) { | 38 | function 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) { | |||
61 | function updateVideoToFriends (videoData, transaction, callback) { | 48 | function 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) { | |||
71 | function removeVideoToFriends (videoParams) { | 58 | function 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) { | |||
80 | function reportAbuseVideoToFriend (reportData, video) { | 67 | function 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 | ||
90 | function quickAndDirtyUpdateVideoToFriends (qaduParams, transaction, callback) { | 77 | function 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 | ||
113 | function addEventToRemoteVideo (eventParams, transaction, callback) { | 100 | function 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 | ||
266 | module.exports = friends | 254 | export { |
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 | ||
306 | function getForeignPodsList (host, callback) { | 311 | function 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 } |
375 | function createRequest (options, callback) { | 380 | function 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 | ||
391 | function createVideoQaduRequest (options, callback) { | 396 | function 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 | ||
397 | function createVideoEventRequest (options, callback) { | 402 | function 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 | ||
403 | function isMe (host) { | 408 | function 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 @@ | |||
1 | export * from './jobs' | ||
2 | export * from './request' | ||
3 | export * from './friends' | ||
4 | export * 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 | |||
3 | const videoTranscoder = require('./video-transcoder') | ||
4 | |||
5 | module.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 @@ | |||
1 | import * as videoTranscoder from './video-transcoder' | ||
2 | |||
3 | const jobHandlers = { | ||
4 | videoTranscoder | ||
5 | } | ||
6 | |||
7 | export { | ||
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 | |||
3 | const db = require('../../../initializers/database') | 1 | const db = require('../../../initializers/database') |
4 | const logger = require('../../../helpers/logger') | 2 | import { logger } from '../../../helpers' |
5 | const friends = require('../../../lib/friends') | 3 | import { addVideoToFriends } from '../../../lib' |
6 | |||
7 | const VideoTranscoderHandler = { | ||
8 | process, | ||
9 | onError, | ||
10 | onSuccess | ||
11 | } | ||
12 | |||
13 | // --------------------------------------------------------------------------- | ||
14 | 4 | ||
15 | function process (data, callback) { | 5 | function 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 | ||
43 | module.exports = VideoTranscoderHandler | 33 | export { |
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 | |||
3 | const forever = require('async/forever') | ||
4 | const queue = require('async/queue') | ||
5 | |||
6 | const constants = require('../../initializers/constants') | ||
7 | const db = require('../../initializers/database') | ||
8 | const logger = require('../../helpers/logger') | ||
9 | |||
10 | const jobHandlers = require('./handlers') | ||
11 | |||
12 | const jobScheduler = { | ||
13 | activate, | ||
14 | createJob | ||
15 | } | ||
16 | |||
17 | function 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 | |||
56 | module.exports = jobScheduler | ||
57 | |||
58 | // --------------------------------------------------------------------------- | ||
59 | |||
60 | function 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 | |||
70 | function 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 | |||
81 | function 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 | |||
106 | function 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 | |||
116 | function 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 | |||
126 | function 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 @@ | |||
1 | import { forever, queue } from 'async' | ||
2 | |||
3 | const db = require('../../initializers/database') | ||
4 | import { | ||
5 | JOBS_FETCHING_INTERVAL, | ||
6 | JOBS_FETCH_LIMIT_PER_CYCLE, | ||
7 | JOB_STATES | ||
8 | } from '../../initializers' | ||
9 | import { logger } from '../../helpers' | ||
10 | import { jobHandlers } from './handlers' | ||
11 | |||
12 | class 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 | |||
135 | export { | ||
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 @@ | |||
1 | const db = require('../initializers/database') | 1 | const db = require('../initializers/database') |
2 | const logger = require('../helpers/logger') | 2 | import { logger } from '../helpers' |
3 | |||
4 | // See https://github.com/oauthjs/node-oauth2-server/wiki/Model-specification for the model specifications | ||
5 | const 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 | ||
97 | module.exports = OAuthModel | 87 | // See https://github.com/oauthjs/node-oauth2-server/wiki/Model-specification for the model specifications |
88 | export { | ||
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' | 1 | import { eachLimit } from 'async/eachLimit' |
2 | 2 | ||
3 | const eachLimit = require('async/eachLimit') | ||
4 | |||
5 | const constants = require('../../initializers/constants') | ||
6 | const db = require('../../initializers/database') | 3 | const db = require('../../initializers/database') |
7 | const logger = require('../../helpers/logger') | 4 | import { logger, makeSecureRequest } from '../../helpers' |
8 | const requests = require('../../helpers/requests') | 5 | import { |
9 | 6 | API_VERSION, | |
10 | module.exports = class BaseRequestScheduler { | 7 | REQUESTS_IN_PARALLEL, |
11 | constructor (options) { | 8 | REQUESTS_INTERVAL |
9 | } from '../../initializers' | ||
10 | |||
11 | abstract 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 | |||
152 | export { | ||
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 @@ | |||
1 | export * from './request-scheduler' | ||
2 | export * from './request-video-event-scheduler' | ||
3 | export * 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 | |||
3 | const constants = require('../../initializers/constants') | ||
4 | const BaseRequestScheduler = require('./base-request-scheduler') | ||
5 | const db = require('../../initializers/database') | 1 | const db = require('../../initializers/database') |
6 | const logger = require('../../helpers/logger') | 2 | import { BaseRequestScheduler } from './base-request-scheduler' |
7 | 3 | import { logger } from '../../helpers' | |
8 | module.exports = class RequestScheduler extends BaseRequestScheduler { | 4 | import { |
5 | REQUESTS_LIMIT_PODS, | ||
6 | REQUESTS_LIMIT_PER_POD | ||
7 | } from '../../initializers' | ||
8 | |||
9 | class 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 | |||
102 | export { | ||
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 | |||
3 | const BaseRequestScheduler = require('./base-request-scheduler') | ||
4 | const constants = require('../../initializers/constants') | ||
5 | const db = require('../../initializers/database') | 1 | const db = require('../../initializers/database') |
6 | 2 | import { BaseRequestScheduler } from './base-request-scheduler' | |
7 | module.exports = class RequestVideoEventScheduler extends BaseRequestScheduler { | 3 | import { |
4 | REQUESTS_VIDEO_EVENT_LIMIT_PODS, | ||
5 | REQUESTS_VIDEO_EVENT_LIMIT_PER_POD, | ||
6 | REQUEST_VIDEO_EVENT_ENDPOINT | ||
7 | } from '../../initializers' | ||
8 | |||
9 | class 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 | |||
114 | export { | ||
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 | |||
3 | const BaseRequestScheduler = require('./base-request-scheduler') | ||
4 | const constants = require('../../initializers/constants') | ||
5 | const db = require('../../initializers/database') | 1 | const db = require('../../initializers/database') |
6 | const logger = require('../../helpers/logger') | 2 | import { BaseRequestScheduler } from './base-request-scheduler' |
7 | 3 | import { logger } from '../../helpers' | |
8 | module.exports = class RequestVideoQaduScheduler extends BaseRequestScheduler { | 4 | import { |
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 | |||
11 | class 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 | |||
124 | export { | ||
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 | |||
3 | const logger = require('../helpers/logger') | 1 | const logger = require('../helpers/logger') |
4 | 2 | ||
5 | const adminMiddleware = { | ||
6 | ensureIsAdmin | ||
7 | } | ||
8 | |||
9 | function ensureIsAdmin (req, res, next) { | 3 | function 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 | ||
21 | module.exports = adminMiddleware | 15 | export { |
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 | |||
3 | const adminMiddleware = require('./admin') | ||
4 | const oauthMiddleware = require('./oauth') | ||
5 | const paginationMiddleware = require('./pagination') | ||
6 | const podsMiddleware = require('./pods') | ||
7 | const validatorsMiddleware = require('./validators') | ||
8 | const searchMiddleware = require('./search') | ||
9 | const sortMiddleware = require('./sort') | ||
10 | const secureMiddleware = require('./secure') | ||
11 | |||
12 | const 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 | |||
25 | module.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 @@ | |||
1 | export * from './validators'; | ||
2 | export * from './admin'; | ||
3 | export * from './oauth'; | ||
4 | export * from './pagination'; | ||
5 | export * from './pods'; | ||
6 | export * from './search'; | ||
7 | export * from './secure'; | ||
8 | export * 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' | 1 | import OAuthServer = require('express-oauth-server') |
2 | |||
3 | const OAuthServer = require('express-oauth-server') | ||
4 | 2 | ||
5 | const constants = require('../initializers/constants') | 3 | const constants = require('../initializers/constants') |
6 | const logger = require('../helpers/logger') | 4 | const 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 | ||
14 | const oAuth = { | ||
15 | authenticate, | ||
16 | token | ||
17 | } | ||
18 | |||
19 | function authenticate (req, res, next) { | 12 | function 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 | ||
38 | module.exports = oAuth | 31 | export { |
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 | |||
3 | const constants = require('../initializers/constants') | 1 | const constants = require('../initializers/constants') |
4 | 2 | ||
5 | const paginationMiddleware = { | ||
6 | setPagination | ||
7 | } | ||
8 | |||
9 | function setPagination (req, res, next) { | 3 | function 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 | ||
20 | module.exports = paginationMiddleware | 15 | export { |
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 | ||
3 | const constants = require('../initializers/constants') | 3 | const constants = require('../initializers/constants') |
4 | 4 | ||
5 | const podsMiddleware = { | ||
6 | setBodyHostsPort, | ||
7 | setBodyHostPort | ||
8 | } | ||
9 | |||
10 | function setBodyHostsPort (req, res, next) { | 5 | function 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 | ||
44 | module.exports = podsMiddleware | 39 | export { |
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 | |||
3 | const searchMiddleware = { | ||
4 | setVideosSearch | ||
5 | } | ||
6 | |||
7 | function setVideosSearch (req, res, next) { | 1 | function 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 | ||
15 | module.exports = searchMiddleware | 9 | export { |
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 | |||
3 | const db = require('../initializers/database') | 1 | const db = require('../initializers/database') |
4 | const logger = require('../helpers/logger') | 2 | const logger = require('../helpers/logger') |
5 | const peertubeCrypto = require('../helpers/peertube-crypto') | 3 | const peertubeCrypto = require('../helpers/peertube-crypto') |
6 | 4 | ||
7 | const secureMiddleware = { | ||
8 | checkSignature | ||
9 | } | ||
10 | |||
11 | function checkSignature (req, res, next) { | 5 | function 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 | ||
52 | module.exports = secureMiddleware | 46 | export { |
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 | |||
3 | const sortMiddleware = { | ||
4 | setUsersSort, | ||
5 | setVideoAbusesSort, | ||
6 | setVideosSort | ||
7 | } | ||
8 | |||
9 | function setUsersSort (req, res, next) { | 1 | function 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 | ||
29 | module.exports = sortMiddleware | 21 | export { |
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 | |||
3 | const paginationValidators = require('./pagination') | ||
4 | const podsValidators = require('./pods') | ||
5 | const remoteValidators = require('./remote') | ||
6 | const sortValidators = require('./sort') | ||
7 | const usersValidators = require('./users') | ||
8 | const videosValidators = require('./videos') | ||
9 | |||
10 | const validators = { | ||
11 | pagination: paginationValidators, | ||
12 | pods: podsValidators, | ||
13 | remote: remoteValidators, | ||
14 | sort: sortValidators, | ||
15 | users: usersValidators, | ||
16 | videos: videosValidators | ||
17 | } | ||
18 | |||
19 | // --------------------------------------------------------------------------- | ||
20 | |||
21 | module.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 @@ | |||
1 | export * from './remote' | ||
2 | export * from './pagination' | ||
3 | export * from './pods' | ||
4 | export * from './sort' | ||
5 | export * from './users' | ||
6 | export * 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' | 1 | import { checkErrors } from './utils' |
2 | import { logger } from '../../helpers' | ||
2 | 3 | ||
3 | const checkErrors = require('./utils').checkErrors | 4 | function paginationValidator (req, res, next) { |
4 | const logger = require('../../helpers/logger') | ||
5 | |||
6 | const validatorsPagination = { | ||
7 | pagination | ||
8 | } | ||
9 | |||
10 | function 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 | ||
21 | module.exports = validatorsPagination | 15 | export { |
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 | |||
3 | const checkErrors = require('./utils').checkErrors | ||
4 | const constants = require('../../initializers/constants') | ||
5 | const db = require('../../initializers/database') | 1 | const db = require('../../initializers/database') |
6 | const friends = require('../../lib/friends') | 2 | import { checkErrors } from './utils' |
7 | const logger = require('../../helpers/logger') | 3 | import { logger } from '../../helpers' |
8 | const utils = require('../../helpers/utils') | 4 | import { CONFIG } from '../../initializers' |
9 | 5 | import { hasFriends } from '../../lib' | |
10 | const validatorsPod = { | 6 | import { isTestInstance } from '../../helpers' |
11 | makeFriends, | ||
12 | podsAdd | ||
13 | } | ||
14 | 7 | ||
15 | function makeFriends (req, res, next) { | 8 | function 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 | ||
42 | function podsAdd (req, res, next) { | 35 | function 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 | ||
67 | module.exports = validatorsPod | 60 | export { |
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 | |||
3 | const remoteSignatureValidators = require('./signature') | ||
4 | const remoteVideosValidators = require('./videos') | ||
5 | |||
6 | const validators = { | ||
7 | signature: remoteSignatureValidators, | ||
8 | videos: remoteVideosValidators | ||
9 | } | ||
10 | |||
11 | // --------------------------------------------------------------------------- | ||
12 | |||
13 | module.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 @@ | |||
1 | export * from './signature' | ||
2 | export * 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' | 1 | import { logger } from '../../../helpers' |
2 | import { checkErrors } from '../utils' | ||
2 | 3 | ||
3 | const checkErrors = require('../utils').checkErrors | 4 | function signatureValidator (req, res, next) { |
4 | const logger = require('../../../helpers/logger') | ||
5 | |||
6 | const validatorsRemoteSignature = { | ||
7 | signature | ||
8 | } | ||
9 | |||
10 | function 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 | ||
21 | module.exports = validatorsRemoteSignature | 15 | export { |
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' | 1 | import { logger } from '../../../helpers' |
2 | import { checkErrors } from '../utils' | ||
2 | 3 | ||
3 | const checkErrors = require('../utils').checkErrors | 4 | function remoteVideosValidator (req, res, next) { |
4 | const logger = require('../../../helpers/logger') | ||
5 | |||
6 | const validatorsRemoteVideos = { | ||
7 | remoteVideos, | ||
8 | remoteQaduVideos, | ||
9 | remoteEventsVideos | ||
10 | } | ||
11 | |||
12 | function 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 | ||
20 | function remoteQaduVideos (req, res, next) { | 12 | function 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 | ||
28 | function remoteEventsVideos (req, res, next) { | 20 | function 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 | ||
37 | module.exports = validatorsRemoteVideos | 30 | export { |
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' | 1 | import { checkErrors } from './utils' |
2 | 2 | import { logger } from '../../helpers' | |
3 | const checkErrors = require('./utils').checkErrors | 3 | import { SORTABLE_COLUMNS } from '../../initializers' |
4 | const constants = require('../../initializers/constants') | ||
5 | const logger = require('../../helpers/logger') | ||
6 | |||
7 | const validatorsSort = { | ||
8 | usersSort, | ||
9 | videoAbusesSort, | ||
10 | videosSort | ||
11 | } | ||
12 | 4 | ||
13 | // Initialize constants here for better performances | 5 | // Initialize constants here for better performances |
14 | const SORTABLE_USERS_COLUMNS = createSortableColumns(constants.SORTABLE_COLUMNS.USERS) | 6 | const SORTABLE_USERS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.USERS) |
15 | const SORTABLE_VIDEO_ABUSES_COLUMNS = createSortableColumns(constants.SORTABLE_COLUMNS.VIDEO_ABUSES) | 7 | const SORTABLE_VIDEO_ABUSES_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEO_ABUSES) |
16 | const SORTABLE_VIDEOS_COLUMNS = createSortableColumns(constants.SORTABLE_COLUMNS.VIDEOS) | 8 | const SORTABLE_VIDEOS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEOS) |
17 | 9 | ||
18 | function usersSort (req, res, next) { | 10 | function usersSortValidator (req, res, next) { |
19 | checkSort(req, res, next, SORTABLE_USERS_COLUMNS) | 11 | checkSort(req, res, next, SORTABLE_USERS_COLUMNS) |
20 | } | 12 | } |
21 | 13 | ||
22 | function videoAbusesSort (req, res, next) { | 14 | function 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 | ||
26 | function videosSort (req, res, next) { | 18 | function 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 | ||
32 | module.exports = validatorsSort | 24 | export { |
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 | |||
3 | const checkErrors = require('./utils').checkErrors | ||
4 | const db = require('../../initializers/database') | 1 | const db = require('../../initializers/database') |
5 | const logger = require('../../helpers/logger') | 2 | import { checkErrors } from './utils' |
6 | 3 | import { logger } from '../../helpers' | |
7 | const validatorsUsers = { | ||
8 | usersAdd, | ||
9 | usersRemove, | ||
10 | usersUpdate, | ||
11 | usersVideoRating | ||
12 | } | ||
13 | 4 | ||
14 | function usersAdd (req, res, next) { | 5 | function 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 | ||
35 | function usersRemove (req, res, next) { | 26 | function 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 | ||
56 | function usersUpdate (req, res, next) { | 47 | function 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 | ||
67 | function usersVideoRating (req, res, next) { | 58 | function 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 | ||
88 | module.exports = validatorsUsers | 79 | export { |
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' | 1 | import { inspect } from 'util' |
2 | 2 | ||
3 | const util = require('util') | 3 | import { logger } from '../../helpers' |
4 | 4 | ||
5 | const logger = require('../../helpers/logger') | 5 | function checkErrors (req, res, next, statusCode?) { |
6 | |||
7 | const validatorsUtils = { | ||
8 | checkErrors | ||
9 | } | ||
10 | |||
11 | function 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 | ||
25 | module.exports = validatorsUtils | 19 | export { |
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 | |||
3 | const checkErrors = require('./utils').checkErrors | ||
4 | const constants = require('../../initializers/constants') | ||
5 | const customVideosValidators = require('../../helpers/custom-validators').videos | ||
6 | const db = require('../../initializers/database') | 1 | const db = require('../../initializers/database') |
7 | const logger = require('../../helpers/logger') | 2 | import { checkErrors } from './utils' |
8 | 3 | import { CONSTRAINTS_FIELDS, SEARCHABLE_COLUMNS } from '../../initializers' | |
9 | const validatorsVideos = { | 4 | import { 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 | ||
23 | function videosAdd (req, res, next) { | 6 | function 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 | ||
53 | function videosUpdate (req, res, next) { | 36 | function 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 | ||
81 | function videosGet (req, res, next) { | 64 | function 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 | ||
91 | function videosRemove (req, res, next) { | 74 | function 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 | ||
108 | function videosSearch (req, res, next) { | 91 | function 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 | ||
118 | function videoAbuseReport (req, res, next) { | 101 | function 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 | ||
129 | function videoRate (req, res, next) { | 112 | function 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 | ||
140 | function videosBlacklist (req, res, next) { | 123 | function 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 | ||
154 | module.exports = validatorsVideos | 137 | export { |
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 | |||
3 | module.exports = function (sequelize, DataTypes) { | 1 | module.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 | ||
40 | function updateMigrationVersion (newVersion, transaction, callback) { | 38 | function 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' | 1 | import { isUserUsernameValid } from '../helpers' |
2 | |||
3 | const customUsersValidators = require('../helpers/custom-validators').users | ||
4 | 2 | ||
5 | module.exports = function (sequelize, DataTypes) { | 3 | module.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' | 1 | import { values } from 'lodash' |
2 | 2 | ||
3 | const values = require('lodash/values') | 3 | import { JOB_STATES } from '../initializers' |
4 | |||
5 | const 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 | |||
3 | module.exports = function (sequelize, DataTypes) { | 1 | module.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' | 1 | import { logger } from '../helpers' |
2 | |||
3 | const 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' | 1 | import { each, waterfall } from 'async' |
2 | import { map } from 'lodash' | ||
2 | 3 | ||
3 | const each = require('async/each') | 4 | import { FRIEND_SCORE, PODS_SCORE } from '../initializers' |
4 | const map = require('lodash/map') | 5 | import { logger, isHostValid } from '../helpers' |
5 | const waterfall = require('async/waterfall') | ||
6 | |||
7 | const constants = require('../initializers/constants') | ||
8 | const logger = require('../helpers/logger') | ||
9 | const 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 | ||
108 | function incrementScores (ids, value, callback) { | 104 | function 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 | |||
5 | module.exports = function (sequelize, DataTypes) { | 1 | module.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 | ||
29 | function removeByRequestIdsAndPod (requestsIds, podId, callback) { | 25 | function 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 | ||
7 | const values = require('lodash/values') | 5 | import { values } from 'lodash' |
8 | 6 | ||
9 | const constants = require('../initializers/constants') | 7 | import { REQUEST_VIDEO_EVENT_TYPES } from '../initializers' |
10 | const customVideosValidators = require('../helpers/custom-validators').videos | 8 | import { 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 | ||
14 | const values = require('lodash/values') | 12 | import { values } from 'lodash' |
15 | 13 | ||
16 | const constants = require('../initializers/constants') | 14 | import { 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' | 1 | import { values } from 'lodash' |
2 | 2 | ||
3 | const values = require('lodash/values') | 3 | import { REQUEST_ENDPOINTS } from '../initializers' |
4 | |||
5 | const 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 | ||
102 | function removeWithEmptyTo (callback) { | 100 | function 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' | 1 | import { each } from 'async' |
2 | |||
3 | const 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 | */ |
5 | import { values } from 'lodash' | ||
7 | 6 | ||
8 | const values = require('lodash/values') | 7 | import { VIDEO_RATE_TYPES } from '../initializers' |
9 | |||
10 | const 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' | 1 | import { values } from 'lodash' |
2 | 2 | ||
3 | const values = require('lodash/values') | 3 | import { getSort } from './utils' |
4 | 4 | import { USER_ROLES } from '../initializers' | |
5 | const modelUtils = require('./utils') | 5 | import { |
6 | const constants = require('../initializers/constants') | 6 | cryptPassword, |
7 | const peertubeCrypto = require('../helpers/peertube-crypto') | 7 | comparePassword, |
8 | const 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 | ||
95 | function beforeCreateOrUpdate (user, options, next) { | 98 | function 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 | ||
107 | function isPasswordMatch (password, callback) { | 110 | function isPasswordMatch (password, callback) { |
108 | return peertubeCrypto.comparePassword(password, this.password, callback) | 111 | return comparePassword(password, this.password, callback) |
109 | } | 112 | } |
110 | 113 | ||
111 | function toFormatedJSON () { | 114 | function toFormatedJSON () { |
@@ -120,7 +123,7 @@ function toFormatedJSON () { | |||
120 | } | 123 | } |
121 | 124 | ||
122 | function isAdmin () { | 125 | function 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 | |||
3 | const utils = { | ||
4 | getSort | ||
5 | } | ||
6 | |||
7 | // Translate for example "-name" to [ 'name', 'DESC' ] | 1 | // Translate for example "-name" to [ 'name', 'DESC' ] |
8 | function getSort (value) { | 2 | function getSort (value) { |
9 | let field | 3 | let field |
@@ -22,4 +16,6 @@ function getSort (value) { | |||
22 | 16 | ||
23 | // --------------------------------------------------------------------------- | 17 | // --------------------------------------------------------------------------- |
24 | 18 | ||
25 | module.exports = utils | 19 | export { |
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' | 1 | import { CONFIG } from '../initializers' |
2 | 2 | import { isVideoAbuseReporterUsernameValid, isVideoAbuseReasonValid } from '../helpers' | |
3 | const constants = require('../initializers/constants') | 3 | import { getSort } from './utils' |
4 | const modelUtils = require('./utils') | ||
5 | const customVideosValidators = require('../helpers/custom-validators').videos | ||
6 | 4 | ||
7 | module.exports = function (sequelize, DataTypes) { | 5 | module.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' | 1 | import { getSort } from './utils' |
2 | |||
3 | const 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 | |||
5 | module.exports = function (sequelize, DataTypes) { | 1 | module.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' | 1 | import safeBuffer = require('safe-buffer') |
2 | 2 | const Buffer = safeBuffer.Buffer | |
3 | const Buffer = require('safe-buffer').Buffer | 3 | import createTorrent = require('create-torrent') |
4 | const createTorrent = require('create-torrent') | 4 | import ffmpeg = require('fluent-ffmpeg') |
5 | const ffmpeg = require('fluent-ffmpeg') | 5 | import fs = require('fs') |
6 | const fs = require('fs') | 6 | import magnetUtil = require('magnet-uri') |
7 | const magnetUtil = require('magnet-uri') | 7 | import { map, values } from 'lodash' |
8 | const map = require('lodash/map') | 8 | import { parallel, series } from 'async' |
9 | const parallel = require('async/parallel') | 9 | import parseTorrent = require('parse-torrent') |
10 | const series = require('async/series') | 10 | import { join } from 'path' |
11 | const parseTorrent = require('parse-torrent') | 11 | |
12 | const pathUtils = require('path') | ||
13 | const values = require('lodash/values') | ||
14 | |||
15 | const constants = require('../initializers/constants') | ||
16 | const logger = require('../helpers/logger') | ||
17 | const friends = require('../lib/friends') | ||
18 | const modelUtils = require('./utils') | ||
19 | const customVideosValidators = require('../helpers/custom-validators').videos | ||
20 | const db = require('../initializers/database') | 12 | const db = require('../initializers/database') |
21 | const jobScheduler = require('../lib/jobs/job-scheduler') | 13 | import { |
14 | logger, | ||
15 | isVideoNameValid, | ||
16 | isVideoCategoryValid, | ||
17 | isVideoLicenceValid, | ||
18 | isVideoLanguageValid, | ||
19 | isVideoNSFWValid, | ||
20 | isVideoDescriptionValid, | ||
21 | isVideoInfoHashValid, | ||
22 | isVideoDurationValid | ||
23 | } from '../helpers' | ||
24 | import { | ||
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' | ||
34 | import { JobScheduler, removeVideoToFriends } from '../lib' | ||
35 | import { 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 | ||
334 | function generateMagnetUri () { | 348 | function 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) { | |||
501 | function transcodeVideofile (finalCallback) { | 516 | function 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 | ||
685 | function searchAndPopulateAuthorAndPodAndTags (value, field, start, count, sort, callback) { | 700 | function 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 | ||
768 | function removeThumbnail (video, callback) { | 783 | function 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 | ||
773 | function removeFile (video, callback) { | 788 | function 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 | ||
778 | function removeTorrent (video, callback) { | 793 | function 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 | ||
783 | function removePreview (video, callback) { | 798 | function 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 | ||
788 | function createTorrentFromVideo (video, videoPath, callback) { | 803 | function 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 | ||
812 | function createPreview (video, videoPath, callback) { | 827 | function 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 | ||
816 | function createThumbnail (video, videoPath, callback) { | 831 | function 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 | ||
820 | function generateImage (video, videoPath, folder, imageName, size, callback) { | 835 | function 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 | } | ||
@@ -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 | |||
41 | abbrev@1: | 111 | abbrev@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 | ||
201 | babel-code-frame@^6.16.0: | 271 | babel-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 | ||
596 | colors@^1.1.2: | ||
597 | version "1.1.2" | ||
598 | resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" | ||
599 | |||
526 | combined-stream@^1.0.5, combined-stream@~1.0.5: | 600 | combined-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 | ||
788 | diff@3.2.0: | 862 | diff@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 | ||
873 | doctrine@^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 | |||
799 | doctrine@^2.0.0: | 880 | doctrine@^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 | ||
1141 | esutils@^1.1.6: | ||
1142 | version "1.1.6" | ||
1143 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.1.6.tgz#c01ccaa9ae4b897c6d0c3e210ae52f3c7a844375" | ||
1144 | |||
1060 | esutils@^2.0.2: | 1145 | esutils@^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 | ||
1288 | findup-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 | |||
1203 | flat-cache@^1.2.1: | 1294 | flat-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 | ||
1336 | glob@7.1.1, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5: | 1427 | glob@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 | ||
1438 | glob@~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 | |||
1347 | globals@^9.14.0: | 1448 | globals@^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 | ||
1865 | minimatch@^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 | ||
2104 | optimist@0.6.1: | 2205 | optimist@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 | ||
2536 | resolve@^1.1.6, resolve@^1.1.7: | 2637 | resolve@^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 | ||
2619 | semver@5.3.0, semver@^5.0.1, semver@~5.3.0: | 2720 | semver@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 | ||
3184 | tslib@^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 | |||
3188 | tslint-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 | |||
3194 | tslint-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 | |||
3202 | tslint@^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 | |||
3217 | tsutils@^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 | |||
3083 | tunnel-agent@^0.4.3: | 3221 | tunnel-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 | ||
3266 | typescript@~2.2.0: | ||
3267 | version "2.2.2" | ||
3268 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.2.2.tgz#606022508479b55ffa368b58fee963a03dfd7b0c" | ||
3269 | |||
3128 | uid-number@~0.0.6: | 3270 | uid-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" |