First typescript iteration
This commit is contained in:
parent
d5f345ed4c
commit
65fcc3119c
|
@ -16,3 +16,4 @@
|
|||
/ffmpeg/
|
||||
/*.sublime-project
|
||||
/*.sublime-workspace
|
||||
/dist
|
||||
|
|
16
package.json
16
package.json
|
@ -70,15 +70,31 @@
|
|||
"safe-buffer": "^5.0.1",
|
||||
"scripty": "^1.5.0",
|
||||
"sequelize": "^3.27.0",
|
||||
"typescript": "~2.2.0",
|
||||
"winston": "^2.1.1",
|
||||
"ws": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/async": "^2.0.40",
|
||||
"@types/bcrypt": "^1.0.0",
|
||||
"@types/body-parser": "^1.16.3",
|
||||
"@types/config": "^0.0.32",
|
||||
"@types/express": "^4.0.35",
|
||||
"@types/lodash": "^4.14.64",
|
||||
"@types/mkdirp": "^0.3.29",
|
||||
"@types/morgan": "^1.7.32",
|
||||
"@types/node": "^7.0.18",
|
||||
"@types/request": "^0.0.43",
|
||||
"@types/sequelize": "3",
|
||||
"@types/winston": "^2.3.2",
|
||||
"@types/ws": "^0.0.41",
|
||||
"chai": "^3.3.0",
|
||||
"commander": "^2.9.0",
|
||||
"mocha": "^3.0.1",
|
||||
"standard": "^10.0.0",
|
||||
"supertest": "^3.0.0",
|
||||
"tslint": "^5.2.0",
|
||||
"tslint-config-standard": "^5.0.2",
|
||||
"webtorrent": "^0.98.0"
|
||||
},
|
||||
"standard": {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
'use strict'
|
||||
|
||||
// ----------- Node modules -----------
|
||||
const bodyParser = require('body-parser')
|
||||
const express = require('express')
|
||||
import bodyParser = require('body-parser')
|
||||
import express = require('express')
|
||||
const expressValidator = require('express-validator')
|
||||
const http = require('http')
|
||||
const morgan = require('morgan')
|
||||
const path = require('path')
|
||||
const TrackerServer = require('bittorrent-tracker').Server
|
||||
const WebSocketServer = require('ws').Server
|
||||
import http = require('http')
|
||||
import morgan = require('morgan')
|
||||
import path = require('path')
|
||||
import bittorrentTracker = require('bittorrent-tracker')
|
||||
import { Server as WebSocketServer } from 'ws'
|
||||
|
||||
const TrackerServer = bittorrentTracker.Server
|
||||
|
||||
process.title = 'peertube'
|
||||
|
||||
|
@ -16,70 +16,62 @@ process.title = 'peertube'
|
|||
const app = express()
|
||||
|
||||
// ----------- Database -----------
|
||||
const constants = require('./server/initializers/constants')
|
||||
const logger = require('./server/helpers/logger')
|
||||
// Do not use barels because we don't want to load all modules here (we need to initialize database first)
|
||||
import { logger } from './server/helpers/logger'
|
||||
import { API_VERSION, CONFIG } from './server/initializers/constants'
|
||||
// Initialize database and models
|
||||
const db = require('./server/initializers/database')
|
||||
db.init(onDatabaseInitDone)
|
||||
|
||||
// ----------- Checker -----------
|
||||
const checker = require('./server/initializers/checker')
|
||||
import { checkMissedConfig, checkFFmpeg, checkConfig } from './server/initializers/checker'
|
||||
|
||||
const missed = checker.checkMissedConfig()
|
||||
const missed = checkMissedConfig()
|
||||
if (missed.length !== 0) {
|
||||
throw new Error('Miss some configurations keys : ' + missed)
|
||||
}
|
||||
checker.checkFFmpeg(function (err) {
|
||||
checkFFmpeg(function (err) {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
})
|
||||
|
||||
const errorMessage = checker.checkConfig()
|
||||
const errorMessage = checkConfig()
|
||||
if (errorMessage !== null) {
|
||||
throw new Error(errorMessage)
|
||||
}
|
||||
|
||||
// ----------- PeerTube modules -----------
|
||||
const customValidators = require('./server/helpers/custom-validators')
|
||||
const friends = require('./server/lib/friends')
|
||||
const installer = require('./server/initializers/installer')
|
||||
const migrator = require('./server/initializers/migrator')
|
||||
const jobScheduler = require('./server/lib/jobs/job-scheduler')
|
||||
const routes = require('./server/controllers')
|
||||
import { migrate, installApplication } from './server/initializers'
|
||||
import { JobScheduler, activateSchedulers } from './server/lib'
|
||||
import * as customValidators from './server/helpers/custom-validators'
|
||||
import { apiRouter, clientsRouter, staticRouter } from './server/controllers'
|
||||
|
||||
// ----------- Command line -----------
|
||||
|
||||
// ----------- App -----------
|
||||
|
||||
// For the logger
|
||||
app.use(morgan('combined', { stream: logger.stream }))
|
||||
// app.use(morgan('combined', { stream: logger.stream }))
|
||||
// For body requests
|
||||
app.use(bodyParser.json({ limit: '500kb' }))
|
||||
app.use(bodyParser.urlencoded({ extended: false }))
|
||||
// Validate some params for the API
|
||||
app.use(expressValidator({
|
||||
customValidators: Object.assign(
|
||||
{},
|
||||
customValidators.misc,
|
||||
customValidators.pods,
|
||||
customValidators.users,
|
||||
customValidators.videos,
|
||||
customValidators.remote.videos
|
||||
)
|
||||
customValidators: customValidators
|
||||
}))
|
||||
|
||||
// ----------- Views, routes and static files -----------
|
||||
|
||||
// API
|
||||
const apiRoute = '/api/' + constants.API_VERSION
|
||||
app.use(apiRoute, routes.api)
|
||||
const apiRoute = '/api/' + API_VERSION
|
||||
app.use(apiRoute, apiRouter)
|
||||
|
||||
// Client files
|
||||
app.use('/', routes.client)
|
||||
app.use('/', clientsRouter)
|
||||
|
||||
// Static files
|
||||
app.use('/', routes.static)
|
||||
app.use('/', staticRouter)
|
||||
|
||||
// Always serve index client page (the client is a single page application, let it handle routing)
|
||||
app.use('/*', function (req, res, next) {
|
||||
|
@ -104,7 +96,7 @@ trackerServer.on('warning', function (err) {
|
|||
})
|
||||
|
||||
const server = http.createServer(app)
|
||||
const wss = new WebSocketServer({server: server, path: '/tracker/socket'})
|
||||
const wss = new WebSocketServer({ server: server, path: '/tracker/socket' })
|
||||
wss.on('connection', function (ws) {
|
||||
trackerServer.onWebSocketConnection(ws)
|
||||
})
|
||||
|
@ -114,7 +106,7 @@ wss.on('connection', function (ws) {
|
|||
// Catch 404 and forward to error handler
|
||||
app.use(function (req, res, next) {
|
||||
const err = new Error('Not Found')
|
||||
err.status = 404
|
||||
err['status'] = 404
|
||||
next(err)
|
||||
})
|
||||
|
||||
|
@ -126,29 +118,25 @@ app.use(function (err, req, res, next) {
|
|||
// ----------- Run -----------
|
||||
|
||||
function onDatabaseInitDone () {
|
||||
const port = constants.CONFIG.LISTEN.PORT
|
||||
const port = CONFIG.LISTEN.PORT
|
||||
// Run the migration scripts if needed
|
||||
migrator.migrate(function (err) {
|
||||
migrate(function (err) {
|
||||
if (err) throw err
|
||||
|
||||
installer.installApplication(function (err) {
|
||||
installApplication(function (err) {
|
||||
if (err) throw err
|
||||
|
||||
// ----------- Make the server listening -----------
|
||||
server.listen(port, function () {
|
||||
// Activate the communication with friends
|
||||
friends.activate()
|
||||
activateSchedulers()
|
||||
|
||||
// Activate job scheduler
|
||||
jobScheduler.activate()
|
||||
JobScheduler.Instance.activate()
|
||||
|
||||
logger.info('Server listening on port %d', port)
|
||||
logger.info('Webserver: %s', constants.CONFIG.WEBSERVER.URL)
|
||||
|
||||
app.emit('ready')
|
||||
logger.info('Webserver: %s', CONFIG.WEBSERVER.URL)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = app
|
|
@ -1,19 +1,17 @@
|
|||
'use strict'
|
||||
import express = require('express')
|
||||
|
||||
const express = require('express')
|
||||
|
||||
const constants = require('../../initializers/constants')
|
||||
import { CONFIG } from '../../initializers';
|
||||
import { logger } from '../../helpers'
|
||||
const db = require('../../initializers/database')
|
||||
const logger = require('../../helpers/logger')
|
||||
|
||||
const router = express.Router()
|
||||
const clientsRouter = express.Router()
|
||||
|
||||
router.get('/local', getLocalClient)
|
||||
clientsRouter.get('/local', getLocalClient)
|
||||
|
||||
// Get the client credentials for the PeerTube front end
|
||||
function getLocalClient (req, res, next) {
|
||||
const serverHostname = constants.CONFIG.WEBSERVER.HOSTNAME
|
||||
const serverPort = constants.CONFIG.WEBSERVER.PORT
|
||||
const serverHostname = CONFIG.WEBSERVER.HOSTNAME
|
||||
const serverPort = CONFIG.WEBSERVER.PORT
|
||||
let headerHostShouldBe = serverHostname
|
||||
if (serverPort !== 80 && serverPort !== 443) {
|
||||
headerHostShouldBe += ':' + serverPort
|
||||
|
@ -38,4 +36,6 @@ function getLocalClient (req, res, next) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = router
|
||||
export {
|
||||
clientsRouter
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const express = require('express')
|
||||
|
||||
const constants = require('../../initializers/constants')
|
||||
|
||||
const router = express.Router()
|
||||
|
||||
router.get('/', getConfig)
|
||||
|
||||
// Get the client credentials for the PeerTube front end
|
||||
function getConfig (req, res, next) {
|
||||
res.json({
|
||||
signup: {
|
||||
enabled: constants.CONFIG.SIGNUP.ENABLED
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = router
|
|
@ -0,0 +1,22 @@
|
|||
import express = require('express')
|
||||
|
||||
import { CONFIG } from '../../initializers';
|
||||
|
||||
const configRouter = express.Router()
|
||||
|
||||
configRouter.get('/', getConfig)
|
||||
|
||||
// Get the client credentials for the PeerTube front end
|
||||
function getConfig (req, res, next) {
|
||||
res.json({
|
||||
signup: {
|
||||
enabled: CONFIG.SIGNUP.ENABLED
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
configRouter
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const express = require('express')
|
||||
|
||||
const utils = require('../../helpers/utils')
|
||||
|
||||
const router = express.Router()
|
||||
|
||||
const clientsController = require('./clients')
|
||||
const configController = require('./config')
|
||||
const podsController = require('./pods')
|
||||
const remoteController = require('./remote')
|
||||
const requestsController = require('./requests')
|
||||
const usersController = require('./users')
|
||||
const videosController = require('./videos')
|
||||
|
||||
router.use('/clients', clientsController)
|
||||
router.use('/config', configController)
|
||||
router.use('/pods', podsController)
|
||||
router.use('/remote', remoteController)
|
||||
router.use('/requests', requestsController)
|
||||
router.use('/users', usersController)
|
||||
router.use('/videos', videosController)
|
||||
router.use('/ping', pong)
|
||||
router.use('/*', utils.badRequest)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = router
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function pong (req, res, next) {
|
||||
return res.send('pong').status(200).end()
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
import express = require('express')
|
||||
|
||||
import { badRequest } from '../../helpers'
|
||||
|
||||
import { clientsRouter } from './clients'
|
||||
import { configRouter } from './config'
|
||||
import { podsRouter } from './pods'
|
||||
import { remoteRouter } from './remote'
|
||||
import { requestsRouter } from './requests'
|
||||
import { usersRouter } from './users'
|
||||
import { videosRouter } from './videos'
|
||||
|
||||
const apiRouter = express.Router()
|
||||
|
||||
apiRouter.use('/clients', clientsRouter)
|
||||
apiRouter.use('/config', configRouter)
|
||||
apiRouter.use('/pods', podsRouter)
|
||||
apiRouter.use('/remote', remoteRouter)
|
||||
apiRouter.use('/requests', requestsRouter)
|
||||
apiRouter.use('/users', usersRouter)
|
||||
apiRouter.use('/videos', videosRouter)
|
||||
apiRouter.use('/ping', pong)
|
||||
apiRouter.use('/*', badRequest)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export { apiRouter }
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function pong (req, res, next) {
|
||||
return res.send('pong').status(200).end()
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const express = require('express')
|
||||
const waterfall = require('async/waterfall')
|
||||
|
||||
const db = require('../../initializers/database')
|
||||
const constants = require('../../initializers/constants')
|
||||
const logger = require('../../helpers/logger')
|
||||
const peertubeCrypto = require('../../helpers/peertube-crypto')
|
||||
const utils = require('../../helpers/utils')
|
||||
const friends = require('../../lib/friends')
|
||||
const middlewares = require('../../middlewares')
|
||||
const admin = middlewares.admin
|
||||
const oAuth = middlewares.oauth
|
||||
const podsMiddleware = middlewares.pods
|
||||
const validators = middlewares.validators.pods
|
||||
|
||||
const router = express.Router()
|
||||
|
||||
router.get('/', listPods)
|
||||
router.post('/',
|
||||
podsMiddleware.setBodyHostPort, // We need to modify the host before running the validator!
|
||||
validators.podsAdd,
|
||||
addPods
|
||||
)
|
||||
router.post('/makefriends',
|
||||
oAuth.authenticate,
|
||||
admin.ensureIsAdmin,
|
||||
validators.makeFriends,
|
||||
podsMiddleware.setBodyHostsPort,
|
||||
makeFriends
|
||||
)
|
||||
router.get('/quitfriends',
|
||||
oAuth.authenticate,
|
||||
admin.ensureIsAdmin,
|
||||
quitFriends
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = router
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function addPods (req, res, next) {
|
||||
const informations = req.body
|
||||
|
||||
waterfall([
|
||||
function addPod (callback) {
|
||||
const pod = db.Pod.build(informations)
|
||||
pod.save().asCallback(function (err, podCreated) {
|
||||
// Be sure about the number of parameters for the callback
|
||||
return callback(err, podCreated)
|
||||
})
|
||||
},
|
||||
|
||||
function sendMyVideos (podCreated, callback) {
|
||||
friends.sendOwnedVideosToPod(podCreated.id)
|
||||
|
||||
callback(null)
|
||||
},
|
||||
|
||||
function fetchMyCertificate (callback) {
|
||||
peertubeCrypto.getMyPublicCert(function (err, cert) {
|
||||
if (err) {
|
||||
logger.error('Cannot read cert file.')
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
return callback(null, cert)
|
||||
})
|
||||
}
|
||||
], function (err, cert) {
|
||||
if (err) return next(err)
|
||||
|
||||
return res.json({ cert: cert, email: constants.CONFIG.ADMIN.EMAIL })
|
||||
})
|
||||
}
|
||||
|
||||
function listPods (req, res, next) {
|
||||
db.Pod.list(function (err, podsList) {
|
||||
if (err) return next(err)
|
||||
|
||||
res.json(utils.getFormatedObjects(podsList, podsList.length))
|
||||
})
|
||||
}
|
||||
|
||||
function makeFriends (req, res, next) {
|
||||
const hosts = req.body.hosts
|
||||
|
||||
friends.makeFriends(hosts, function (err) {
|
||||
if (err) {
|
||||
logger.error('Could not make friends.', { error: err })
|
||||
return
|
||||
}
|
||||
|
||||
logger.info('Made friends!')
|
||||
})
|
||||
|
||||
res.type('json').status(204).end()
|
||||
}
|
||||
|
||||
function quitFriends (req, res, next) {
|
||||
friends.quitFriends(function (err) {
|
||||
if (err) return next(err)
|
||||
|
||||
res.type('json').status(204).end()
|
||||
})
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
import express = require('express')
|
||||
import { waterfall } from 'async'
|
||||
|
||||
const db = require('../../initializers/database')
|
||||
import { CONFIG } from '../../initializers'
|
||||
import {
|
||||
logger,
|
||||
getMyPublicCert,
|
||||
getFormatedObjects
|
||||
} from '../../helpers'
|
||||
import {
|
||||
sendOwnedVideosToPod,
|
||||
makeFriends,
|
||||
quitFriends
|
||||
} from '../../lib'
|
||||
import {
|
||||
podsAddValidator,
|
||||
authenticate,
|
||||
ensureIsAdmin,
|
||||
makeFriendsValidator,
|
||||
setBodyHostPort,
|
||||
setBodyHostsPort
|
||||
} from '../../middlewares'
|
||||
|
||||
const podsRouter = express.Router()
|
||||
|
||||
podsRouter.get('/', listPods)
|
||||
podsRouter.post('/',
|
||||
setBodyHostPort, // We need to modify the host before running the validator!
|
||||
podsAddValidator,
|
||||
addPods
|
||||
)
|
||||
podsRouter.post('/makefriends',
|
||||
authenticate,
|
||||
ensureIsAdmin,
|
||||
makeFriendsValidator,
|
||||
setBodyHostsPort,
|
||||
makeFriends
|
||||
)
|
||||
podsRouter.get('/quitfriends',
|
||||
authenticate,
|
||||
ensureIsAdmin,
|
||||
quitFriends
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
podsRouter
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function addPods (req, res, next) {
|
||||
const informations = req.body
|
||||
|
||||
waterfall([
|
||||
function addPod (callback) {
|
||||
const pod = db.Pod.build(informations)
|
||||
pod.save().asCallback(function (err, podCreated) {
|
||||
// Be sure about the number of parameters for the callback
|
||||
return callback(err, podCreated)
|
||||
})
|
||||
},
|
||||
|
||||
function sendMyVideos (podCreated, callback) {
|
||||
sendOwnedVideosToPod(podCreated.id)
|
||||
|
||||
callback(null)
|
||||
},
|
||||
|
||||
function fetchMyCertificate (callback) {
|
||||
getMyPublicCert(function (err, cert) {
|
||||
if (err) {
|
||||
logger.error('Cannot read cert file.')
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
return callback(null, cert)
|
||||
})
|
||||
}
|
||||
], function (err, cert) {
|
||||
if (err) return next(err)
|
||||
|
||||
return res.json({ cert: cert, email: CONFIG.ADMIN.EMAIL })
|
||||
})
|
||||
}
|
||||
|
||||
function listPods (req, res, next) {
|
||||
db.Pod.list(function (err, podsList) {
|
||||
if (err) return next(err)
|
||||
|
||||
res.json(getFormatedObjects(podsList, podsList.length))
|
||||
})
|
||||
}
|
||||
|
||||
function makeFriendsController (req, res, next) {
|
||||
const hosts = req.body.hosts
|
||||
|
||||
makeFriends(hosts, function (err) {
|
||||
if (err) {
|
||||
logger.error('Could not make friends.', { error: err })
|
||||
return
|
||||
}
|
||||
|
||||
logger.info('Made friends!')
|
||||
})
|
||||
|
||||
res.type('json').status(204).end()
|
||||
}
|
||||
|
||||
function quitFriendsController (req, res, next) {
|
||||
quitFriends(function (err) {
|
||||
if (err) return next(err)
|
||||
|
||||
res.type('json').status(204).end()
|
||||
})
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const express = require('express')
|
||||
|
||||
const utils = require('../../../helpers/utils')
|
||||
|
||||
const router = express.Router()
|
||||
|
||||
const podsRemoteController = require('./pods')
|
||||
const videosRemoteController = require('./videos')
|
||||
|
||||
router.use('/pods', podsRemoteController)
|
||||
router.use('/videos', videosRemoteController)
|
||||
router.use('/*', utils.badRequest)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = router
|
|
@ -0,0 +1,18 @@
|
|||
import express = require('express')
|
||||
|
||||
import { badRequest } from '../../../helpers'
|
||||
|
||||
import { remotePodsRouter } from './pods'
|
||||
import { remoteVideosRouter } from './videos'
|
||||
|
||||
const remoteRouter = express.Router()
|
||||
|
||||
remoteRouter.use('/pods', remotePodsRouter)
|
||||
remoteRouter.use('/videos', remoteVideosRouter)
|
||||
remoteRouter.use('/*', badRequest)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
remoteRouter
|
||||
}
|
|
@ -1,25 +1,23 @@
|
|||
'use strict'
|
||||
|
||||
const express = require('express')
|
||||
const waterfall = require('async/waterfall')
|
||||
import express = require('express')
|
||||
import { waterfall } from 'async/waterfall'
|
||||
|
||||
const db = require('../../../initializers/database')
|
||||
const middlewares = require('../../../middlewares')
|
||||
const checkSignature = middlewares.secure.checkSignature
|
||||
const signatureValidator = middlewares.validators.remote.signature
|
||||
import { checkSignature, signatureValidator } from '../../../middlewares'
|
||||
|
||||
const router = express.Router()
|
||||
const remotePodsRouter = express.Router()
|
||||
|
||||
// Post because this is a secured request
|
||||
router.post('/remove',
|
||||
signatureValidator.signature,
|
||||
remotePodsRouter.post('/remove',
|
||||
signatureValidator,
|
||||
checkSignature,
|
||||
removePods
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = router
|
||||
export {
|
||||
remotePodsRouter
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -1,20 +1,30 @@
|
|||
'use strict'
|
||||
|
||||
const eachSeries = require('async/eachSeries')
|
||||
const express = require('express')
|
||||
const waterfall = require('async/waterfall')
|
||||
import express = require('express')
|
||||
import { eachSeries, waterfall } from 'async'
|
||||
|
||||
const db = require('../../../initializers/database')
|
||||
const constants = require('../../../initializers/constants')
|
||||
const middlewares = require('../../../middlewares')
|
||||
const secureMiddleware = middlewares.secure
|
||||
const videosValidators = middlewares.validators.remote.videos
|
||||
const signatureValidators = middlewares.validators.remote.signature
|
||||
const logger = require('../../../helpers/logger')
|
||||
const friends = require('../../../lib/friends')
|
||||
const databaseUtils = require('../../../helpers/database-utils')
|
||||
import {
|
||||
REQUEST_ENDPOINT_ACTIONS,
|
||||
REQUEST_ENDPOINTS,
|
||||
REQUEST_VIDEO_EVENT_TYPES,
|
||||
REQUEST_VIDEO_QADU_TYPES
|
||||
} from '../../../initializers'
|
||||
import {
|
||||
checkSignature,
|
||||
signatureValidator,
|
||||
remoteVideosValidator,
|
||||
remoteQaduVideosValidator,
|
||||
remoteEventsVideosValidator
|
||||
} from '../../../middlewares'
|
||||
import {
|
||||
logger,
|
||||
commitTransaction,
|
||||
retryTransactionWrapper,
|
||||
rollbackTransaction,
|
||||
startSerializableTransaction
|
||||
} from '../../../helpers'
|
||||
import { quickAndDirtyUpdatesVideoToFriends } from '../../../lib'
|
||||
|
||||
const ENDPOINT_ACTIONS = constants.REQUEST_ENDPOINT_ACTIONS[constants.REQUEST_ENDPOINTS.VIDEOS]
|
||||
const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS]
|
||||
|
||||
// Functions to call when processing a remote request
|
||||
const functionsHash = {}
|
||||
|
@ -23,32 +33,34 @@ functionsHash[ENDPOINT_ACTIONS.UPDATE] = updateRemoteVideoRetryWrapper
|
|||
functionsHash[ENDPOINT_ACTIONS.REMOVE] = removeRemoteVideo
|
||||
functionsHash[ENDPOINT_ACTIONS.REPORT_ABUSE] = reportAbuseRemoteVideo
|
||||
|
||||
const router = express.Router()
|
||||
const remoteVideosRouter = express.Router()
|
||||
|
||||
router.post('/',
|
||||
signatureValidators.signature,
|
||||
secureMiddleware.checkSignature,
|
||||
videosValidators.remoteVideos,
|
||||
remoteVideosRouter.post('/',
|
||||
signatureValidator,
|
||||
checkSignature,
|
||||
remoteVideosValidator,
|
||||
remoteVideos
|
||||
)
|
||||
|
||||
router.post('/qadu',
|
||||
signatureValidators.signature,
|
||||
secureMiddleware.checkSignature,
|
||||
videosValidators.remoteQaduVideos,
|
||||
remoteVideosRouter.post('/qadu',
|
||||
signatureValidator,
|
||||
checkSignature,
|
||||
remoteQaduVideosValidator,
|
||||
remoteVideosQadu
|
||||
)
|
||||
|
||||
router.post('/events',
|
||||
signatureValidators.signature,
|
||||
secureMiddleware.checkSignature,
|
||||
videosValidators.remoteEventsVideos,
|
||||
remoteVideosRouter.post('/events',
|
||||
signatureValidator,
|
||||
checkSignature,
|
||||
remoteEventsVideosValidator,
|
||||
remoteVideosEvents
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = router
|
||||
export {
|
||||
remoteVideosRouter
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
@ -58,7 +70,7 @@ function remoteVideos (req, res, next) {
|
|||
|
||||
// We need to process in the same order to keep consistency
|
||||
// TODO: optimization
|
||||
eachSeries(requests, function (request, callbackEach) {
|
||||
eachSeries(requests, function (request: any, callbackEach) {
|
||||
const data = request.data
|
||||
|
||||
// Get the function we need to call in order to process the request
|
||||
|
@ -81,7 +93,7 @@ function remoteVideosQadu (req, res, next) {
|
|||
const requests = req.body.data
|
||||
const fromPod = res.locals.secure.pod
|
||||
|
||||
eachSeries(requests, function (request, callbackEach) {
|
||||
eachSeries(requests, function (request: any, callbackEach) {
|
||||
const videoData = request.data
|
||||
|
||||
quickAndDirtyUpdateVideoRetryWrapper(videoData, fromPod, callbackEach)
|
||||
|
@ -96,7 +108,7 @@ function remoteVideosEvents (req, res, next) {
|
|||
const requests = req.body.data
|
||||
const fromPod = res.locals.secure.pod
|
||||
|
||||
eachSeries(requests, function (request, callbackEach) {
|
||||
eachSeries(requests, function (request: any, callbackEach) {
|
||||
const eventData = request.data
|
||||
|
||||
processVideosEventsRetryWrapper(eventData, fromPod, callbackEach)
|
||||
|
@ -113,12 +125,12 @@ function processVideosEventsRetryWrapper (eventData, fromPod, finalCallback) {
|
|||
errorMessage: 'Cannot process videos events with many retries.'
|
||||
}
|
||||
|
||||
databaseUtils.retryTransactionWrapper(processVideosEvents, options, finalCallback)
|
||||
retryTransactionWrapper(processVideosEvents, options, finalCallback)
|
||||
}
|
||||
|
||||
function processVideosEvents (eventData, fromPod, finalCallback) {
|
||||
waterfall([
|
||||
databaseUtils.startSerializableTransaction,
|
||||
startSerializableTransaction,
|
||||
|
||||
function findVideo (t, callback) {
|
||||
fetchOwnedVideo(eventData.remoteId, function (err, videoInstance) {
|
||||
|
@ -133,19 +145,19 @@ function processVideosEvents (eventData, fromPod, finalCallback) {
|
|||
let qaduType
|
||||
|
||||
switch (eventData.eventType) {
|
||||
case constants.REQUEST_VIDEO_EVENT_TYPES.VIEWS:
|
||||
case REQUEST_VIDEO_EVENT_TYPES.VIEWS:
|
||||
columnToUpdate = 'views'
|
||||
qaduType = constants.REQUEST_VIDEO_QADU_TYPES.VIEWS
|
||||
qaduType = REQUEST_VIDEO_QADU_TYPES.VIEWS
|
||||
break
|
||||
|
||||
case constants.REQUEST_VIDEO_EVENT_TYPES.LIKES:
|
||||
case REQUEST_VIDEO_EVENT_TYPES.LIKES:
|
||||
columnToUpdate = 'likes'
|
||||
qaduType = constants.REQUEST_VIDEO_QADU_TYPES.LIKES
|
||||
qaduType = REQUEST_VIDEO_QADU_TYPES.LIKES
|
||||
break
|
||||
|
||||
case constants.REQUEST_VIDEO_EVENT_TYPES.DISLIKES:
|
||||
case REQUEST_VIDEO_EVENT_TYPES.DISLIKES:
|
||||
columnToUpdate = 'dislikes'
|
||||
qaduType = constants.REQUEST_VIDEO_QADU_TYPES.DISLIKES
|
||||
qaduType = REQUEST_VIDEO_QADU_TYPES.DISLIKES
|
||||
break
|
||||
|
||||
default:
|
||||
|
@ -168,17 +180,17 @@ function processVideosEvents (eventData, fromPod, finalCallback) {
|
|||
}
|
||||
]
|
||||
|
||||
friends.quickAndDirtyUpdatesVideoToFriends(qadusParams, t, function (err) {
|
||||
quickAndDirtyUpdatesVideoToFriends(qadusParams, t, function (err) {
|
||||
return callback(err, t)
|
||||
})
|
||||
},
|
||||
|
||||
databaseUtils.commitTransaction
|
||||
commitTransaction
|
||||
|
||||
], function (err, t) {
|
||||
if (err) {
|
||||
logger.debug('Cannot process a video event.', { error: err })
|
||||
return databaseUtils.rollbackTransaction(err, t, finalCallback)
|
||||
return rollbackTransaction(err, t, finalCallback)
|
||||
}
|
||||
|
||||
logger.info('Remote video event processed for video %s.', eventData.remoteId)
|
||||
|
@ -192,14 +204,14 @@ function quickAndDirtyUpdateVideoRetryWrapper (videoData, fromPod, finalCallback
|
|||
errorMessage: 'Cannot update quick and dirty the remote video with many retries.'
|
||||
}
|
||||
|
||||
databaseUtils.retryTransactionWrapper(quickAndDirtyUpdateVideo, options, finalCallback)
|
||||
retryTransactionWrapper(quickAndDirtyUpdateVideo, options, finalCallback)
|
||||
}
|
||||
|
||||
function quickAndDirtyUpdateVideo (videoData, fromPod, finalCallback) {
|
||||
let videoName
|
||||
|
||||
waterfall([
|
||||
databaseUtils.startSerializableTransaction,
|
||||
startSerializableTransaction,
|
||||
|
||||
function findVideo (t, callback) {
|
||||
fetchRemoteVideo(fromPod.host, videoData.remoteId, function (err, videoInstance) {
|
||||
|
@ -229,12 +241,12 @@ function quickAndDirtyUpdateVideo (videoData, fromPod, finalCallback) {
|
|||
})
|
||||
},
|
||||
|
||||
databaseUtils.commitTransaction
|
||||
commitTransaction
|
||||
|
||||
], function (err, t) {
|
||||
if (err) {
|
||||
logger.debug('Cannot quick and dirty update the remote video.', { error: err })
|
||||
return databaseUtils.rollbackTransaction(err, t, finalCallback)
|
||||
return rollbackTransaction(err, t, finalCallback)
|
||||
}
|
||||
|
||||
logger.info('Remote video %s quick and dirty updated', videoName)
|
||||
|
@ -249,7 +261,7 @@ function addRemoteVideoRetryWrapper (videoToCreateData, fromPod, finalCallback)
|
|||
errorMessage: 'Cannot insert the remote video with many retries.'
|
||||
}
|
||||
|
||||
databaseUtils.retryTransactionWrapper(addRemoteVideo, options, finalCallback)
|
||||
retryTransactionWrapper(addRemoteVideo, options, finalCallback)
|
||||
}
|
||||
|
||||
function addRemoteVideo (videoToCreateData, fromPod, finalCallback) {
|
||||
|
@ -257,7 +269,7 @@ function addRemoteVideo (videoToCreateData, fromPod, finalCallback) {
|
|||
|
||||
waterfall([
|
||||
|
||||
databaseUtils.startSerializableTransaction,
|
||||
startSerializableTransaction,
|
||||
|
||||
function assertRemoteIdAndHostUnique (t, callback) {
|
||||
db.Video.loadByHostAndRemoteId(fromPod.host, videoToCreateData.remoteId, function (err, video) {
|
||||
|
@ -345,13 +357,13 @@ function addRemoteVideo (videoToCreateData, fromPod, finalCallback) {
|
|||
})
|
||||
},
|
||||
|
||||
databaseUtils.commitTransaction
|
||||
commitTransaction
|
||||
|
||||
], function (err, t) {
|
||||
if (err) {
|
||||
// This is just a debug because we will retry the insert
|
||||
logger.debug('Cannot insert the remote video.', { error: err })
|
||||
return databaseUtils.rollbackTransaction(err, t, finalCallback)
|
||||
return rollbackTransaction(err, t, finalCallback)
|
||||
}
|
||||
|
||||
logger.info('Remote video %s inserted.', videoToCreateData.name)
|
||||
|
@ -366,7 +378,7 @@ function updateRemoteVideoRetryWrapper (videoAttributesToUpdate, fromPod, finalC
|
|||
errorMessage: 'Cannot update the remote video with many retries'
|
||||
}
|
||||
|
||||
databaseUtils.retryTransactionWrapper(updateRemoteVideo, options, finalCallback)
|
||||
retryTransactionWrapper(updateRemoteVideo, options, finalCallback)
|
||||
}
|
||||
|
||||
function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) {
|
||||
|
@ -374,7 +386,7 @@ function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) {
|
|||
|
||||
waterfall([
|
||||
|
||||
databaseUtils.startSerializableTransaction,
|
||||
startSerializableTransaction,
|
||||
|
||||
function findVideo (t, callback) {
|
||||
fetchRemoteVideo(fromPod.host, videoAttributesToUpdate.remoteId, function (err, videoInstance) {
|
||||
|
@ -421,13 +433,13 @@ function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) {
|
|||
})
|
||||
},
|
||||
|
||||
databaseUtils.commitTransaction
|
||||
commitTransaction
|
||||
|
||||
], function (err, t) {
|
||||
if (err) {
|
||||
// This is just a debug because we will retry the insert
|
||||
logger.debug('Cannot update the remote video.', { error: err })
|
||||
return databaseUtils.rollbackTransaction(err, t, finalCallback)
|
||||
return rollbackTransaction(err, t, finalCallback)
|
||||
}
|
||||
|
||||
logger.info('Remote video %s updated', videoAttributesToUpdate.name)
|
|
@ -1,32 +1,34 @@
|
|||
'use strict'
|
||||
import express = require('express')
|
||||
import { parallel } from 'async'
|
||||
|
||||
const express = require('express')
|
||||
const parallel = require('async/parallel')
|
||||
import {
|
||||
getRequestScheduler,
|
||||
getRequestVideoQaduScheduler,
|
||||
getRequestVideoEventScheduler
|
||||
} from '../../lib'
|
||||
import { authenticate, ensureIsAdmin } from '../../middlewares'
|
||||
|
||||
const friends = require('../../lib/friends')
|
||||
const middlewares = require('../../middlewares')
|
||||
const admin = middlewares.admin
|
||||
const oAuth = middlewares.oauth
|
||||
const requestsRouter = express.Router()
|
||||
|
||||
const router = express.Router()
|
||||
|
||||
router.get('/stats',
|
||||
oAuth.authenticate,
|
||||
admin.ensureIsAdmin,
|
||||
requestsRouter.get('/stats',
|
||||
authenticate,
|
||||
ensureIsAdmin,
|
||||
getStatsRequests
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = router
|
||||
export {
|
||||
requestsRouter
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function getStatsRequests (req, res, next) {
|
||||
parallel({
|
||||
requestScheduler: buildRequestSchedulerFunction(friends.getRequestScheduler()),
|
||||
requestVideoQaduScheduler: buildRequestSchedulerFunction(friends.getRequestVideoQaduScheduler()),
|
||||
requestVideoEventScheduler: buildRequestSchedulerFunction(friends.getRequestVideoEventScheduler())
|
||||
requestScheduler: buildRequestSchedulerFunction(getRequestScheduler()),
|
||||
requestVideoQaduScheduler: buildRequestSchedulerFunction(getRequestVideoQaduScheduler()),
|
||||
requestVideoEventScheduler: buildRequestSchedulerFunction(getRequestVideoEventScheduler())
|
||||
}, function (err, result) {
|
||||
if (err) return next(err)
|
||||
|
|
@ -1,79 +1,83 @@
|
|||
'use strict'
|
||||
import express = require('express')
|
||||
import { waterfall } from 'async'
|
||||
|
||||
const express = require('express')
|
||||
const waterfall = require('async/waterfall')
|
||||
|
||||
const constants = require('../../initializers/constants')
|
||||
const db = require('../../initializers/database')
|
||||
const logger = require('../../helpers/logger')
|
||||
const utils = require('../../helpers/utils')
|
||||
const middlewares = require('../../middlewares')
|
||||
const admin = middlewares.admin
|
||||
const oAuth = middlewares.oauth
|
||||
const pagination = middlewares.pagination
|
||||
const sort = middlewares.sort
|
||||
const validatorsPagination = middlewares.validators.pagination
|
||||
const validatorsSort = middlewares.validators.sort
|
||||
const validatorsUsers = middlewares.validators.users
|
||||
import { CONFIG, USER_ROLES } from '../../initializers'
|
||||
import { logger, getFormatedObjects } from '../../helpers'
|
||||
import {
|
||||
authenticate,
|
||||
ensureIsAdmin,
|
||||
usersAddValidator,
|
||||
usersUpdateValidator,
|
||||
usersRemoveValidator,
|
||||
usersVideoRatingValidator,
|
||||
paginationValidator,
|
||||
setPagination,
|
||||
usersSortValidator,
|
||||
setUsersSort,
|
||||
token
|
||||
} from '../../middlewares'
|
||||
|
||||
const router = express.Router()
|
||||
const usersRouter = express.Router()
|
||||
|
||||
router.get('/me',
|
||||
oAuth.authenticate,
|
||||
usersRouter.get('/me',
|
||||
authenticate,
|
||||
getUserInformation
|
||||
)
|
||||
|
||||
router.get('/me/videos/:videoId/rating',
|
||||
oAuth.authenticate,
|
||||
validatorsUsers.usersVideoRating,
|
||||
usersRouter.get('/me/videos/:videoId/rating',
|
||||
authenticate,
|
||||
usersVideoRatingValidator,
|
||||
getUserVideoRating
|
||||
)
|
||||
|
||||
router.get('/',
|
||||
validatorsPagination.pagination,
|
||||
validatorsSort.usersSort,
|
||||
sort.setUsersSort,
|
||||
pagination.setPagination,
|
||||
usersRouter.get('/',
|
||||
paginationValidator,
|
||||
usersSortValidator,
|
||||
setUsersSort,
|
||||
setPagination,
|
||||
listUsers
|
||||
)
|
||||
|
||||
router.post('/',
|
||||
oAuth.authenticate,
|
||||
admin.ensureIsAdmin,
|
||||
validatorsUsers.usersAdd,
|
||||
usersRouter.post('/',
|
||||
authenticate,
|
||||
ensureIsAdmin,
|
||||
usersAddValidator,
|
||||
createUser
|
||||
)
|
||||
|
||||
router.post('/register',
|
||||
usersRouter.post('/register',
|
||||
ensureRegistrationEnabled,
|
||||
validatorsUsers.usersAdd,
|
||||
usersAddValidator,
|
||||
createUser
|
||||
)
|
||||
|
||||
router.put('/:id',
|
||||
oAuth.authenticate,
|
||||
validatorsUsers.usersUpdate,
|
||||
usersRouter.put('/:id',
|
||||
authenticate,
|
||||
usersUpdateValidator,
|
||||
updateUser
|
||||
)
|
||||
|
||||
router.delete('/:id',
|
||||
oAuth.authenticate,
|
||||
admin.ensureIsAdmin,
|
||||
validatorsUsers.usersRemove,
|
||||
usersRouter.delete('/:id',
|
||||
authenticate,
|
||||
ensureIsAdmin,
|
||||
usersRemoveValidator,
|
||||
removeUser
|
||||
)
|
||||
|
||||
router.post('/token', oAuth.token, success)
|
||||
usersRouter.post('/token', token, success)
|
||||
// TODO: Once https://github.com/oauthjs/node-oauth2-server/pull/289 is merged, implement revoke token route
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = router
|
||||
export {
|
||||
usersRouter
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function ensureRegistrationEnabled (req, res, next) {
|
||||
const registrationEnabled = constants.CONFIG.SIGNUP.ENABLED
|
||||
const registrationEnabled = CONFIG.SIGNUP.ENABLED
|
||||
|
||||
if (registrationEnabled === true) {
|
||||
return next()
|
||||
|
@ -88,7 +92,7 @@ function createUser (req, res, next) {
|
|||
password: req.body.password,
|
||||
email: req.body.email,
|
||||
displayNSFW: false,
|
||||
role: constants.USER_ROLES.USER
|
||||
role: USER_ROLES.USER
|
||||
})
|
||||
|
||||
user.save().asCallback(function (err, createdUser) {
|
||||
|
@ -126,7 +130,7 @@ function listUsers (req, res, next) {
|
|||
db.User.listForApi(req.query.start, req.query.count, req.query.sort, function (err, usersList, usersTotal) {
|
||||
if (err) return next(err)
|
||||
|
||||
res.json(utils.getFormatedObjects(usersList, usersTotal))
|
||||
res.json(getFormatedObjects(usersList, usersTotal))
|
||||
})
|
||||
}
|
||||
|
|
@ -1,43 +1,48 @@
|
|||
'use strict'
|
||||
|
||||
const express = require('express')
|
||||
const waterfall = require('async/waterfall')
|
||||
import express = require('express')
|
||||
import { waterfall } from 'async'
|
||||
|
||||
const db = require('../../../initializers/database')
|
||||
const logger = require('../../../helpers/logger')
|
||||
const friends = require('../../../lib/friends')
|
||||
const middlewares = require('../../../middlewares')
|
||||
const admin = middlewares.admin
|
||||
const oAuth = middlewares.oauth
|
||||
const pagination = middlewares.pagination
|
||||
const validators = middlewares.validators
|
||||
const validatorsPagination = validators.pagination
|
||||
const validatorsSort = validators.sort
|
||||
const validatorsVideos = validators.videos
|
||||
const sort = middlewares.sort
|
||||
const databaseUtils = require('../../../helpers/database-utils')
|
||||
const utils = require('../../../helpers/utils')
|
||||
import friends = require('../../../lib/friends')
|
||||
import {
|
||||
logger,
|
||||
getFormatedObjects,
|
||||
retryTransactionWrapper,
|
||||
startSerializableTransaction,
|
||||
commitTransaction,
|
||||
rollbackTransaction
|
||||
} from '../../../helpers'
|
||||
import {
|
||||
authenticate,
|
||||
ensureIsAdmin,
|
||||
paginationValidator,
|
||||
videoAbuseReportValidator,
|
||||
videoAbusesSortValidator,
|
||||
setVideoAbusesSort,
|
||||
setPagination
|
||||
} from '../../../middlewares'
|
||||
|
||||
const router = express.Router()
|
||||
const abuseVideoRouter = express.Router()
|
||||
|
||||
router.get('/abuse',
|
||||
oAuth.authenticate,
|
||||
admin.ensureIsAdmin,
|
||||
validatorsPagination.pagination,
|
||||
validatorsSort.videoAbusesSort,
|
||||
sort.setVideoAbusesSort,
|
||||
pagination.setPagination,
|
||||
abuseVideoRouter.get('/abuse',
|
||||
authenticate,
|
||||
ensureIsAdmin,
|
||||
paginationValidator,
|
||||
videoAbusesSortValidator,
|
||||
setVideoAbusesSort,
|
||||
setPagination,
|
||||
listVideoAbuses
|
||||
)
|
||||
router.post('/:id/abuse',
|
||||
oAuth.authenticate,
|
||||
validatorsVideos.videoAbuseReport,
|
||||
abuseVideoRouter.post('/:id/abuse',
|
||||
authenticate,
|
||||
videoAbuseReportValidator,
|
||||
reportVideoAbuseRetryWrapper
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = router
|
||||
export {
|
||||
abuseVideoRouter
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
@ -45,7 +50,7 @@ function listVideoAbuses (req, res, next) {
|
|||
db.VideoAbuse.listForApi(req.query.start, req.query.count, req.query.sort, function (err, abusesList, abusesTotal) {
|
||||
if (err) return next(err)
|
||||
|
||||
res.json(utils.getFormatedObjects(abusesList, abusesTotal))
|
||||
res.json(getFormatedObjects(abusesList, abusesTotal))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -55,7 +60,7 @@ function reportVideoAbuseRetryWrapper (req, res, next) {
|
|||
errorMessage: 'Cannot report abuse to the video with many retries.'
|
||||
}
|
||||
|
||||
databaseUtils.retryTransactionWrapper(reportVideoAbuse, options, function (err) {
|
||||
retryTransactionWrapper(reportVideoAbuse, options, function (err) {
|
||||
if (err) return next(err)
|
||||
|
||||
return res.type('json').status(204).end()
|
||||
|
@ -75,7 +80,7 @@ function reportVideoAbuse (req, res, finalCallback) {
|
|||
|
||||
waterfall([
|
||||
|
||||
databaseUtils.startSerializableTransaction,
|
||||
startSerializableTransaction,
|
||||
|
||||
function createAbuse (t, callback) {
|
||||
db.VideoAbuse.create(abuse).asCallback(function (err, abuse) {
|
||||
|
@ -98,12 +103,12 @@ function reportVideoAbuse (req, res, finalCallback) {
|
|||
return callback(null, t)
|
||||
},
|
||||
|
||||
databaseUtils.commitTransaction
|
||||
commitTransaction
|
||||
|
||||
], function andFinally (err, t) {
|
||||
if (err) {
|
||||
logger.debug('Cannot update the video.', { error: err })
|
||||
return databaseUtils.rollbackTransaction(err, t, finalCallback)
|
||||
return rollbackTransaction(err, t, finalCallback)
|
||||
}
|
||||
|
||||
logger.info('Abuse report for video %s created.', videoInstance.name)
|
|
@ -1,27 +1,27 @@
|
|||
'use strict'
|
||||
|
||||
const express = require('express')
|
||||
import express = require('express')
|
||||
|
||||
const db = require('../../../initializers/database')
|
||||
const logger = require('../../../helpers/logger')
|
||||
const middlewares = require('../../../middlewares')
|
||||
const admin = middlewares.admin
|
||||
const oAuth = middlewares.oauth
|
||||
const validators = middlewares.validators
|
||||
const validatorsVideos = validators.videos
|
||||
import { logger } from '../../../helpers'
|
||||
import {
|
||||
authenticate,
|
||||
ensureIsAdmin,
|
||||
videosBlacklistValidator
|
||||
} from '../../../middlewares'
|
||||
|
||||
const router = express.Router()
|
||||
const blacklistRouter = express.Router()
|
||||
|
||||
router.post('/:id/blacklist',
|
||||
oAuth.authenticate,
|
||||
admin.ensureIsAdmin,
|
||||
validatorsVideos.videosBlacklist,
|
||||
blacklistRouter.post('/:id/blacklist',
|
||||
authenticate,
|
||||
ensureIsAdmin,
|
||||
videosBlacklistValidator,
|
||||
addVideoToBlacklist
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = router
|
||||
export {
|
||||
blacklistRouter
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -1,37 +1,57 @@
|
|||
'use strict'
|
||||
import express = require('express')
|
||||
import fs = require('fs')
|
||||
import multer = require('multer')
|
||||
import path = require('path')
|
||||
import { waterfall } from 'async'
|
||||
|
||||
const express = require('express')
|
||||
const fs = require('fs')
|
||||
const multer = require('multer')
|
||||
const path = require('path')
|
||||
const waterfall = require('async/waterfall')
|
||||
|
||||
const constants = require('../../../initializers/constants')
|
||||
const db = require('../../../initializers/database')
|
||||
const logger = require('../../../helpers/logger')
|
||||
const friends = require('../../../lib/friends')
|
||||
const middlewares = require('../../../middlewares')
|
||||
const oAuth = middlewares.oauth
|
||||
const pagination = middlewares.pagination
|
||||
const validators = middlewares.validators
|
||||
const validatorsPagination = validators.pagination
|
||||
const validatorsSort = validators.sort
|
||||
const validatorsVideos = validators.videos
|
||||
const search = middlewares.search
|
||||
const sort = middlewares.sort
|
||||
const databaseUtils = require('../../../helpers/database-utils')
|
||||
const utils = require('../../../helpers/utils')
|
||||
import {
|
||||
CONFIG,
|
||||
REQUEST_VIDEO_QADU_TYPES,
|
||||
REQUEST_VIDEO_EVENT_TYPES,
|
||||
VIDEO_CATEGORIES,
|
||||
VIDEO_LICENCES,
|
||||
VIDEO_LANGUAGES
|
||||
} from '../../../initializers'
|
||||
import {
|
||||
addEventToRemoteVideo,
|
||||
quickAndDirtyUpdateVideoToFriends,
|
||||
addVideoToFriends,
|
||||
updateVideoToFriends
|
||||
} from '../../../lib'
|
||||
import {
|
||||
authenticate,
|
||||
paginationValidator,
|
||||
videosSortValidator,
|
||||
setVideosSort,
|
||||
setPagination,
|
||||
setVideosSearch,
|
||||
videosUpdateValidator,
|
||||
videosSearchValidator,
|
||||
videosAddValidator,
|
||||
videosGetValidator,
|
||||
videosRemoveValidator
|
||||
} from '../../../middlewares'
|
||||
import {
|
||||
logger,
|
||||
commitTransaction,
|
||||
retryTransactionWrapper,
|
||||
rollbackTransaction,
|
||||
startSerializableTransaction,
|
||||
generateRandomString,
|
||||
getFormatedObjects
|
||||
} from '../../../helpers'
|
||||
|
||||
const abuseController = require('./abuse')
|
||||
const blacklistController = require('./blacklist')
|
||||
const rateController = require('./rate')
|
||||
import { abuseVideoRouter } from './abuse'
|
||||
import { blacklistRouter } from './blacklist'
|
||||
import { rateVideoRouter } from './rate'
|
||||
|
||||
const router = express.Router()
|
||||
const videosRouter = express.Router()
|
||||
|
||||
// multer configuration
|
||||
const storage = multer.diskStorage({
|
||||
destination: function (req, file, cb) {
|
||||
cb(null, constants.CONFIG.STORAGE.VIDEOS_DIR)
|
||||
cb(null, CONFIG.STORAGE.VIDEOS_DIR)
|
||||
},
|
||||
|
||||
filename: function (req, file, cb) {
|
||||
|
@ -39,7 +59,7 @@ const storage = multer.diskStorage({
|
|||
if (file.mimetype === 'video/webm') extension = 'webm'
|
||||
else if (file.mimetype === 'video/mp4') extension = 'mp4'
|
||||
else if (file.mimetype === 'video/ogg') extension = 'ogv'
|
||||
utils.generateRandomString(16, function (err, randomString) {
|
||||
generateRandomString(16, function (err, randomString) {
|
||||
const fieldname = err ? undefined : randomString
|
||||
cb(null, fieldname + '.' + extension)
|
||||
})
|
||||
|
@ -48,70 +68,72 @@ const storage = multer.diskStorage({
|
|||
|
||||
const reqFiles = multer({ storage: storage }).fields([{ name: 'videofile', maxCount: 1 }])
|
||||
|
||||
router.use('/', abuseController)
|
||||
router.use('/', blacklistController)
|
||||
router.use('/', rateController)
|
||||
videosRouter.use('/', abuseVideoRouter)
|
||||
videosRouter.use('/', blacklistRouter)
|
||||
videosRouter.use('/', rateVideoRouter)
|
||||
|
||||
router.get('/categories', listVideoCategories)
|
||||
router.get('/licences', listVideoLicences)
|
||||
router.get('/languages', listVideoLanguages)
|
||||
videosRouter.get('/categories', listVideoCategories)
|
||||
videosRouter.get('/licences', listVideoLicences)
|
||||
videosRouter.get('/languages', listVideoLanguages)
|
||||
|
||||
router.get('/',
|
||||
validatorsPagination.pagination,
|
||||
validatorsSort.videosSort,
|
||||
sort.setVideosSort,
|
||||
pagination.setPagination,
|
||||
videosRouter.get('/',
|
||||
paginationValidator,
|
||||
videosSortValidator,
|
||||
setVideosSort,
|
||||
setPagination,
|
||||
listVideos
|
||||
)
|
||||
router.put('/:id',
|
||||
oAuth.authenticate,
|
||||
videosRouter.put('/:id',
|
||||
authenticate,
|
||||
reqFiles,
|
||||
validatorsVideos.videosUpdate,
|
||||
videosUpdateValidator,
|
||||
updateVideoRetryWrapper
|
||||
)
|
||||
router.post('/',
|
||||
oAuth.authenticate,
|
||||
videosRouter.post('/',
|
||||
authenticate,
|
||||
reqFiles,
|
||||
validatorsVideos.videosAdd,
|
||||
videosAddValidator,
|
||||
addVideoRetryWrapper
|
||||
)
|
||||
router.get('/:id',
|
||||
validatorsVideos.videosGet,
|
||||
videosRouter.get('/:id',
|
||||
videosGetValidator,
|
||||
getVideo
|
||||
)
|
||||
|
||||
router.delete('/:id',
|
||||
oAuth.authenticate,
|
||||
validatorsVideos.videosRemove,
|
||||
videosRouter.delete('/:id',
|
||||
authenticate,
|
||||
videosRemoveValidator,
|
||||
removeVideo
|
||||
)
|
||||
|
||||
router.get('/search/:value',
|
||||
validatorsVideos.videosSearch,
|
||||
validatorsPagination.pagination,
|
||||
validatorsSort.videosSort,
|
||||
sort.setVideosSort,
|
||||
pagination.setPagination,
|
||||
search.setVideosSearch,
|
||||
videosRouter.get('/search/:value',
|
||||
videosSearchValidator,
|
||||
paginationValidator,
|
||||
videosSortValidator,
|
||||
setVideosSort,
|
||||
setPagination,
|
||||
setVideosSearch,
|
||||
searchVideos
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = router
|
||||
export {
|
||||
videosRouter
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function listVideoCategories (req, res, next) {
|
||||
res.json(constants.VIDEO_CATEGORIES)
|
||||
res.json(VIDEO_CATEGORIES)
|
||||
}
|
||||
|
||||
function listVideoLicences (req, res, next) {
|
||||
res.json(constants.VIDEO_LICENCES)
|
||||
res.json(VIDEO_LICENCES)
|
||||
}
|
||||
|
||||
function listVideoLanguages (req, res, next) {
|
||||
res.json(constants.VIDEO_LANGUAGES)
|
||||
res.json(VIDEO_LANGUAGES)
|
||||
}
|
||||
|
||||
// Wrapper to video add that retry the function if there is a database error
|
||||
|
@ -122,7 +144,7 @@ function addVideoRetryWrapper (req, res, next) {
|
|||
errorMessage: 'Cannot insert the video with many retries.'
|
||||
}
|
||||
|
||||
databaseUtils.retryTransactionWrapper(addVideo, options, function (err) {
|
||||
retryTransactionWrapper(addVideo, options, function (err) {
|
||||
if (err) return next(err)
|
||||
|
||||
// TODO : include Location of the new video -> 201
|
||||
|
@ -135,7 +157,7 @@ function addVideo (req, res, videoFile, finalCallback) {
|
|||
|
||||
waterfall([
|
||||
|
||||
databaseUtils.startSerializableTransaction,
|
||||
startSerializableTransaction,
|
||||
|
||||
function findOrCreateAuthor (t, callback) {
|
||||
const user = res.locals.oauth.token.User
|
||||
|
@ -179,7 +201,7 @@ function addVideo (req, res, videoFile, finalCallback) {
|
|||
|
||||
// Set the videoname the same as the id
|
||||
function renameVideoFile (t, author, tagInstances, video, callback) {
|
||||
const videoDir = constants.CONFIG.STORAGE.VIDEOS_DIR
|
||||
const videoDir = CONFIG.STORAGE.VIDEOS_DIR
|
||||
const source = path.join(videoDir, videoFile.filename)
|
||||
const destination = path.join(videoDir, video.getVideoFilename())
|
||||
|
||||
|
@ -218,25 +240,25 @@ function addVideo (req, res, videoFile, finalCallback) {
|
|||
|
||||
function sendToFriends (t, video, callback) {
|
||||
// Let transcoding job send the video to friends because the videofile extension might change
|
||||
if (constants.CONFIG.TRANSCODING.ENABLED === true) return callback(null, t)
|
||||
if (CONFIG.TRANSCODING.ENABLED === true) return callback(null, t)
|
||||
|
||||
video.toAddRemoteJSON(function (err, remoteVideo) {
|
||||
if (err) return callback(err)
|
||||
|
||||
// Now we'll add the video's meta data to our friends
|
||||
friends.addVideoToFriends(remoteVideo, t, function (err) {
|
||||
addVideoToFriends(remoteVideo, t, function (err) {
|
||||
return callback(err, t)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
databaseUtils.commitTransaction
|
||||
commitTransaction
|
||||
|
||||
], function andFinally (err, t) {
|
||||
if (err) {
|
||||
// This is just a debug because we will retry the insert
|
||||
logger.debug('Cannot insert the video.', { error: err })
|
||||
return databaseUtils.rollbackTransaction(err, t, finalCallback)
|
||||
return rollbackTransaction(err, t, finalCallback)
|
||||
}
|
||||
|
||||
logger.info('Video with name %s created.', videoInfos.name)
|
||||
|
@ -250,7 +272,7 @@ function updateVideoRetryWrapper (req, res, next) {
|
|||
errorMessage: 'Cannot update the video with many retries.'
|
||||
}
|
||||
|
||||
databaseUtils.retryTransactionWrapper(updateVideo, options, function (err) {
|
||||
retryTransactionWrapper(updateVideo, options, function (err) {
|
||||
if (err) return next(err)
|
||||
|
||||
// TODO : include Location of the new video -> 201
|
||||
|
@ -265,7 +287,7 @@ function updateVideo (req, res, finalCallback) {
|
|||
|
||||
waterfall([
|
||||
|
||||
databaseUtils.startSerializableTransaction,
|
||||
startSerializableTransaction,
|
||||
|
||||
function findOrCreateTags (t, callback) {
|
||||
if (videoInfosToUpdate.tags) {
|
||||
|
@ -312,12 +334,12 @@ function updateVideo (req, res, finalCallback) {
|
|||
const json = videoInstance.toUpdateRemoteJSON()
|
||||
|
||||
// Now we'll update the video's meta data to our friends
|
||||
friends.updateVideoToFriends(json, t, function (err) {
|
||||
updateVideoToFriends(json, t, function (err) {
|
||||
return callback(err, t)
|
||||
})
|
||||
},
|
||||
|
||||
databaseUtils.commitTransaction
|
||||
commitTransaction
|
||||
|
||||
], function andFinally (err, t) {
|
||||
if (err) {
|
||||
|
@ -331,7 +353,7 @@ function updateVideo (req, res, finalCallback) {
|
|||
videoInstance.set(key, value)
|
||||
})
|
||||
|
||||
return databaseUtils.rollbackTransaction(err, t, finalCallback)
|
||||
return rollbackTransaction(err, t, finalCallback)
|
||||
}
|
||||
|
||||
logger.info('Video with name %s updated.', videoInfosToUpdate.name)
|
||||
|
@ -354,17 +376,17 @@ function getVideo (req, res, next) {
|
|||
// For example, only add a view when a user watch a video during 30s etc
|
||||
const qaduParams = {
|
||||
videoId: videoInstance.id,
|
||||
type: constants.REQUEST_VIDEO_QADU_TYPES.VIEWS
|
||||
type: REQUEST_VIDEO_QADU_TYPES.VIEWS
|
||||
}
|
||||
friends.quickAndDirtyUpdateVideoToFriends(qaduParams)
|
||||
quickAndDirtyUpdateVideoToFriends(qaduParams)
|
||||
})
|
||||
} else {
|
||||
// Just send the event to our friends
|
||||
const eventParams = {
|
||||
videoId: videoInstance.id,
|
||||
type: constants.REQUEST_VIDEO_EVENT_TYPES.VIEWS
|
||||
type: REQUEST_VIDEO_EVENT_TYPES.VIEWS
|
||||
}
|
||||
friends.addEventToRemoteVideo(eventParams)
|
||||
addEventToRemoteVideo(eventParams)
|
||||
}
|
||||
|
||||
// Do not wait the view system
|
||||
|
@ -375,7 +397,7 @@ function listVideos (req, res, next) {
|
|||
db.Video.listForApi(req.query.start, req.query.count, req.query.sort, function (err, videosList, videosTotal) {
|
||||
if (err) return next(err)
|
||||
|
||||
res.json(utils.getFormatedObjects(videosList, videosTotal))
|
||||
res.json(getFormatedObjects(videosList, videosTotal))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -398,7 +420,7 @@ function searchVideos (req, res, next) {
|
|||
function (err, videosList, videosTotal) {
|
||||
if (err) return next(err)
|
||||
|
||||
res.json(utils.getFormatedObjects(videosList, videosTotal))
|
||||
res.json(getFormatedObjects(videosList, videosTotal))
|
||||
}
|
||||
)
|
||||
}
|
|
@ -1,29 +1,41 @@
|
|||
'use strict'
|
||||
import express = require('express')
|
||||
import { waterfall } from 'async'
|
||||
|
||||
const express = require('express')
|
||||
const waterfall = require('async/waterfall')
|
||||
|
||||
const constants = require('../../../initializers/constants')
|
||||
const db = require('../../../initializers/database')
|
||||
const logger = require('../../../helpers/logger')
|
||||
const friends = require('../../../lib/friends')
|
||||
const middlewares = require('../../../middlewares')
|
||||
const oAuth = middlewares.oauth
|
||||
const validators = middlewares.validators
|
||||
const validatorsVideos = validators.videos
|
||||
const databaseUtils = require('../../../helpers/database-utils')
|
||||
import {
|
||||
logger,
|
||||
retryTransactionWrapper,
|
||||
startSerializableTransaction,
|
||||
commitTransaction,
|
||||
rollbackTransaction
|
||||
} from '../../../helpers'
|
||||
import {
|
||||
VIDEO_RATE_TYPES,
|
||||
REQUEST_VIDEO_EVENT_TYPES,
|
||||
REQUEST_VIDEO_QADU_TYPES
|
||||
} from '../../../initializers'
|
||||
import {
|
||||
addEventsToRemoteVideo,
|
||||
quickAndDirtyUpdatesVideoToFriends
|
||||
} from '../../../lib'
|
||||
import {
|
||||
authenticate,
|
||||
videoRateValidator
|
||||
} from '../../../middlewares'
|
||||
|
||||
const router = express.Router()
|
||||
const rateVideoRouter = express.Router()
|
||||
|
||||
router.put('/:id/rate',
|
||||
oAuth.authenticate,
|
||||
validatorsVideos.videoRate,
|
||||
rateVideoRouter.put('/:id/rate',
|
||||
authenticate,
|
||||
videoRateValidator,
|
||||
rateVideoRetryWrapper
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = router
|
||||
export {
|
||||
rateVideoRouter
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
@ -33,7 +45,7 @@ function rateVideoRetryWrapper (req, res, next) {
|
|||
errorMessage: 'Cannot update the user video rate.'
|
||||
}
|
||||
|
||||
databaseUtils.retryTransactionWrapper(rateVideo, options, function (err) {
|
||||
retryTransactionWrapper(rateVideo, options, function (err) {
|
||||
if (err) return next(err)
|
||||
|
||||
return res.type('json').status(204).end()
|
||||
|
@ -46,7 +58,7 @@ function rateVideo (req, res, finalCallback) {
|
|||
const userInstance = res.locals.oauth.token.User
|
||||
|
||||
waterfall([
|
||||
databaseUtils.startSerializableTransaction,
|
||||
startSerializableTransaction,
|
||||
|
||||
function findPreviousRate (t, callback) {
|
||||
db.UserVideoRate.load(userInstance.id, videoInstance.id, t, function (err, previousRate) {
|
||||
|
@ -60,14 +72,14 @@ function rateVideo (req, res, finalCallback) {
|
|||
let likesToIncrement = 0
|
||||
let dislikesToIncrement = 0
|
||||
|
||||
if (rateType === constants.VIDEO_RATE_TYPES.LIKE) likesToIncrement++
|
||||
else if (rateType === constants.VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement++
|
||||
if (rateType === VIDEO_RATE_TYPES.LIKE) likesToIncrement++
|
||||
else if (rateType === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement++
|
||||
|
||||
// There was a previous rate, update it
|
||||
if (previousRate) {
|
||||
// We will remove the previous rate, so we will need to remove it from the video attribute
|
||||
if (previousRate.type === constants.VIDEO_RATE_TYPES.LIKE) likesToIncrement--
|
||||
else if (previousRate.type === constants.VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement--
|
||||
if (previousRate.type === VIDEO_RATE_TYPES.LIKE) likesToIncrement--
|
||||
else if (previousRate.type === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement--
|
||||
|
||||
previousRate.type = rateType
|
||||
|
||||
|
@ -110,7 +122,7 @@ function rateVideo (req, res, finalCallback) {
|
|||
if (likesToIncrement !== 0) {
|
||||
eventsParams.push({
|
||||
videoId: videoInstance.id,
|
||||
type: constants.REQUEST_VIDEO_EVENT_TYPES.LIKES,
|
||||
type: REQUEST_VIDEO_EVENT_TYPES.LIKES,
|
||||
count: likesToIncrement
|
||||
})
|
||||
}
|
||||
|
@ -118,12 +130,12 @@ function rateVideo (req, res, finalCallback) {
|
|||
if (dislikesToIncrement !== 0) {
|
||||
eventsParams.push({
|
||||
videoId: videoInstance.id,
|
||||
type: constants.REQUEST_VIDEO_EVENT_TYPES.DISLIKES,
|
||||
type: REQUEST_VIDEO_EVENT_TYPES.DISLIKES,
|
||||
count: dislikesToIncrement
|
||||
})
|
||||
}
|
||||
|
||||
friends.addEventsToRemoteVideo(eventsParams, t, function (err) {
|
||||
addEventsToRemoteVideo(eventsParams, t, function (err) {
|
||||
return callback(err, t, likesToIncrement, dislikesToIncrement)
|
||||
})
|
||||
},
|
||||
|
@ -138,29 +150,29 @@ function rateVideo (req, res, finalCallback) {
|
|||
if (likesToIncrement !== 0) {
|
||||
qadusParams.push({
|
||||
videoId: videoInstance.id,
|
||||
type: constants.REQUEST_VIDEO_QADU_TYPES.LIKES
|
||||
type: REQUEST_VIDEO_QADU_TYPES.LIKES
|
||||
})
|
||||
}
|
||||
|
||||
if (dislikesToIncrement !== 0) {
|
||||
qadusParams.push({
|
||||
videoId: videoInstance.id,
|
||||
type: constants.REQUEST_VIDEO_QADU_TYPES.DISLIKES
|
||||
type: REQUEST_VIDEO_QADU_TYPES.DISLIKES
|
||||
})
|
||||
}
|
||||
|
||||
friends.quickAndDirtyUpdatesVideoToFriends(qadusParams, t, function (err) {
|
||||
quickAndDirtyUpdatesVideoToFriends(qadusParams, t, function (err) {
|
||||
return callback(err, t)
|
||||
})
|
||||
},
|
||||
|
||||
databaseUtils.commitTransaction
|
||||
commitTransaction
|
||||
|
||||
], function (err, t) {
|
||||
if (err) {
|
||||
// This is just a debug because we will retry the insert
|
||||
logger.debug('Cannot add the user video rate.', { error: err })
|
||||
return databaseUtils.rollbackTransaction(err, t, finalCallback)
|
||||
return rollbackTransaction(err, t, finalCallback)
|
||||
}
|
||||
|
||||
logger.info('User video rate for video %s of user %s updated.', videoInstance.name, userInstance.username)
|
|
@ -1,40 +1,48 @@
|
|||
'use strict'
|
||||
import { parallel } from 'async'
|
||||
import express = require('express')
|
||||
import fs = require('fs')
|
||||
import { join } from 'path'
|
||||
import expressValidator = require('express-validator')
|
||||
// TODO: use .validator when express-validator typing will have validator field
|
||||
const validator = expressValidator['validator']
|
||||
|
||||
const parallel = require('async/parallel')
|
||||
const express = require('express')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const validator = require('express-validator').validator
|
||||
|
||||
const constants = require('../initializers/constants')
|
||||
const db = require('../initializers/database')
|
||||
import {
|
||||
CONFIG,
|
||||
REMOTE_SCHEME,
|
||||
STATIC_PATHS,
|
||||
STATIC_MAX_AGE
|
||||
} from '../initializers'
|
||||
|
||||
const router = express.Router()
|
||||
const clientsRouter = express.Router()
|
||||
|
||||
// TODO: move to constants
|
||||
const opengraphComment = '<!-- opengraph tags -->'
|
||||
const distPath = path.join(__dirname, '..', '..', 'client/dist')
|
||||
const embedPath = path.join(distPath, 'standalone/videos/embed.html')
|
||||
const indexPath = path.join(distPath, 'index.html')
|
||||
const distPath = join(__dirname, '..', '..', 'client/dist')
|
||||
const embedPath = join(distPath, 'standalone/videos/embed.html')
|
||||
const indexPath = join(distPath, 'index.html')
|
||||
|
||||
// Special route that add OpenGraph tags
|
||||
// Do not use a template engine for a so little thing
|
||||
router.use('/videos/watch/:id', generateWatchHtmlPage)
|
||||
clientsRouter.use('/videos/watch/:id', generateWatchHtmlPage)
|
||||
|
||||
router.use('/videos/embed', function (req, res, next) {
|
||||
clientsRouter.use('/videos/embed', function (req, res, next) {
|
||||
res.sendFile(embedPath)
|
||||
})
|
||||
|
||||
// Static HTML/CSS/JS client files
|
||||
router.use('/client', express.static(distPath, { maxAge: constants.STATIC_MAX_AGE }))
|
||||
clientsRouter.use('/client', express.static(distPath, { maxAge: STATIC_MAX_AGE }))
|
||||
|
||||
// 404 for static files not found
|
||||
router.use('/client/*', function (req, res, next) {
|
||||
clientsRouter.use('/client/*', function (req, res, next) {
|
||||
res.sendStatus(404)
|
||||
})
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = router
|
||||
export {
|
||||
clientsRouter
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
@ -42,16 +50,16 @@ function addOpenGraphTags (htmlStringPage, video) {
|
|||
let basePreviewUrlHttp
|
||||
|
||||
if (video.isOwned()) {
|
||||
basePreviewUrlHttp = constants.CONFIG.WEBSERVER.URL
|
||||
basePreviewUrlHttp = CONFIG.WEBSERVER.URL
|
||||
} else {
|
||||
basePreviewUrlHttp = constants.REMOTE_SCHEME.HTTP + '://' + video.Author.Pod.host
|
||||
basePreviewUrlHttp = REMOTE_SCHEME.HTTP + '://' + video.Author.Pod.host
|
||||
}
|
||||
|
||||
// We fetch the remote preview (bigger than the thumbnail)
|
||||
// This should not overhead the remote server since social websites put in a cache the OpenGraph tags
|
||||
// We can't use the thumbnail because these social websites want bigger images (> 200x200 for Facebook for example)
|
||||
const previewUrl = basePreviewUrlHttp + constants.STATIC_PATHS.PREVIEWS + video.getPreviewName()
|
||||
const videoUrl = constants.CONFIG.WEBSERVER.URL + '/videos/watch/' + video.id
|
||||
const previewUrl = basePreviewUrlHttp + STATIC_PATHS.PREVIEWS + video.getPreviewName()
|
||||
const videoUrl = CONFIG.WEBSERVER.URL + '/videos/watch/' + video.id
|
||||
|
||||
const metaTags = {
|
||||
'og:type': 'video',
|
||||
|
@ -95,11 +103,11 @@ function generateWatchHtmlPage (req, res, next) {
|
|||
video: function (callback) {
|
||||
db.Video.loadAndPopulateAuthorAndPodAndTags(videoId, callback)
|
||||
}
|
||||
}, function (err, results) {
|
||||
}, function (err, result: any) {
|
||||
if (err) return next(err)
|
||||
|
||||
const html = results.file.toString()
|
||||
const video = results.video
|
||||
const html = result.file.toString()
|
||||
const video = result.video
|
||||
|
||||
// Let Angular application handle errors
|
||||
if (!video) return res.sendFile(indexPath)
|
|
@ -1,11 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const apiController = require('./api/')
|
||||
const clientController = require('./client')
|
||||
const staticController = require('./static')
|
||||
|
||||
module.exports = {
|
||||
api: apiController,
|
||||
client: clientController,
|
||||
static: staticController
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export * from './static';
|
||||
export * from './client';
|
||||
export * from './api';
|
|
@ -1,45 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const express = require('express')
|
||||
const cors = require('cors')
|
||||
|
||||
const constants = require('../initializers/constants')
|
||||
|
||||
const router = express.Router()
|
||||
|
||||
/*
|
||||
Cors is very important to let other pods access torrent and video files
|
||||
*/
|
||||
|
||||
const torrentsPhysicalPath = constants.CONFIG.STORAGE.TORRENTS_DIR
|
||||
router.use(
|
||||
constants.STATIC_PATHS.TORRENTS,
|
||||
cors(),
|
||||
express.static(torrentsPhysicalPath, { maxAge: constants.STATIC_MAX_AGE })
|
||||
)
|
||||
|
||||
// Videos path for webseeding
|
||||
const videosPhysicalPath = constants.CONFIG.STORAGE.VIDEOS_DIR
|
||||
router.use(
|
||||
constants.STATIC_PATHS.WEBSEED,
|
||||
cors(),
|
||||
express.static(videosPhysicalPath, { maxAge: constants.STATIC_MAX_AGE })
|
||||
)
|
||||
|
||||
// Thumbnails path for express
|
||||
const thumbnailsPhysicalPath = constants.CONFIG.STORAGE.THUMBNAILS_DIR
|
||||
router.use(
|
||||
constants.STATIC_PATHS.THUMBNAILS,
|
||||
express.static(thumbnailsPhysicalPath, { maxAge: constants.STATIC_MAX_AGE })
|
||||
)
|
||||
|
||||
// Video previews path for express
|
||||
const previewsPhysicalPath = constants.CONFIG.STORAGE.PREVIEWS_DIR
|
||||
router.use(
|
||||
constants.STATIC_PATHS.PREVIEWS,
|
||||
express.static(previewsPhysicalPath, { maxAge: constants.STATIC_MAX_AGE })
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = router
|
|
@ -0,0 +1,49 @@
|
|||
import express = require('express')
|
||||
import cors = require('cors')
|
||||
|
||||
import {
|
||||
CONFIG,
|
||||
STATIC_MAX_AGE,
|
||||
STATIC_PATHS
|
||||
} from '../initializers'
|
||||
|
||||
const staticRouter = express.Router()
|
||||
|
||||
/*
|
||||
Cors is very important to let other pods access torrent and video files
|
||||
*/
|
||||
|
||||
const torrentsPhysicalPath = CONFIG.STORAGE.TORRENTS_DIR
|
||||
staticRouter.use(
|
||||
STATIC_PATHS.TORRENTS,
|
||||
cors(),
|
||||
express.static(torrentsPhysicalPath, { maxAge: STATIC_MAX_AGE })
|
||||
)
|
||||
|
||||
// Videos path for webseeding
|
||||
const videosPhysicalPath = CONFIG.STORAGE.VIDEOS_DIR
|
||||
staticRouter.use(
|
||||
STATIC_PATHS.WEBSEED,
|
||||
cors(),
|
||||
express.static(videosPhysicalPath, { maxAge: STATIC_MAX_AGE })
|
||||
)
|
||||
|
||||
// Thumbnails path for express
|
||||
const thumbnailsPhysicalPath = CONFIG.STORAGE.THUMBNAILS_DIR
|
||||
staticRouter.use(
|
||||
STATIC_PATHS.THUMBNAILS,
|
||||
express.static(thumbnailsPhysicalPath, { maxAge: STATIC_MAX_AGE })
|
||||
)
|
||||
|
||||
// Video previews path for express
|
||||
const previewsPhysicalPath = CONFIG.STORAGE.PREVIEWS_DIR
|
||||
staticRouter.use(
|
||||
STATIC_PATHS.PREVIEWS,
|
||||
express.static(previewsPhysicalPath, { maxAge: STATIC_MAX_AGE })
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
staticRouter
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const miscValidators = require('./misc')
|
||||
const podsValidators = require('./pods')
|
||||
const remoteValidators = require('./remote')
|
||||
const usersValidators = require('./users')
|
||||
const videosValidators = require('./videos')
|
||||
|
||||
const validators = {
|
||||
misc: miscValidators,
|
||||
pods: podsValidators,
|
||||
remote: remoteValidators,
|
||||
users: usersValidators,
|
||||
videos: videosValidators
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = validators
|
|
@ -0,0 +1,6 @@
|
|||
export * from './remote'
|
||||
export * from './misc'
|
||||
export * from './pods'
|
||||
export * from './pods'
|
||||
export * from './users'
|
||||
export * from './videos'
|
|
@ -1,10 +1,3 @@
|
|||
'use strict'
|
||||
|
||||
const miscValidators = {
|
||||
exists,
|
||||
isArray
|
||||
}
|
||||
|
||||
function exists (value) {
|
||||
return value !== undefined && value !== null
|
||||
}
|
||||
|
@ -15,4 +8,7 @@ function isArray (value) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = miscValidators
|
||||
export {
|
||||
exists,
|
||||
isArray
|
||||
}
|
|
@ -1,20 +1,15 @@
|
|||
'use strict'
|
||||
import expressValidator = require('express-validator')
|
||||
// TODO: use .validator when express-validator typing will have validator field
|
||||
const validator = expressValidator['validator']
|
||||
|
||||
const validator = require('express-validator').validator
|
||||
|
||||
const miscValidators = require('./misc')
|
||||
|
||||
const podsValidators = {
|
||||
isEachUniqueHostValid,
|
||||
isHostValid
|
||||
}
|
||||
import { isArray } from './misc'
|
||||
|
||||
function isHostValid (host) {
|
||||
return validator.isURL(host) && host.split('://').length === 1
|
||||
}
|
||||
|
||||
function isEachUniqueHostValid (hosts) {
|
||||
return miscValidators.isArray(hosts) &&
|
||||
return isArray(hosts) &&
|
||||
hosts.length !== 0 &&
|
||||
hosts.every(function (host) {
|
||||
return isHostValid(host) && hosts.indexOf(host) === hosts.lastIndexOf(host)
|
||||
|
@ -23,4 +18,7 @@ function isEachUniqueHostValid (hosts) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = podsValidators
|
||||
export {
|
||||
isEachUniqueHostValid,
|
||||
isHostValid
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const remoteVideosValidators = require('./videos')
|
||||
|
||||
const validators = {
|
||||
videos: remoteVideosValidators
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = validators
|
|
@ -0,0 +1 @@
|
|||
export * from './videos';
|
|
@ -1,118 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const has = require('lodash/has')
|
||||
const values = require('lodash/values')
|
||||
|
||||
const constants = require('../../../initializers/constants')
|
||||
const videosValidators = require('../videos')
|
||||
const miscValidators = require('../misc')
|
||||
|
||||
const ENDPOINT_ACTIONS = constants.REQUEST_ENDPOINT_ACTIONS[constants.REQUEST_ENDPOINTS.VIDEOS]
|
||||
|
||||
const remoteVideosValidators = {
|
||||
isEachRemoteRequestVideosValid,
|
||||
isEachRemoteRequestVideosQaduValid,
|
||||
isEachRemoteRequestVideosEventsValid
|
||||
}
|
||||
|
||||
function isEachRemoteRequestVideosValid (requests) {
|
||||
return miscValidators.isArray(requests) &&
|
||||
requests.every(function (request) {
|
||||
const video = request.data
|
||||
|
||||
if (!video) return false
|
||||
|
||||
return (
|
||||
isRequestTypeAddValid(request.type) &&
|
||||
isCommonVideoAttributesValid(video) &&
|
||||
videosValidators.isVideoAuthorValid(video.author) &&
|
||||
videosValidators.isVideoThumbnailDataValid(video.thumbnailData)
|
||||
) ||
|
||||
(
|
||||
isRequestTypeUpdateValid(request.type) &&
|
||||
isCommonVideoAttributesValid(video)
|
||||
) ||
|
||||
(
|
||||
isRequestTypeRemoveValid(request.type) &&
|
||||
videosValidators.isVideoRemoteIdValid(video.remoteId)
|
||||
) ||
|
||||
(
|
||||
isRequestTypeReportAbuseValid(request.type) &&
|
||||
videosValidators.isVideoRemoteIdValid(request.data.videoRemoteId) &&
|
||||
videosValidators.isVideoAbuseReasonValid(request.data.reportReason) &&
|
||||
videosValidators.isVideoAbuseReporterUsernameValid(request.data.reporterUsername)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
function isEachRemoteRequestVideosQaduValid (requests) {
|
||||
return miscValidators.isArray(requests) &&
|
||||
requests.every(function (request) {
|
||||
const video = request.data
|
||||
|
||||
if (!video) return false
|
||||
|
||||
return (
|
||||
videosValidators.isVideoRemoteIdValid(video.remoteId) &&
|
||||
(has(video, 'views') === false || videosValidators.isVideoViewsValid) &&
|
||||
(has(video, 'likes') === false || videosValidators.isVideoLikesValid) &&
|
||||
(has(video, 'dislikes') === false || videosValidators.isVideoDislikesValid)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
function isEachRemoteRequestVideosEventsValid (requests) {
|
||||
return miscValidators.isArray(requests) &&
|
||||
requests.every(function (request) {
|
||||
const eventData = request.data
|
||||
|
||||
if (!eventData) return false
|
||||
|
||||
return (
|
||||
videosValidators.isVideoRemoteIdValid(eventData.remoteId) &&
|
||||
values(constants.REQUEST_VIDEO_EVENT_TYPES).indexOf(eventData.eventType) !== -1 &&
|
||||
videosValidators.isVideoEventCountValid(eventData.count)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = remoteVideosValidators
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function isCommonVideoAttributesValid (video) {
|
||||
return videosValidators.isVideoDateValid(video.createdAt) &&
|
||||
videosValidators.isVideoDateValid(video.updatedAt) &&
|
||||
videosValidators.isVideoCategoryValid(video.category) &&
|
||||
videosValidators.isVideoLicenceValid(video.licence) &&
|
||||
videosValidators.isVideoLanguageValid(video.language) &&
|
||||
videosValidators.isVideoNSFWValid(video.nsfw) &&
|
||||
videosValidators.isVideoDescriptionValid(video.description) &&
|
||||
videosValidators.isVideoDurationValid(video.duration) &&
|
||||
videosValidators.isVideoInfoHashValid(video.infoHash) &&
|
||||
videosValidators.isVideoNameValid(video.name) &&
|
||||
videosValidators.isVideoTagsValid(video.tags) &&
|
||||
videosValidators.isVideoRemoteIdValid(video.remoteId) &&
|
||||
videosValidators.isVideoExtnameValid(video.extname) &&
|
||||
videosValidators.isVideoViewsValid(video.views) &&
|
||||
videosValidators.isVideoLikesValid(video.likes) &&
|
||||
videosValidators.isVideoDislikesValid(video.dislikes)
|
||||
}
|
||||
|
||||
function isRequestTypeAddValid (value) {
|
||||
return value === ENDPOINT_ACTIONS.ADD
|
||||
}
|
||||
|
||||
function isRequestTypeUpdateValid (value) {
|
||||
return value === ENDPOINT_ACTIONS.UPDATE
|
||||
}
|
||||
|
||||
function isRequestTypeRemoveValid (value) {
|
||||
return value === ENDPOINT_ACTIONS.REMOVE
|
||||
}
|
||||
|
||||
function isRequestTypeReportAbuseValid (value) {
|
||||
return value === ENDPOINT_ACTIONS.REPORT_ABUSE
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
import { has, values } from 'lodash'
|
||||
|
||||
import {
|
||||
REQUEST_ENDPOINTS,
|
||||
REQUEST_ENDPOINT_ACTIONS,
|
||||
REQUEST_VIDEO_EVENT_TYPES
|
||||
} from '../../../initializers'
|
||||
import { isArray } from '../misc'
|
||||
import {
|
||||
isVideoAuthorValid,
|
||||
isVideoThumbnailDataValid,
|
||||
isVideoRemoteIdValid,
|
||||
isVideoAbuseReasonValid,
|
||||
isVideoAbuseReporterUsernameValid,
|
||||
isVideoViewsValid,
|
||||
isVideoLikesValid,
|
||||
isVideoDislikesValid,
|
||||
isVideoEventCountValid,
|
||||
isVideoDateValid,
|
||||
isVideoCategoryValid,
|
||||
isVideoLicenceValid,
|
||||
isVideoLanguageValid,
|
||||
isVideoNSFWValid,
|
||||
isVideoDescriptionValid,
|
||||
isVideoDurationValid,
|
||||
isVideoInfoHashValid,
|
||||
isVideoNameValid,
|
||||
isVideoTagsValid,
|
||||
isVideoExtnameValid
|
||||
} from '../videos'
|
||||
|
||||
const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS]
|
||||
|
||||
function isEachRemoteRequestVideosValid (requests) {
|
||||
return isArray(requests) &&
|
||||
requests.every(function (request) {
|
||||
const video = request.data
|
||||
|
||||
if (!video) return false
|
||||
|
||||
return (
|
||||
isRequestTypeAddValid(request.type) &&
|
||||
isCommonVideoAttributesValid(video) &&
|
||||
isVideoAuthorValid(video.author) &&
|
||||
isVideoThumbnailDataValid(video.thumbnailData)
|
||||
) ||
|
||||
(
|
||||
isRequestTypeUpdateValid(request.type) &&
|
||||
isCommonVideoAttributesValid(video)
|
||||
) ||
|
||||
(
|
||||
isRequestTypeRemoveValid(request.type) &&
|
||||
isVideoRemoteIdValid(video.remoteId)
|
||||
) ||
|
||||
(
|
||||
isRequestTypeReportAbuseValid(request.type) &&
|
||||
isVideoRemoteIdValid(request.data.videoRemoteId) &&
|
||||
isVideoAbuseReasonValid(request.data.reportReason) &&
|
||||
isVideoAbuseReporterUsernameValid(request.data.reporterUsername)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
function isEachRemoteRequestVideosQaduValid (requests) {
|
||||
return isArray(requests) &&
|
||||
requests.every(function (request) {
|
||||
const video = request.data
|
||||
|
||||
if (!video) return false
|
||||
|
||||
return (
|
||||
isVideoRemoteIdValid(video.remoteId) &&
|
||||
(has(video, 'views') === false || isVideoViewsValid) &&
|
||||
(has(video, 'likes') === false || isVideoLikesValid) &&
|
||||
(has(video, 'dislikes') === false || isVideoDislikesValid)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
function isEachRemoteRequestVideosEventsValid (requests) {
|
||||
return isArray(requests) &&
|
||||
requests.every(function (request) {
|
||||
const eventData = request.data
|
||||
|
||||
if (!eventData) return false
|
||||
|
||||
return (
|
||||
isVideoRemoteIdValid(eventData.remoteId) &&
|
||||
values(REQUEST_VIDEO_EVENT_TYPES).indexOf(eventData.eventType) !== -1 &&
|
||||
isVideoEventCountValid(eventData.count)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
isEachRemoteRequestVideosValid,
|
||||
isEachRemoteRequestVideosQaduValid,
|
||||
isEachRemoteRequestVideosEventsValid
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function isCommonVideoAttributesValid (video) {
|
||||
return isVideoDateValid(video.createdAt) &&
|
||||
isVideoDateValid(video.updatedAt) &&
|
||||
isVideoCategoryValid(video.category) &&
|
||||
isVideoLicenceValid(video.licence) &&
|
||||
isVideoLanguageValid(video.language) &&
|
||||
isVideoNSFWValid(video.nsfw) &&
|
||||
isVideoDescriptionValid(video.description) &&
|
||||
isVideoDurationValid(video.duration) &&
|
||||
isVideoInfoHashValid(video.infoHash) &&
|
||||
isVideoNameValid(video.name) &&
|
||||
isVideoTagsValid(video.tags) &&
|
||||
isVideoRemoteIdValid(video.remoteId) &&
|
||||
isVideoExtnameValid(video.extname) &&
|
||||
isVideoViewsValid(video.views) &&
|
||||
isVideoLikesValid(video.likes) &&
|
||||
isVideoDislikesValid(video.dislikes)
|
||||
}
|
||||
|
||||
function isRequestTypeAddValid (value) {
|
||||
return value === ENDPOINT_ACTIONS.ADD
|
||||
}
|
||||
|
||||
function isRequestTypeUpdateValid (value) {
|
||||
return value === ENDPOINT_ACTIONS.UPDATE
|
||||
}
|
||||
|
||||
function isRequestTypeRemoveValid (value) {
|
||||
return value === ENDPOINT_ACTIONS.REMOVE
|
||||
}
|
||||
|
||||
function isRequestTypeReportAbuseValid (value) {
|
||||
return value === ENDPOINT_ACTIONS.REPORT_ABUSE
|
||||
}
|
|
@ -1,24 +1,17 @@
|
|||
'use strict'
|
||||
import { values } from 'lodash'
|
||||
import expressValidator = require('express-validator')
|
||||
// TODO: use .validator when express-validator typing will have validator field
|
||||
const validator = expressValidator['validator']
|
||||
|
||||
const validator = require('express-validator').validator
|
||||
const values = require('lodash/values')
|
||||
|
||||
const constants = require('../../initializers/constants')
|
||||
const USERS_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.USERS
|
||||
|
||||
const usersValidators = {
|
||||
isUserPasswordValid,
|
||||
isUserRoleValid,
|
||||
isUserUsernameValid,
|
||||
isUserDisplayNSFWValid
|
||||
}
|
||||
import { CONSTRAINTS_FIELDS, USER_ROLES } from '../../initializers'
|
||||
const USERS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.USERS
|
||||
|
||||
function isUserPasswordValid (value) {
|
||||
return validator.isLength(value, USERS_CONSTRAINTS_FIELDS.PASSWORD)
|
||||
}
|
||||
|
||||
function isUserRoleValid (value) {
|
||||
return values(constants.USER_ROLES).indexOf(value) !== -1
|
||||
return values(USER_ROLES).indexOf(value) !== -1
|
||||
}
|
||||
|
||||
function isUserUsernameValid (value) {
|
||||
|
@ -33,4 +26,9 @@ function isUserDisplayNSFWValid (value) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = usersValidators
|
||||
export {
|
||||
isUserPasswordValid,
|
||||
isUserRoleValid,
|
||||
isUserUsernameValid,
|
||||
isUserDisplayNSFWValid
|
||||
}
|
|
@ -1,43 +1,24 @@
|
|||
'use strict'
|
||||
import { values } from 'lodash'
|
||||
import expressValidator = require('express-validator')
|
||||
// TODO: use .validator when express-validator typing will have validator field
|
||||
const validator = expressValidator['validator']
|
||||
|
||||
const validator = require('express-validator').validator
|
||||
const values = require('lodash/values')
|
||||
import {
|
||||
CONSTRAINTS_FIELDS,
|
||||
VIDEO_CATEGORIES,
|
||||
VIDEO_LICENCES,
|
||||
VIDEO_LANGUAGES,
|
||||
VIDEO_RATE_TYPES
|
||||
} from '../../initializers'
|
||||
import { isUserUsernameValid } from './users'
|
||||
import { isArray } from './misc'
|
||||
|
||||
const constants = require('../../initializers/constants')
|
||||
const usersValidators = require('./users')
|
||||
const miscValidators = require('./misc')
|
||||
const VIDEOS_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.VIDEOS
|
||||
const VIDEO_ABUSES_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.VIDEO_ABUSES
|
||||
const VIDEO_EVENTS_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.VIDEO_EVENTS
|
||||
|
||||
const videosValidators = {
|
||||
isVideoAuthorValid,
|
||||
isVideoDateValid,
|
||||
isVideoCategoryValid,
|
||||
isVideoLicenceValid,
|
||||
isVideoLanguageValid,
|
||||
isVideoNSFWValid,
|
||||
isVideoDescriptionValid,
|
||||
isVideoDurationValid,
|
||||
isVideoInfoHashValid,
|
||||
isVideoNameValid,
|
||||
isVideoTagsValid,
|
||||
isVideoThumbnailValid,
|
||||
isVideoThumbnailDataValid,
|
||||
isVideoExtnameValid,
|
||||
isVideoRemoteIdValid,
|
||||
isVideoAbuseReasonValid,
|
||||
isVideoAbuseReporterUsernameValid,
|
||||
isVideoFile,
|
||||
isVideoViewsValid,
|
||||
isVideoLikesValid,
|
||||
isVideoRatingTypeValid,
|
||||
isVideoDislikesValid,
|
||||
isVideoEventCountValid
|
||||
}
|
||||
const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
|
||||
const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES
|
||||
const VIDEO_EVENTS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_EVENTS
|
||||
|
||||
function isVideoAuthorValid (value) {
|
||||
return usersValidators.isUserUsernameValid(value)
|
||||
return isUserUsernameValid(value)
|
||||
}
|
||||
|
||||
function isVideoDateValid (value) {
|
||||
|
@ -45,15 +26,15 @@ function isVideoDateValid (value) {
|
|||
}
|
||||
|
||||
function isVideoCategoryValid (value) {
|
||||
return constants.VIDEO_CATEGORIES[value] !== undefined
|
||||
return VIDEO_CATEGORIES[value] !== undefined
|
||||
}
|
||||
|
||||
function isVideoLicenceValid (value) {
|
||||
return constants.VIDEO_LICENCES[value] !== undefined
|
||||
return VIDEO_LICENCES[value] !== undefined
|
||||
}
|
||||
|
||||
function isVideoLanguageValid (value) {
|
||||
return value === null || constants.VIDEO_LANGUAGES[value] !== undefined
|
||||
return value === null || VIDEO_LANGUAGES[value] !== undefined
|
||||
}
|
||||
|
||||
function isVideoNSFWValid (value) {
|
||||
|
@ -81,7 +62,7 @@ function isVideoNameValid (value) {
|
|||
}
|
||||
|
||||
function isVideoTagsValid (tags) {
|
||||
return miscValidators.isArray(tags) &&
|
||||
return isArray(tags) &&
|
||||
validator.isInt(tags.length, VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
|
||||
tags.every(function (tag) {
|
||||
return validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
|
||||
|
@ -105,7 +86,7 @@ function isVideoAbuseReasonValid (value) {
|
|||
}
|
||||
|
||||
function isVideoAbuseReporterUsernameValid (value) {
|
||||
return usersValidators.isUserUsernameValid(value)
|
||||
return isUserUsernameValid(value)
|
||||
}
|
||||
|
||||
function isVideoViewsValid (value) {
|
||||
|
@ -125,7 +106,7 @@ function isVideoEventCountValid (value) {
|
|||
}
|
||||
|
||||
function isVideoRatingTypeValid (value) {
|
||||
return values(constants.VIDEO_RATE_TYPES).indexOf(value) !== -1
|
||||
return values(VIDEO_RATE_TYPES).indexOf(value) !== -1
|
||||
}
|
||||
|
||||
function isVideoFile (value, files) {
|
||||
|
@ -145,4 +126,28 @@ function isVideoFile (value, files) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = videosValidators
|
||||
export {
|
||||
isVideoAuthorValid,
|
||||
isVideoDateValid,
|
||||
isVideoCategoryValid,
|
||||
isVideoLicenceValid,
|
||||
isVideoLanguageValid,
|
||||
isVideoNSFWValid,
|
||||
isVideoDescriptionValid,
|
||||
isVideoDurationValid,
|
||||
isVideoInfoHashValid,
|
||||
isVideoNameValid,
|
||||
isVideoTagsValid,
|
||||
isVideoThumbnailValid,
|
||||
isVideoThumbnailDataValid,
|
||||
isVideoExtnameValid,
|
||||
isVideoRemoteIdValid,
|
||||
isVideoAbuseReasonValid,
|
||||
isVideoAbuseReporterUsernameValid,
|
||||
isVideoFile,
|
||||
isVideoViewsValid,
|
||||
isVideoLikesValid,
|
||||
isVideoRatingTypeValid,
|
||||
isVideoDislikesValid,
|
||||
isVideoEventCountValid
|
||||
}
|
|
@ -1,17 +1,8 @@
|
|||
'use strict'
|
||||
|
||||
const retry = require('async/retry')
|
||||
// TODO: import from ES6 when retry typing file will include errorFilter function
|
||||
import retry = require('async/retry')
|
||||
|
||||
const db = require('../initializers/database')
|
||||
const logger = require('./logger')
|
||||
|
||||
const utils = {
|
||||
commitTransaction,
|
||||
retryTransactionWrapper,
|
||||
rollbackTransaction,
|
||||
startSerializableTransaction,
|
||||
transactionRetryer
|
||||
}
|
||||
import { logger } from './logger'
|
||||
|
||||
function commitTransaction (t, callback) {
|
||||
return t.commit().asCallback(callback)
|
||||
|
@ -33,7 +24,7 @@ function rollbackTransaction (err, t, callback) {
|
|||
function retryTransactionWrapper (functionToRetry, options, finalCallback) {
|
||||
const args = options.arguments ? options.arguments : []
|
||||
|
||||
utils.transactionRetryer(
|
||||
transactionRetryer(
|
||||
function (callback) {
|
||||
return functionToRetry.apply(this, args.concat([ callback ]))
|
||||
},
|
||||
|
@ -69,4 +60,10 @@ function startSerializableTransaction (callback) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = utils
|
||||
export {
|
||||
commitTransaction,
|
||||
retryTransactionWrapper,
|
||||
rollbackTransaction,
|
||||
startSerializableTransaction,
|
||||
transactionRetryer
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
export * from './logger'
|
||||
export * from './custom-validators'
|
||||
export * from './database-utils'
|
||||
export * from './peertube-crypto'
|
||||
export * from './requests'
|
||||
export * from './utils'
|
|
@ -1,23 +1,21 @@
|
|||
// Thanks http://tostring.it/2014/06/23/advanced-logging-with-nodejs/
|
||||
'use strict'
|
||||
import mkdirp = require('mkdirp')
|
||||
import path = require('path')
|
||||
import winston = require('winston')
|
||||
|
||||
const mkdirp = require('mkdirp')
|
||||
const path = require('path')
|
||||
const winston = require('winston')
|
||||
winston.emitErrs = true
|
||||
// Do not use barrel (dependencies issues)
|
||||
import { CONFIG } from '../initializers/constants'
|
||||
|
||||
const constants = require('../initializers/constants')
|
||||
|
||||
const label = constants.CONFIG.WEBSERVER.HOSTNAME + ':' + constants.CONFIG.WEBSERVER.PORT
|
||||
const label = CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
|
||||
|
||||
// Create the directory if it does not exist
|
||||
mkdirp.sync(constants.CONFIG.STORAGE.LOG_DIR)
|
||||
mkdirp.sync(CONFIG.STORAGE.LOG_DIR)
|
||||
|
||||
const logger = new winston.Logger({
|
||||
transports: [
|
||||
new winston.transports.File({
|
||||
level: 'debug',
|
||||
filename: path.join(constants.CONFIG.STORAGE.LOG_DIR, 'all-logs.log'),
|
||||
filename: path.join(CONFIG.STORAGE.LOG_DIR, 'all-logs.log'),
|
||||
handleExceptions: true,
|
||||
json: true,
|
||||
maxsize: 5242880,
|
||||
|
@ -38,12 +36,13 @@ const logger = new winston.Logger({
|
|||
exitOnError: true
|
||||
})
|
||||
|
||||
logger.stream = {
|
||||
write: function (message, encoding) {
|
||||
logger.info(message)
|
||||
}
|
||||
}
|
||||
// TODO: useful?
|
||||
// logger.stream = {
|
||||
// write: function (message) {
|
||||
// logger.info(message)
|
||||
// }
|
||||
// }
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = logger
|
||||
export { logger }
|
|
@ -1,26 +1,21 @@
|
|||
'use strict'
|
||||
import crypto = require('crypto')
|
||||
import bcrypt = require('bcrypt')
|
||||
import fs = require('fs')
|
||||
import openssl = require('openssl-wrapper')
|
||||
import { join } from 'path'
|
||||
|
||||
const crypto = require('crypto')
|
||||
const bcrypt = require('bcrypt')
|
||||
const fs = require('fs')
|
||||
const openssl = require('openssl-wrapper')
|
||||
const pathUtils = require('path')
|
||||
|
||||
const constants = require('../initializers/constants')
|
||||
const logger = require('./logger')
|
||||
|
||||
const peertubeCrypto = {
|
||||
checkSignature,
|
||||
comparePassword,
|
||||
createCertsIfNotExist,
|
||||
cryptPassword,
|
||||
getMyPrivateCert,
|
||||
getMyPublicCert,
|
||||
sign
|
||||
}
|
||||
import {
|
||||
SIGNATURE_ALGORITHM,
|
||||
SIGNATURE_ENCODING,
|
||||
PRIVATE_CERT_NAME,
|
||||
CONFIG,
|
||||
BCRYPT_SALT_SIZE,
|
||||
PUBLIC_CERT_NAME
|
||||
} from '../initializers'
|
||||
import { logger } from './logger'
|
||||
|
||||
function checkSignature (publicKey, data, hexSignature) {
|
||||
const verify = crypto.createVerify(constants.SIGNATURE_ALGORITHM)
|
||||
const verify = crypto.createVerify(SIGNATURE_ALGORITHM)
|
||||
|
||||
let dataString
|
||||
if (typeof data === 'string') {
|
||||
|
@ -36,12 +31,12 @@ function checkSignature (publicKey, data, hexSignature) {
|
|||
|
||||
verify.update(dataString, 'utf8')
|
||||
|
||||
const isValid = verify.verify(publicKey, hexSignature, constants.SIGNATURE_ENCODING)
|
||||
const isValid = verify.verify(publicKey, hexSignature, SIGNATURE_ENCODING)
|
||||
return isValid
|
||||
}
|
||||
|
||||
function sign (data) {
|
||||
const sign = crypto.createSign(constants.SIGNATURE_ALGORITHM)
|
||||
const sign = crypto.createSign(SIGNATURE_ALGORITHM)
|
||||
|
||||
let dataString
|
||||
if (typeof data === 'string') {
|
||||
|
@ -58,9 +53,9 @@ function sign (data) {
|
|||
sign.update(dataString, 'utf8')
|
||||
|
||||
// TODO: make async
|
||||
const certPath = pathUtils.join(constants.CONFIG.STORAGE.CERT_DIR, constants.PRIVATE_CERT_NAME)
|
||||
const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME)
|
||||
const myKey = fs.readFileSync(certPath)
|
||||
const signature = sign.sign(myKey, constants.SIGNATURE_ENCODING)
|
||||
const signature = sign.sign(myKey.toString(), SIGNATURE_ENCODING)
|
||||
|
||||
return signature
|
||||
}
|
||||
|
@ -88,7 +83,7 @@ function createCertsIfNotExist (callback) {
|
|||
}
|
||||
|
||||
function cryptPassword (password, callback) {
|
||||
bcrypt.genSalt(constants.BCRYPT_SALT_SIZE, function (err, salt) {
|
||||
bcrypt.genSalt(BCRYPT_SALT_SIZE, function (err, salt) {
|
||||
if (err) return callback(err)
|
||||
|
||||
bcrypt.hash(password, salt, function (err, hash) {
|
||||
|
@ -98,23 +93,31 @@ function cryptPassword (password, callback) {
|
|||
}
|
||||
|
||||
function getMyPrivateCert (callback) {
|
||||
const certPath = pathUtils.join(constants.CONFIG.STORAGE.CERT_DIR, constants.PRIVATE_CERT_NAME)
|
||||
const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME)
|
||||
fs.readFile(certPath, 'utf8', callback)
|
||||
}
|
||||
|
||||
function getMyPublicCert (callback) {
|
||||
const certPath = pathUtils.join(constants.CONFIG.STORAGE.CERT_DIR, constants.PUBLIC_CERT_NAME)
|
||||
const certPath = join(CONFIG.STORAGE.CERT_DIR, PUBLIC_CERT_NAME)
|
||||
fs.readFile(certPath, 'utf8', callback)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = peertubeCrypto
|
||||
export {
|
||||
checkSignature,
|
||||
comparePassword,
|
||||
createCertsIfNotExist,
|
||||
cryptPassword,
|
||||
getMyPrivateCert,
|
||||
getMyPublicCert,
|
||||
sign
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function certsExist (callback) {
|
||||
const certPath = pathUtils.join(constants.CONFIG.STORAGE.CERT_DIR, constants.PRIVATE_CERT_NAME)
|
||||
const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME)
|
||||
fs.access(certPath, function (err) {
|
||||
// If there is an error the certificates do not exist
|
||||
const exists = !err
|
||||
|
@ -134,7 +137,7 @@ function createCerts (callback) {
|
|||
|
||||
logger.info('Generating a RSA key...')
|
||||
|
||||
const privateCertPath = pathUtils.join(constants.CONFIG.STORAGE.CERT_DIR, constants.PRIVATE_CERT_NAME)
|
||||
const privateCertPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME)
|
||||
const genRsaOptions = {
|
||||
'out': privateCertPath,
|
||||
'2048': false
|
||||
|
@ -148,7 +151,7 @@ function createCerts (callback) {
|
|||
logger.info('RSA key generated.')
|
||||
logger.info('Managing public key...')
|
||||
|
||||
const publicCertPath = pathUtils.join(constants.CONFIG.STORAGE.CERT_DIR, 'peertube.pub')
|
||||
const publicCertPath = join(CONFIG.STORAGE.CERT_DIR, 'peertube.pub')
|
||||
const rsaOptions = {
|
||||
'in': privateCertPath,
|
||||
'pubout': true,
|
|
@ -1,21 +1,18 @@
|
|||
'use strict'
|
||||
import replay = require('request-replay')
|
||||
import request = require('request')
|
||||
|
||||
const replay = require('request-replay')
|
||||
const request = require('request')
|
||||
|
||||
const constants = require('../initializers/constants')
|
||||
const peertubeCrypto = require('./peertube-crypto')
|
||||
|
||||
const requests = {
|
||||
makeRetryRequest,
|
||||
makeSecureRequest
|
||||
}
|
||||
import {
|
||||
RETRY_REQUESTS,
|
||||
REMOTE_SCHEME,
|
||||
CONFIG
|
||||
} from '../initializers'
|
||||
import { sign } from './peertube-crypto'
|
||||
|
||||
function makeRetryRequest (params, callback) {
|
||||
replay(
|
||||
request(params, callback),
|
||||
{
|
||||
retries: constants.RETRY_REQUESTS,
|
||||
retries: RETRY_REQUESTS,
|
||||
factor: 3,
|
||||
maxTimeout: Infinity,
|
||||
errorCodes: [ 'EADDRINFO', 'ETIMEDOUT', 'ECONNRESET', 'ESOCKETTIMEDOUT', 'ENOTFOUND', 'ECONNREFUSED' ]
|
||||
|
@ -25,18 +22,17 @@ function makeRetryRequest (params, callback) {
|
|||
|
||||
function makeSecureRequest (params, callback) {
|
||||
const requestParams = {
|
||||
url: constants.REMOTE_SCHEME.HTTP + '://' + params.toPod.host + params.path
|
||||
url: REMOTE_SCHEME.HTTP + '://' + params.toPod.host + params.path,
|
||||
json: {}
|
||||
}
|
||||
|
||||
if (params.method !== 'POST') {
|
||||
return callback(new Error('Cannot make a secure request with a non POST method.'))
|
||||
}
|
||||
|
||||
requestParams.json = {}
|
||||
|
||||
// Add signature if it is specified in the params
|
||||
if (params.sign === true) {
|
||||
const host = constants.CONFIG.WEBSERVER.HOST
|
||||
const host = CONFIG.WEBSERVER.HOST
|
||||
|
||||
let dataToSign
|
||||
if (params.data) {
|
||||
|
@ -47,22 +43,23 @@ function makeSecureRequest (params, callback) {
|
|||
dataToSign = host
|
||||
}
|
||||
|
||||
requestParams.json.signature = {
|
||||
requestParams.json['signature'] = {
|
||||
host, // Which host we pretend to be
|
||||
signature: peertubeCrypto.sign(dataToSign)
|
||||
signature: sign(dataToSign)
|
||||
}
|
||||
}
|
||||
|
||||
// If there are data informations
|
||||
if (params.data) {
|
||||
requestParams.json.data = params.data
|
||||
requestParams.json['data'] = params.data
|
||||
}
|
||||
|
||||
console.log(requestParams.json.data)
|
||||
|
||||
request.post(requestParams, callback)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = requests
|
||||
export {
|
||||
makeRetryRequest,
|
||||
makeSecureRequest
|
||||
}
|
|
@ -1,24 +1,13 @@
|
|||
'use strict'
|
||||
import { pseudoRandomBytes } from 'crypto'
|
||||
|
||||
const crypto = require('crypto')
|
||||
|
||||
const logger = require('./logger')
|
||||
|
||||
const utils = {
|
||||
badRequest,
|
||||
createEmptyCallback,
|
||||
cleanForExit,
|
||||
generateRandomString,
|
||||
isTestInstance,
|
||||
getFormatedObjects
|
||||
}
|
||||
import { logger } from './logger'
|
||||
|
||||
function badRequest (req, res, next) {
|
||||
res.type('json').status(400).end()
|
||||
}
|
||||
|
||||
function generateRandomString (size, callback) {
|
||||
crypto.pseudoRandomBytes(size, function (err, raw) {
|
||||
pseudoRandomBytes(size, function (err, raw) {
|
||||
if (err) return callback(err)
|
||||
|
||||
callback(null, raw.toString('hex'))
|
||||
|
@ -55,4 +44,11 @@ function getFormatedObjects (objects, objectsTotal) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = utils
|
||||
export {
|
||||
badRequest,
|
||||
createEmptyCallback,
|
||||
cleanForExit,
|
||||
generateRandomString,
|
||||
isTestInstance,
|
||||
getFormatedObjects
|
||||
}
|
|
@ -1,17 +1,7 @@
|
|||
'use strict'
|
||||
import config = require('config')
|
||||
|
||||
const config = require('config')
|
||||
|
||||
const constants = require('./constants')
|
||||
const db = require('./database')
|
||||
|
||||
const checker = {
|
||||
checkConfig,
|
||||
checkFFmpeg,
|
||||
checkMissedConfig,
|
||||
clientsExist,
|
||||
usersExist
|
||||
}
|
||||
import { CONFIG } from './constants'
|
||||
|
||||
// Some checks on configuration files
|
||||
function checkConfig () {
|
||||
|
@ -50,7 +40,7 @@ function checkFFmpeg (callback) {
|
|||
|
||||
Ffmpeg.getAvailableCodecs(function (err, codecs) {
|
||||
if (err) return callback(err)
|
||||
if (constants.CONFIG.TRANSCODING.ENABLED === false) return callback(null)
|
||||
if (CONFIG.TRANSCODING.ENABLED === false) return callback(null)
|
||||
|
||||
const canEncode = [ 'libx264' ]
|
||||
canEncode.forEach(function (codec) {
|
||||
|
@ -85,4 +75,10 @@ function usersExist (callback) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = checker
|
||||
export {
|
||||
checkConfig,
|
||||
checkFFmpeg,
|
||||
checkMissedConfig,
|
||||
clientsExist,
|
||||
usersExist
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
'use strict'
|
||||
|
||||
const config = require('config')
|
||||
const path = require('path')
|
||||
import config = require('config')
|
||||
import { join } from 'path'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
@ -36,38 +34,40 @@ const OAUTH_LIFETIME = {
|
|||
|
||||
const CONFIG = {
|
||||
LISTEN: {
|
||||
PORT: config.get('listen.port')
|
||||
PORT: config.get<number>('listen.port')
|
||||
},
|
||||
DATABASE: {
|
||||
DBNAME: 'peertube' + config.get('database.suffix'),
|
||||
HOSTNAME: config.get('database.hostname'),
|
||||
PORT: config.get('database.port'),
|
||||
USERNAME: config.get('database.username'),
|
||||
PASSWORD: config.get('database.password')
|
||||
DBNAME: 'peertube' + config.get<string>('database.suffix'),
|
||||
HOSTNAME: config.get<string>('database.hostname'),
|
||||
PORT: config.get<number>('database.port'),
|
||||
USERNAME: config.get<string>('database.username'),
|
||||
PASSWORD: config.get<string>('database.password')
|
||||
},
|
||||
STORAGE: {
|
||||
CERT_DIR: path.join(__dirname, '..', '..', config.get('storage.certs')),
|
||||
LOG_DIR: path.join(__dirname, '..', '..', config.get('storage.logs')),
|
||||
VIDEOS_DIR: path.join(__dirname, '..', '..', config.get('storage.videos')),
|
||||
THUMBNAILS_DIR: path.join(__dirname, '..', '..', config.get('storage.thumbnails')),
|
||||
PREVIEWS_DIR: path.join(__dirname, '..', '..', config.get('storage.previews')),
|
||||
TORRENTS_DIR: path.join(__dirname, '..', '..', config.get('storage.torrents'))
|
||||
CERT_DIR: join(__dirname, '..', '..', config.get<string>('storage.certs')),
|
||||
LOG_DIR: join(__dirname, '..', '..', config.get<string>('storage.logs')),
|
||||
VIDEOS_DIR: join(__dirname, '..', '..', config.get<string>('storage.videos')),
|
||||
THUMBNAILS_DIR: join(__dirname, '..', '..', config.get<string>('storage.thumbnails')),
|
||||
PREVIEWS_DIR: join(__dirname, '..', '..', config.get<string>('storage.previews')),
|
||||
TORRENTS_DIR: join(__dirname, '..', '..', config.get<string>('storage.torrents'))
|
||||
},
|
||||
WEBSERVER: {
|
||||
SCHEME: config.get('webserver.https') === true ? 'https' : 'http',
|
||||
WS: config.get('webserver.https') === true ? 'wss' : 'ws',
|
||||
HOSTNAME: config.get('webserver.hostname'),
|
||||
PORT: config.get('webserver.port')
|
||||
SCHEME: config.get<boolean>('webserver.https') === true ? 'https' : 'http',
|
||||
WS: config.get<boolean>('webserver.https') === true ? 'wss' : 'ws',
|
||||
HOSTNAME: config.get<string>('webserver.hostname'),
|
||||
PORT: config.get<number>('webserver.port'),
|
||||
URL: '',
|
||||
HOST: ''
|
||||
},
|
||||
ADMIN: {
|
||||
EMAIL: config.get('admin.email')
|
||||
EMAIL: config.get<string>('admin.email')
|
||||
},
|
||||
SIGNUP: {
|
||||
ENABLED: config.get('signup.enabled')
|
||||
ENABLED: config.get<boolean>('signup.enabled')
|
||||
},
|
||||
TRANSCODING: {
|
||||
ENABLED: config.get('transcoding.enabled'),
|
||||
THREADS: config.get('transcoding.threads')
|
||||
ENABLED: config.get<boolean>('transcoding.enabled'),
|
||||
THREADS: config.get<number>('transcoding.threads')
|
||||
}
|
||||
}
|
||||
CONFIG.WEBSERVER.URL = CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT
|
||||
|
@ -283,12 +283,12 @@ if (isTestInstance() === true) {
|
|||
JOBS_FETCHING_INTERVAL = 10000
|
||||
REMOTE_SCHEME.HTTP = 'http'
|
||||
REMOTE_SCHEME.WS = 'ws'
|
||||
STATIC_MAX_AGE = 0
|
||||
STATIC_MAX_AGE = '0'
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = {
|
||||
export {
|
||||
API_VERSION,
|
||||
BCRYPT_SALT_SIZE,
|
||||
CONFIG,
|
|
@ -1,24 +1,23 @@
|
|||
'use strict'
|
||||
import fs = require('fs')
|
||||
import { join } from 'path'
|
||||
import Sequelize = require('sequelize')
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const Sequelize = require('sequelize')
|
||||
import { CONFIG } from './constants'
|
||||
// Do not use barrel, we need to load database first
|
||||
import { logger } from '../helpers/logger'
|
||||
import { isTestInstance } from '../helpers/utils'
|
||||
|
||||
const constants = require('../initializers/constants')
|
||||
const logger = require('../helpers/logger')
|
||||
const utils = require('../helpers/utils')
|
||||
const dbname = CONFIG.DATABASE.DBNAME
|
||||
const username = CONFIG.DATABASE.USERNAME
|
||||
const password = CONFIG.DATABASE.PASSWORD
|
||||
|
||||
const database = {}
|
||||
|
||||
const dbname = constants.CONFIG.DATABASE.DBNAME
|
||||
const username = constants.CONFIG.DATABASE.USERNAME
|
||||
const password = constants.CONFIG.DATABASE.PASSWORD
|
||||
const database: any = {}
|
||||
|
||||
const sequelize = new Sequelize(dbname, username, password, {
|
||||
dialect: 'postgres',
|
||||
host: constants.CONFIG.DATABASE.HOSTNAME,
|
||||
port: constants.CONFIG.DATABASE.PORT,
|
||||
benchmark: utils.isTestInstance(),
|
||||
host: CONFIG.DATABASE.HOSTNAME,
|
||||
port: CONFIG.DATABASE.PORT,
|
||||
benchmark: isTestInstance(),
|
||||
|
||||
logging: function (message, benchmark) {
|
||||
let newMessage = message
|
||||
|
@ -31,24 +30,16 @@ const sequelize = new Sequelize(dbname, username, password, {
|
|||
})
|
||||
|
||||
database.sequelize = sequelize
|
||||
database.Sequelize = Sequelize
|
||||
database.init = init
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = database
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function init (silent, callback) {
|
||||
database.init = function (silent, callback) {
|
||||
if (!callback) {
|
||||
callback = silent
|
||||
silent = false
|
||||
}
|
||||
|
||||
if (!callback) callback = function () {}
|
||||
if (!callback) callback = function () { /* empty */ }
|
||||
|
||||
const modelDirectory = path.join(__dirname, '..', 'models')
|
||||
const modelDirectory = join(__dirname, '..', 'models')
|
||||
fs.readdir(modelDirectory, function (err, files) {
|
||||
if (err) throw err
|
||||
|
||||
|
@ -59,9 +50,9 @@ function init (silent, callback) {
|
|||
return true
|
||||
})
|
||||
.forEach(function (file) {
|
||||
const model = sequelize.import(path.join(modelDirectory, file))
|
||||
const model = sequelize.import(join(modelDirectory, file))
|
||||
|
||||
database[model.name] = model
|
||||
database[model['name']] = model
|
||||
})
|
||||
|
||||
Object.keys(database).forEach(function (modelName) {
|
||||
|
@ -75,3 +66,7 @@ function init (silent, callback) {
|
|||
return callback(null)
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = database
|
|
@ -0,0 +1,6 @@
|
|||
// Constants first, databse in second!
|
||||
export * from './constants'
|
||||
export * from './database'
|
||||
export * from './checker'
|
||||
export * from './installer'
|
||||
export * from './migrator'
|
|
@ -1,21 +1,13 @@
|
|||
'use strict'
|
||||
import { join } from 'path'
|
||||
import config = require('config')
|
||||
import { each, series } from 'async'
|
||||
import mkdirp = require('mkdirp')
|
||||
import passwordGenerator = require('password-generator')
|
||||
|
||||
const config = require('config')
|
||||
const each = require('async/each')
|
||||
const mkdirp = require('mkdirp')
|
||||
const passwordGenerator = require('password-generator')
|
||||
const path = require('path')
|
||||
const series = require('async/series')
|
||||
|
||||
const checker = require('./checker')
|
||||
const constants = require('./constants')
|
||||
const db = require('./database')
|
||||
const logger = require('../helpers/logger')
|
||||
const peertubeCrypto = require('../helpers/peertube-crypto')
|
||||
|
||||
const installer = {
|
||||
installApplication
|
||||
}
|
||||
import { USER_ROLES, CONFIG, LAST_MIGRATION_VERSION } from './constants'
|
||||
import { clientsExist, usersExist } from './checker'
|
||||
import { logger, createCertsIfNotExist } from '../helpers'
|
||||
|
||||
function installApplication (callback) {
|
||||
series([
|
||||
|
@ -29,7 +21,7 @@ function installApplication (callback) {
|
|||
},
|
||||
|
||||
function createCertificates (callbackAsync) {
|
||||
peertubeCrypto.createCertsIfNotExist(callbackAsync)
|
||||
createCertsIfNotExist(callbackAsync)
|
||||
},
|
||||
|
||||
function createOAuthClient (callbackAsync) {
|
||||
|
@ -44,7 +36,9 @@ function installApplication (callback) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = installer
|
||||
export {
|
||||
installApplication
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
@ -53,12 +47,12 @@ function createDirectoriesIfNotExist (callback) {
|
|||
|
||||
each(Object.keys(storages), function (key, callbackEach) {
|
||||
const dir = storages[key]
|
||||
mkdirp(path.join(__dirname, '..', '..', dir), callbackEach)
|
||||
mkdirp(join(__dirname, '..', '..', dir), callbackEach)
|
||||
}, callback)
|
||||
}
|
||||
|
||||
function createOAuthClientIfNotExist (callback) {
|
||||
checker.clientsExist(function (err, exist) {
|
||||
clientsExist(function (err, exist) {
|
||||
if (err) return callback(err)
|
||||
|
||||
// Nothing to do, clients already exist
|
||||
|
@ -86,7 +80,7 @@ function createOAuthClientIfNotExist (callback) {
|
|||
}
|
||||
|
||||
function createOAuthAdminIfNotExist (callback) {
|
||||
checker.usersExist(function (err, exist) {
|
||||
usersExist(function (err, exist) {
|
||||
if (err) return callback(err)
|
||||
|
||||
// Nothing to do, users already exist
|
||||
|
@ -95,9 +89,9 @@ function createOAuthAdminIfNotExist (callback) {
|
|||
logger.info('Creating the administrator.')
|
||||
|
||||
const username = 'root'
|
||||
const role = constants.USER_ROLES.ADMIN
|
||||
const email = constants.CONFIG.ADMIN.EMAIL
|
||||
const createOptions = {}
|
||||
const role = USER_ROLES.ADMIN
|
||||
const email = CONFIG.ADMIN.EMAIL
|
||||
const createOptions: { validate?: boolean } = {}
|
||||
let password = ''
|
||||
|
||||
// Do not generate a random password for tests
|
||||
|
@ -128,7 +122,7 @@ function createOAuthAdminIfNotExist (callback) {
|
|||
logger.info('User password: ' + password)
|
||||
|
||||
logger.info('Creating Application table.')
|
||||
db.Application.create({ migrationVersion: constants.LAST_MIGRATION_VERSION }).asCallback(callback)
|
||||
db.Application.create({ migrationVersion: LAST_MIGRATION_VERSION }).asCallback(callback)
|
||||
})
|
||||
})
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
const waterfall = require('async/waterfall')
|
||||
import { waterfall } from 'async'
|
||||
|
||||
// utils = { transaction, queryInterface, sequelize, Sequelize }
|
||||
exports.up = function (utils, finalCallback) {
|
||||
function up (utils, finalCallback) {
|
||||
const q = utils.queryInterface
|
||||
const Sequelize = utils.Sequelize
|
||||
|
||||
|
@ -36,6 +34,11 @@ exports.up = function (utils, finalCallback) {
|
|||
], finalCallback)
|
||||
}
|
||||
|
||||
exports.down = function (options, callback) {
|
||||
function down (options, callback) {
|
||||
throw new Error('Not implemented.')
|
||||
}
|
||||
|
||||
export {
|
||||
up,
|
||||
down
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
const waterfall = require('async/waterfall')
|
||||
import { waterfall } from 'async'
|
||||
|
||||
// utils = { transaction, queryInterface, sequelize, Sequelize }
|
||||
exports.up = function (utils, finalCallback) {
|
||||
function up (utils, finalCallback) {
|
||||
const q = utils.queryInterface
|
||||
const Sequelize = utils.Sequelize
|
||||
|
||||
|
@ -36,6 +34,11 @@ exports.up = function (utils, finalCallback) {
|
|||
], finalCallback)
|
||||
}
|
||||
|
||||
exports.down = function (options, callback) {
|
||||
function down (options, callback) {
|
||||
throw new Error('Not implemented.')
|
||||
}
|
||||
|
||||
export {
|
||||
up,
|
||||
down
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
'use strict'
|
||||
|
||||
// utils = { transaction, queryInterface, sequelize, Sequelize }
|
||||
exports.up = function (utils, finalCallback) {
|
||||
function up (utils, finalCallback) {
|
||||
const q = utils.queryInterface
|
||||
const Sequelize = utils.Sequelize
|
||||
|
||||
|
@ -14,6 +12,11 @@ exports.up = function (utils, finalCallback) {
|
|||
q.addColumn('Videos', 'views', data, { transaction: utils.transaction }).asCallback(finalCallback)
|
||||
}
|
||||
|
||||
exports.down = function (options, callback) {
|
||||
function down (options, callback) {
|
||||
throw new Error('Not implemented.')
|
||||
}
|
||||
|
||||
export {
|
||||
up,
|
||||
down
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
'use strict'
|
||||
|
||||
// utils = { transaction, queryInterface, sequelize, Sequelize }
|
||||
exports.up = function (utils, finalCallback) {
|
||||
function up (utils, finalCallback) {
|
||||
const q = utils.queryInterface
|
||||
const Sequelize = utils.Sequelize
|
||||
|
||||
|
@ -14,6 +12,11 @@ exports.up = function (utils, finalCallback) {
|
|||
q.addColumn('Videos', 'likes', data, { transaction: utils.transaction }).asCallback(finalCallback)
|
||||
}
|
||||
|
||||
exports.down = function (options, callback) {
|
||||
function down (options, callback) {
|
||||
throw new Error('Not implemented.')
|
||||
}
|
||||
|
||||
export {
|
||||
up,
|
||||
down
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
'use strict'
|
||||
|
||||
// utils = { transaction, queryInterface, sequelize, Sequelize }
|
||||
exports.up = function (utils, finalCallback) {
|
||||
function up (utils, finalCallback) {
|
||||
const q = utils.queryInterface
|
||||
const Sequelize = utils.Sequelize
|
||||
|
||||
|
@ -14,6 +12,11 @@ exports.up = function (utils, finalCallback) {
|
|||
q.addColumn('Videos', 'dislikes', data, { transaction: utils.transaction }).asCallback(finalCallback)
|
||||
}
|
||||
|
||||
exports.down = function (options, callback) {
|
||||
function down (options, callback) {
|
||||
throw new Error('Not implemented.')
|
||||
}
|
||||
|
||||
export {
|
||||
up,
|
||||
down
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
const waterfall = require('async/waterfall')
|
||||
import { waterfall } from 'async'
|
||||
|
||||
// utils = { transaction, queryInterface, sequelize, Sequelize }
|
||||
exports.up = function (utils, finalCallback) {
|
||||
function up (utils, finalCallback) {
|
||||
const q = utils.queryInterface
|
||||
const Sequelize = utils.Sequelize
|
||||
|
||||
|
@ -29,6 +27,11 @@ exports.up = function (utils, finalCallback) {
|
|||
], finalCallback)
|
||||
}
|
||||
|
||||
exports.down = function (options, callback) {
|
||||
function down (options, callback) {
|
||||
throw new Error('Not implemented.')
|
||||
}
|
||||
|
||||
export {
|
||||
up,
|
||||
down
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
const waterfall = require('async/waterfall')
|
||||
import { waterfall } from 'async'
|
||||
|
||||
// utils = { transaction, queryInterface, sequelize, Sequelize }
|
||||
exports.up = function (utils, finalCallback) {
|
||||
function up (utils, finalCallback) {
|
||||
const q = utils.queryInterface
|
||||
const Sequelize = utils.Sequelize
|
||||
|
||||
|
@ -29,6 +27,11 @@ exports.up = function (utils, finalCallback) {
|
|||
], finalCallback)
|
||||
}
|
||||
|
||||
exports.down = function (options, callback) {
|
||||
function down (options, callback) {
|
||||
throw new Error('Not implemented.')
|
||||
}
|
||||
|
||||
export {
|
||||
up,
|
||||
down
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
const waterfall = require('async/waterfall')
|
||||
import { waterfall } from 'async'
|
||||
|
||||
// utils = { transaction, queryInterface, sequelize, Sequelize }
|
||||
exports.up = function (utils, finalCallback) {
|
||||
function up (utils, finalCallback) {
|
||||
const q = utils.queryInterface
|
||||
const Sequelize = utils.Sequelize
|
||||
|
||||
|
@ -29,6 +27,11 @@ exports.up = function (utils, finalCallback) {
|
|||
], finalCallback)
|
||||
}
|
||||
|
||||
exports.down = function (options, callback) {
|
||||
function down (options, callback) {
|
||||
throw new Error('Not implemented.')
|
||||
}
|
||||
|
||||
export {
|
||||
up,
|
||||
down
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
'use strict'
|
||||
|
||||
// utils = { transaction, queryInterface, sequelize, Sequelize }
|
||||
exports.up = function (utils, finalCallback) {
|
||||
function up (utils, finalCallback) {
|
||||
const q = utils.queryInterface
|
||||
const Sequelize = utils.Sequelize
|
||||
|
||||
|
@ -14,6 +12,11 @@ exports.up = function (utils, finalCallback) {
|
|||
q.addColumn('Users', 'displayNSFW', data, { transaction: utils.transaction }).asCallback(finalCallback)
|
||||
}
|
||||
|
||||
exports.down = function (options, callback) {
|
||||
function down (options, callback) {
|
||||
throw new Error('Not implemented.')
|
||||
}
|
||||
|
||||
export {
|
||||
up,
|
||||
down
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
'use strict'
|
||||
|
||||
// utils = { transaction, queryInterface, sequelize, Sequelize }
|
||||
exports.up = function (utils, finalCallback) {
|
||||
function up (utils, finalCallback) {
|
||||
const q = utils.queryInterface
|
||||
const Sequelize = utils.Sequelize
|
||||
|
||||
|
@ -14,6 +12,11 @@ exports.up = function (utils, finalCallback) {
|
|||
q.addColumn('Videos', 'language', data, { transaction: utils.transaction }).asCallback(finalCallback)
|
||||
}
|
||||
|
||||
exports.down = function (options, callback) {
|
||||
function down (options, callback) {
|
||||
throw new Error('Not implemented.')
|
||||
}
|
||||
|
||||
export {
|
||||
up,
|
||||
down
|
||||
}
|
|
@ -1,17 +1,10 @@
|
|||
'use strict'
|
||||
import { waterfall, eachSeries } from 'async'
|
||||
import fs = require('fs')
|
||||
import path = require('path')
|
||||
|
||||
const waterfall = require('async/waterfall')
|
||||
const eachSeries = require('async/eachSeries')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const constants = require('./constants')
|
||||
const db = require('./database')
|
||||
const logger = require('../helpers/logger')
|
||||
|
||||
const migrator = {
|
||||
migrate: migrate
|
||||
}
|
||||
import { LAST_MIGRATION_VERSION } from './constants'
|
||||
import { logger } from '../helpers'
|
||||
|
||||
function migrate (finalCallback) {
|
||||
waterfall([
|
||||
|
@ -46,7 +39,7 @@ function migrate (finalCallback) {
|
|||
|
||||
function abortMigrationIfNotNeeded (actualVersion, callback) {
|
||||
// No need migrations
|
||||
if (actualVersion >= constants.LAST_MIGRATION_VERSION) return finalCallback(null)
|
||||
if (actualVersion >= LAST_MIGRATION_VERSION) return finalCallback(null)
|
||||
|
||||
return callback(null, actualVersion)
|
||||
},
|
||||
|
@ -66,7 +59,7 @@ function migrate (finalCallback) {
|
|||
}, function (err) {
|
||||
if (err) return callback(err)
|
||||
|
||||
logger.info('Migrations finished. New migration version schema: %s', constants.LAST_MIGRATION_VERSION)
|
||||
logger.info('Migrations finished. New migration version schema: %s', LAST_MIGRATION_VERSION)
|
||||
return callback(null)
|
||||
})
|
||||
}
|
||||
|
@ -75,7 +68,9 @@ function migrate (finalCallback) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = migrator
|
||||
export {
|
||||
migrate
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -1,48 +1,35 @@
|
|||
'use strict'
|
||||
import { each, eachLimit, eachSeries, series, waterfall } from 'async'
|
||||
import request = require('request')
|
||||
|
||||
const each = require('async/each')
|
||||
const eachLimit = require('async/eachLimit')
|
||||
const eachSeries = require('async/eachSeries')
|
||||
const series = require('async/series')
|
||||
const request = require('request')
|
||||
const waterfall = require('async/waterfall')
|
||||
|
||||
const constants = require('../initializers/constants')
|
||||
const db = require('../initializers/database')
|
||||
const logger = require('../helpers/logger')
|
||||
const peertubeCrypto = require('../helpers/peertube-crypto')
|
||||
const requests = require('../helpers/requests')
|
||||
const utils = require('../helpers/utils')
|
||||
const RequestScheduler = require('./request/request-scheduler')
|
||||
const RequestVideoQaduScheduler = require('./request/request-video-qadu-scheduler')
|
||||
const RequestVideoEventScheduler = require('./request/request-video-event-scheduler')
|
||||
import {
|
||||
API_VERSION,
|
||||
CONFIG,
|
||||
REQUESTS_IN_PARALLEL,
|
||||
REQUEST_ENDPOINTS,
|
||||
REQUEST_ENDPOINT_ACTIONS,
|
||||
REMOTE_SCHEME
|
||||
} from '../initializers'
|
||||
import {
|
||||
logger,
|
||||
getMyPublicCert,
|
||||
makeSecureRequest,
|
||||
makeRetryRequest,
|
||||
createEmptyCallback
|
||||
} from '../helpers'
|
||||
import {
|
||||
RequestScheduler,
|
||||
RequestVideoQaduScheduler,
|
||||
RequestVideoEventScheduler
|
||||
} from './request'
|
||||
|
||||
const ENDPOINT_ACTIONS = constants.REQUEST_ENDPOINT_ACTIONS[constants.REQUEST_ENDPOINTS.VIDEOS]
|
||||
const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS]
|
||||
|
||||
const requestScheduler = new RequestScheduler()
|
||||
const requestVideoQaduScheduler = new RequestVideoQaduScheduler()
|
||||
const requestVideoEventScheduler = new RequestVideoEventScheduler()
|
||||
|
||||
const friends = {
|
||||
activate,
|
||||
addVideoToFriends,
|
||||
updateVideoToFriends,
|
||||
reportAbuseVideoToFriend,
|
||||
quickAndDirtyUpdateVideoToFriends,
|
||||
quickAndDirtyUpdatesVideoToFriends,
|
||||
addEventToRemoteVideo,
|
||||
addEventsToRemoteVideo,
|
||||
hasFriends,
|
||||
makeFriends,
|
||||
quitFriends,
|
||||
removeVideoToFriends,
|
||||
sendOwnedVideosToPod,
|
||||
getRequestScheduler,
|
||||
getRequestVideoQaduScheduler,
|
||||
getRequestVideoEventScheduler
|
||||
}
|
||||
|
||||
function activate () {
|
||||
function activateSchedulers () {
|
||||
requestScheduler.activate()
|
||||
requestVideoQaduScheduler.activate()
|
||||
requestVideoEventScheduler.activate()
|
||||
|
@ -51,7 +38,7 @@ function activate () {
|
|||
function addVideoToFriends (videoData, transaction, callback) {
|
||||
const options = {
|
||||
type: ENDPOINT_ACTIONS.ADD,
|
||||
endpoint: constants.REQUEST_ENDPOINTS.VIDEOS,
|
||||
endpoint: REQUEST_ENDPOINTS.VIDEOS,
|
||||
data: videoData,
|
||||
transaction
|
||||
}
|
||||
|
@ -61,7 +48,7 @@ function addVideoToFriends (videoData, transaction, callback) {
|
|||
function updateVideoToFriends (videoData, transaction, callback) {
|
||||
const options = {
|
||||
type: ENDPOINT_ACTIONS.UPDATE,
|
||||
endpoint: constants.REQUEST_ENDPOINTS.VIDEOS,
|
||||
endpoint: REQUEST_ENDPOINTS.VIDEOS,
|
||||
data: videoData,
|
||||
transaction
|
||||
}
|
||||
|
@ -71,7 +58,7 @@ function updateVideoToFriends (videoData, transaction, callback) {
|
|||
function removeVideoToFriends (videoParams) {
|
||||
const options = {
|
||||
type: ENDPOINT_ACTIONS.REMOVE,
|
||||
endpoint: constants.REQUEST_ENDPOINTS.VIDEOS,
|
||||
endpoint: REQUEST_ENDPOINTS.VIDEOS,
|
||||
data: videoParams
|
||||
}
|
||||
createRequest(options)
|
||||
|
@ -80,14 +67,14 @@ function removeVideoToFriends (videoParams) {
|
|||
function reportAbuseVideoToFriend (reportData, video) {
|
||||
const options = {
|
||||
type: ENDPOINT_ACTIONS.REPORT_ABUSE,
|
||||
endpoint: constants.REQUEST_ENDPOINTS.VIDEOS,
|
||||
endpoint: REQUEST_ENDPOINTS.VIDEOS,
|
||||
data: reportData,
|
||||
toIds: [ video.Author.podId ]
|
||||
}
|
||||
createRequest(options)
|
||||
}
|
||||
|
||||
function quickAndDirtyUpdateVideoToFriends (qaduParams, transaction, callback) {
|
||||
function quickAndDirtyUpdateVideoToFriends (qaduParams, transaction?, callback?) {
|
||||
const options = {
|
||||
videoId: qaduParams.videoId,
|
||||
type: qaduParams.type,
|
||||
|
@ -110,7 +97,7 @@ function quickAndDirtyUpdatesVideoToFriends (qadusParams, transaction, finalCall
|
|||
series(tasks, finalCallback)
|
||||
}
|
||||
|
||||
function addEventToRemoteVideo (eventParams, transaction, callback) {
|
||||
function addEventToRemoteVideo (eventParams, transaction?, callback?) {
|
||||
const options = {
|
||||
videoId: eventParams.videoId,
|
||||
type: eventParams.type,
|
||||
|
@ -146,7 +133,7 @@ function makeFriends (hosts, callback) {
|
|||
const podsScore = {}
|
||||
|
||||
logger.info('Make friends!')
|
||||
peertubeCrypto.getMyPublicCert(function (err, cert) {
|
||||
getMyPublicCert(function (err, cert) {
|
||||
if (err) {
|
||||
logger.error('Cannot read public cert.')
|
||||
return callback(err)
|
||||
|
@ -186,16 +173,17 @@ function quitFriends (callback) {
|
|||
function announceIQuitMyFriends (pods, callbackAsync) {
|
||||
const requestParams = {
|
||||
method: 'POST',
|
||||
path: '/api/' + constants.API_VERSION + '/remote/pods/remove',
|
||||
sign: true
|
||||
path: '/api/' + API_VERSION + '/remote/pods/remove',
|
||||
sign: true,
|
||||
toPod: null
|
||||
}
|
||||
|
||||
// Announce we quit them
|
||||
// We don't care if the request fails
|
||||
// The other pod will exclude us automatically after a while
|
||||
eachLimit(pods, constants.REQUESTS_IN_PARALLEL, function (pod, callbackEach) {
|
||||
eachLimit(pods, REQUESTS_IN_PARALLEL, function (pod, callbackEach) {
|
||||
requestParams.toPod = pod
|
||||
requests.makeSecureRequest(requestParams, callbackEach)
|
||||
makeSecureRequest(requestParams, callbackEach)
|
||||
}, function (err) {
|
||||
if (err) {
|
||||
logger.error('Some errors while quitting friends.', { err: err })
|
||||
|
@ -207,7 +195,7 @@ function quitFriends (callback) {
|
|||
},
|
||||
|
||||
function removePodsFromDB (pods, callbackAsync) {
|
||||
each(pods, function (pod, callbackEach) {
|
||||
each(pods, function (pod: any, callbackEach) {
|
||||
pod.destroy().asCallback(callbackEach)
|
||||
}, callbackAsync)
|
||||
}
|
||||
|
@ -239,7 +227,7 @@ function sendOwnedVideosToPod (podId) {
|
|||
|
||||
const options = {
|
||||
type: 'add',
|
||||
endpoint: constants.REQUEST_ENDPOINTS.VIDEOS,
|
||||
endpoint: REQUEST_ENDPOINTS.VIDEOS,
|
||||
data: remoteVideo,
|
||||
toIds: [ podId ]
|
||||
}
|
||||
|
@ -263,7 +251,24 @@ function getRequestVideoEventScheduler () {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = friends
|
||||
export {
|
||||
activateSchedulers,
|
||||
addVideoToFriends,
|
||||
updateVideoToFriends,
|
||||
reportAbuseVideoToFriend,
|
||||
quickAndDirtyUpdateVideoToFriends,
|
||||
quickAndDirtyUpdatesVideoToFriends,
|
||||
addEventToRemoteVideo,
|
||||
addEventsToRemoteVideo,
|
||||
hasFriends,
|
||||
makeFriends,
|
||||
quitFriends,
|
||||
removeVideoToFriends,
|
||||
sendOwnedVideosToPod,
|
||||
getRequestScheduler,
|
||||
getRequestVideoQaduScheduler,
|
||||
getRequestVideoEventScheduler
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
@ -304,9 +309,9 @@ function computeWinningPods (hosts, podsScore) {
|
|||
}
|
||||
|
||||
function getForeignPodsList (host, callback) {
|
||||
const path = '/api/' + constants.API_VERSION + '/pods'
|
||||
const path = '/api/' + API_VERSION + '/pods'
|
||||
|
||||
request.get(constants.REMOTE_SCHEME.HTTP + '://' + host + path, function (err, response, body) {
|
||||
request.get(REMOTE_SCHEME.HTTP + '://' + host + path, function (err, response, body) {
|
||||
if (err) return callback(err)
|
||||
|
||||
try {
|
||||
|
@ -324,18 +329,18 @@ function makeRequestsToWinningPods (cert, podsList, callback) {
|
|||
// Flush pool requests
|
||||
requestScheduler.forceSend()
|
||||
|
||||
eachLimit(podsList, constants.REQUESTS_IN_PARALLEL, function (pod, callbackEach) {
|
||||
eachLimit(podsList, REQUESTS_IN_PARALLEL, function (pod: any, callbackEach) {
|
||||
const params = {
|
||||
url: constants.REMOTE_SCHEME.HTTP + '://' + pod.host + '/api/' + constants.API_VERSION + '/pods/',
|
||||
url: REMOTE_SCHEME.HTTP + '://' + pod.host + '/api/' + API_VERSION + '/pods/',
|
||||
method: 'POST',
|
||||
json: {
|
||||
host: constants.CONFIG.WEBSERVER.HOST,
|
||||
email: constants.CONFIG.ADMIN.EMAIL,
|
||||
host: CONFIG.WEBSERVER.HOST,
|
||||
email: CONFIG.ADMIN.EMAIL,
|
||||
publicKey: cert
|
||||
}
|
||||
}
|
||||
|
||||
requests.makeRetryRequest(params, function (err, res, body) {
|
||||
makeRetryRequest(params, function (err, res, body) {
|
||||
if (err) {
|
||||
logger.error('Error with adding %s pod.', pod.host, { error: err })
|
||||
// Don't break the process
|
||||
|
@ -372,8 +377,8 @@ function makeRequestsToWinningPods (cert, podsList, callback) {
|
|||
|
||||
// Wrapper that populate "toIds" argument with all our friends if it is not specified
|
||||
// { type, endpoint, data, toIds, transaction }
|
||||
function createRequest (options, callback) {
|
||||
if (!callback) callback = function () {}
|
||||
function createRequest (options, callback?) {
|
||||
if (!callback) callback = function () { /* empty */ }
|
||||
if (options.toIds) return requestScheduler.createRequest(options, callback)
|
||||
|
||||
// If the "toIds" pods is not specified, we send the request to all our friends
|
||||
|
@ -389,17 +394,17 @@ function createRequest (options, callback) {
|
|||
}
|
||||
|
||||
function createVideoQaduRequest (options, callback) {
|
||||
if (!callback) callback = utils.createEmptyCallback()
|
||||
if (!callback) callback = createEmptyCallback()
|
||||
|
||||
requestVideoQaduScheduler.createRequest(options, callback)
|
||||
}
|
||||
|
||||
function createVideoEventRequest (options, callback) {
|
||||
if (!callback) callback = utils.createEmptyCallback()
|
||||
if (!callback) callback = createEmptyCallback()
|
||||
|
||||
requestVideoEventScheduler.createRequest(options, callback)
|
||||
}
|
||||
|
||||
function isMe (host) {
|
||||
return host === constants.CONFIG.WEBSERVER.HOST
|
||||
return host === CONFIG.WEBSERVER.HOST
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
export * from './jobs'
|
||||
export * from './request'
|
||||
export * from './friends'
|
||||
export * from './oauth-model'
|
|
@ -1,7 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const videoTranscoder = require('./video-transcoder')
|
||||
|
||||
module.exports = {
|
||||
videoTranscoder
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import * as videoTranscoder from './video-transcoder'
|
||||
|
||||
const jobHandlers = {
|
||||
videoTranscoder
|
||||
}
|
||||
|
||||
export {
|
||||
jobHandlers
|
||||
}
|
|
@ -1,16 +1,6 @@
|
|||
'use strict'
|
||||
|
||||
const db = require('../../../initializers/database')
|
||||
const logger = require('../../../helpers/logger')
|
||||
const friends = require('../../../lib/friends')
|
||||
|
||||
const VideoTranscoderHandler = {
|
||||
process,
|
||||
onError,
|
||||
onSuccess
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
import { logger } from '../../../helpers'
|
||||
import { addVideoToFriends } from '../../../lib'
|
||||
|
||||
function process (data, callback) {
|
||||
db.Video.loadAndPopulateAuthorAndPodAndTags(data.id, function (err, video) {
|
||||
|
@ -34,10 +24,14 @@ function onSuccess (data, jobId, video, callback) {
|
|||
if (err) return callback(err)
|
||||
|
||||
// Now we'll add the video's meta data to our friends
|
||||
friends.addVideoToFriends(remoteVideo, null, callback)
|
||||
addVideoToFriends(remoteVideo, null, callback)
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = VideoTranscoderHandler
|
||||
export {
|
||||
process,
|
||||
onError,
|
||||
onSuccess
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export * from './job-scheduler'
|
|
@ -1,129 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const forever = require('async/forever')
|
||||
const queue = require('async/queue')
|
||||
|
||||
const constants = require('../../initializers/constants')
|
||||
const db = require('../../initializers/database')
|
||||
const logger = require('../../helpers/logger')
|
||||
|
||||
const jobHandlers = require('./handlers')
|
||||
|
||||
const jobScheduler = {
|
||||
activate,
|
||||
createJob
|
||||
}
|
||||
|
||||
function activate () {
|
||||
const limit = constants.JOBS_FETCH_LIMIT_PER_CYCLE
|
||||
|
||||
logger.info('Jobs scheduler activated.')
|
||||
|
||||
const jobsQueue = queue(processJob)
|
||||
|
||||
// Finish processing jobs from a previous start
|
||||
const state = constants.JOB_STATES.PROCESSING
|
||||
db.Job.listWithLimit(limit, state, function (err, jobs) {
|
||||
enqueueJobs(err, jobsQueue, jobs)
|
||||
|
||||
forever(
|
||||
function (next) {
|
||||
if (jobsQueue.length() !== 0) {
|
||||
// Finish processing the queue first
|
||||
return setTimeout(next, constants.JOBS_FETCHING_INTERVAL)
|
||||
}
|
||||
|
||||
const state = constants.JOB_STATES.PENDING
|
||||
db.Job.listWithLimit(limit, state, function (err, jobs) {
|
||||
if (err) {
|
||||
logger.error('Cannot list pending jobs.', { error: err })
|
||||
} else {
|
||||
jobs.forEach(function (job) {
|
||||
jobsQueue.push(job)
|
||||
})
|
||||
}
|
||||
|
||||
// Optimization: we could use "drain" from queue object
|
||||
return setTimeout(next, constants.JOBS_FETCHING_INTERVAL)
|
||||
})
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = jobScheduler
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function enqueueJobs (err, jobsQueue, jobs) {
|
||||
if (err) {
|
||||
logger.error('Cannot list pending jobs.', { error: err })
|
||||
} else {
|
||||
jobs.forEach(function (job) {
|
||||
jobsQueue.push(job)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function createJob (transaction, handlerName, handlerInputData, callback) {
|
||||
const createQuery = {
|
||||
state: constants.JOB_STATES.PENDING,
|
||||
handlerName,
|
||||
handlerInputData
|
||||
}
|
||||
const options = { transaction }
|
||||
|
||||
db.Job.create(createQuery, options).asCallback(callback)
|
||||
}
|
||||
|
||||
function processJob (job, callback) {
|
||||
const jobHandler = jobHandlers[job.handlerName]
|
||||
|
||||
logger.info('Processing job %d with handler %s.', job.id, job.handlerName)
|
||||
|
||||
job.state = constants.JOB_STATES.PROCESSING
|
||||
job.save().asCallback(function (err) {
|
||||
if (err) return cannotSaveJobError(err, callback)
|
||||
|
||||
if (jobHandler === undefined) {
|
||||
logger.error('Unknown job handler for job %s.', jobHandler.handlerName)
|
||||
return callback()
|
||||
}
|
||||
|
||||
return jobHandler.process(job.handlerInputData, function (err, result) {
|
||||
if (err) {
|
||||
logger.error('Error in job handler %s.', job.handlerName, { error: err })
|
||||
return onJobError(jobHandler, job, result, callback)
|
||||
}
|
||||
|
||||
return onJobSuccess(jobHandler, job, result, callback)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function onJobError (jobHandler, job, jobResult, callback) {
|
||||
job.state = constants.JOB_STATES.ERROR
|
||||
|
||||
job.save().asCallback(function (err) {
|
||||
if (err) return cannotSaveJobError(err, callback)
|
||||
|
||||
return jobHandler.onError(err, job.id, jobResult, callback)
|
||||
})
|
||||
}
|
||||
|
||||
function onJobSuccess (jobHandler, job, jobResult, callback) {
|
||||
job.state = constants.JOB_STATES.SUCCESS
|
||||
|
||||
job.save().asCallback(function (err) {
|
||||
if (err) return cannotSaveJobError(err, callback)
|
||||
|
||||
return jobHandler.onSuccess(err, job.id, jobResult, callback)
|
||||
})
|
||||
}
|
||||
|
||||
function cannotSaveJobError (err, callback) {
|
||||
logger.error('Cannot save new job state.', { error: err })
|
||||
return callback(err)
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
import { forever, queue } from 'async'
|
||||
|
||||
const db = require('../../initializers/database')
|
||||
import {
|
||||
JOBS_FETCHING_INTERVAL,
|
||||
JOBS_FETCH_LIMIT_PER_CYCLE,
|
||||
JOB_STATES
|
||||
} from '../../initializers'
|
||||
import { logger } from '../../helpers'
|
||||
import { jobHandlers } from './handlers'
|
||||
|
||||
class JobScheduler {
|
||||
|
||||
private static instance: JobScheduler
|
||||
|
||||
private constructor () { }
|
||||
|
||||
static get Instance () {
|
||||
return this.instance || (this.instance = new this())
|
||||
}
|
||||
|
||||
activate () {
|
||||
const limit = JOBS_FETCH_LIMIT_PER_CYCLE
|
||||
|
||||
logger.info('Jobs scheduler activated.')
|
||||
|
||||
const jobsQueue = queue(this.processJob)
|
||||
|
||||
// Finish processing jobs from a previous start
|
||||
const state = JOB_STATES.PROCESSING
|
||||
db.Job.listWithLimit(limit, state, (err, jobs) => {
|
||||
this.enqueueJobs(err, jobsQueue, jobs)
|
||||
|
||||
forever(
|
||||
next => {
|
||||
if (jobsQueue.length() !== 0) {
|
||||
// Finish processing the queue first
|
||||
return setTimeout(next, JOBS_FETCHING_INTERVAL)
|
||||
}
|
||||
|
||||
const state = JOB_STATES.PENDING
|
||||
db.Job.listWithLimit(limit, state, (err, jobs) => {
|
||||
if (err) {
|
||||
logger.error('Cannot list pending jobs.', { error: err })
|
||||
} else {
|
||||
jobs.forEach(job => {
|
||||
jobsQueue.push(job)
|
||||
})
|
||||
}
|
||||
|
||||
// Optimization: we could use "drain" from queue object
|
||||
return setTimeout(next, JOBS_FETCHING_INTERVAL)
|
||||
})
|
||||
},
|
||||
|
||||
err => { logger.error('Error in job scheduler queue.', { error: err }) }
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
createJob (transaction, handlerName, handlerInputData, callback) {
|
||||
const createQuery = {
|
||||
state: JOB_STATES.PENDING,
|
||||
handlerName,
|
||||
handlerInputData
|
||||
}
|
||||
const options = { transaction }
|
||||
|
||||
db.Job.create(createQuery, options).asCallback(callback)
|
||||
}
|
||||
|
||||
private enqueueJobs (err, jobsQueue, jobs) {
|
||||
if (err) {
|
||||
logger.error('Cannot list pending jobs.', { error: err })
|
||||
} else {
|
||||
jobs.forEach(job => {
|
||||
jobsQueue.push(job)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private processJob (job, callback) {
|
||||
const jobHandler = jobHandlers[job.handlerName]
|
||||
|
||||
logger.info('Processing job %d with handler %s.', job.id, job.handlerName)
|
||||
|
||||
job.state = JOB_STATES.PROCESSING
|
||||
job.save().asCallback(err => {
|
||||
if (err) return this.cannotSaveJobError(err, callback)
|
||||
|
||||
if (jobHandler === undefined) {
|
||||
logger.error('Unknown job handler for job %s.', jobHandler.handlerName)
|
||||
return callback()
|
||||
}
|
||||
|
||||
return jobHandler.process(job.handlerInputData, (err, result) => {
|
||||
if (err) {
|
||||
logger.error('Error in job handler %s.', job.handlerName, { error: err })
|
||||
return this.onJobError(jobHandler, job, result, callback)
|
||||
}
|
||||
|
||||
return this.onJobSuccess(jobHandler, job, result, callback)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
private onJobError (jobHandler, job, jobResult, callback) {
|
||||
job.state = JOB_STATES.ERROR
|
||||
|
||||
job.save().asCallback(err => {
|
||||
if (err) return this.cannotSaveJobError(err, callback)
|
||||
|
||||
return jobHandler.onError(err, job.id, jobResult, callback)
|
||||
})
|
||||
}
|
||||
|
||||
private onJobSuccess (jobHandler, job, jobResult, callback) {
|
||||
job.state = JOB_STATES.SUCCESS
|
||||
|
||||
job.save().asCallback(err => {
|
||||
if (err) return this.cannotSaveJobError(err, callback)
|
||||
|
||||
return jobHandler.onSuccess(err, job.id, jobResult, callback)
|
||||
})
|
||||
}
|
||||
|
||||
private cannotSaveJobError (err, callback) {
|
||||
logger.error('Cannot save new job state.', { error: err })
|
||||
return callback(err)
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
JobScheduler
|
||||
}
|
|
@ -1,15 +1,5 @@
|
|||
const db = require('../initializers/database')
|
||||
const logger = require('../helpers/logger')
|
||||
|
||||
// See https://github.com/oauthjs/node-oauth2-server/wiki/Model-specification for the model specifications
|
||||
const OAuthModel = {
|
||||
getAccessToken,
|
||||
getClient,
|
||||
getRefreshToken,
|
||||
getUser,
|
||||
revokeToken,
|
||||
saveToken
|
||||
}
|
||||
import { logger } from '../helpers'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
@ -94,4 +84,12 @@ function saveToken (token, client, user) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = OAuthModel
|
||||
// See https://github.com/oauthjs/node-oauth2-server/wiki/Model-specification for the model specifications
|
||||
export {
|
||||
getAccessToken,
|
||||
getClient,
|
||||
getRefreshToken,
|
||||
getUser,
|
||||
revokeToken,
|
||||
saveToken
|
||||
}
|
|
@ -1,19 +1,31 @@
|
|||
'use strict'
|
||||
import { eachLimit } from 'async/eachLimit'
|
||||
|
||||
const eachLimit = require('async/eachLimit')
|
||||
|
||||
const constants = require('../../initializers/constants')
|
||||
const db = require('../../initializers/database')
|
||||
const logger = require('../../helpers/logger')
|
||||
const requests = require('../../helpers/requests')
|
||||
import { logger, makeSecureRequest } from '../../helpers'
|
||||
import {
|
||||
API_VERSION,
|
||||
REQUESTS_IN_PARALLEL,
|
||||
REQUESTS_INTERVAL
|
||||
} from '../../initializers'
|
||||
|
||||
module.exports = class BaseRequestScheduler {
|
||||
constructor (options) {
|
||||
abstract class BaseRequestScheduler {
|
||||
protected lastRequestTimestamp: number
|
||||
protected timer: NodeJS.Timer
|
||||
protected requestInterval: number
|
||||
protected limitPods: number
|
||||
protected limitPerPod: number
|
||||
protected description: string
|
||||
|
||||
constructor () {
|
||||
this.lastRequestTimestamp = 0
|
||||
this.timer = null
|
||||
this.requestInterval = constants.REQUESTS_INTERVAL
|
||||
this.requestInterval = REQUESTS_INTERVAL
|
||||
}
|
||||
|
||||
abstract getRequestModel ()
|
||||
abstract getRequestToPodModel ()
|
||||
abstract buildRequestObjects (requests: any)
|
||||
|
||||
activate () {
|
||||
logger.info('Requests scheduler activated.')
|
||||
this.lastRequestTimestamp = Date.now()
|
||||
|
@ -38,30 +50,34 @@ module.exports = class BaseRequestScheduler {
|
|||
remainingMilliSeconds () {
|
||||
if (this.timer === null) return -1
|
||||
|
||||
return constants.REQUESTS_INTERVAL - (Date.now() - this.lastRequestTimestamp)
|
||||
return REQUESTS_INTERVAL - (Date.now() - this.lastRequestTimestamp)
|
||||
}
|
||||
|
||||
remainingRequestsCount (callback) {
|
||||
return this.getRequestModel().countTotalRequests(callback)
|
||||
}
|
||||
|
||||
flush (callback) {
|
||||
this.getRequestModel().removeAll(callback)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Make a requests to friends of a certain type
|
||||
makeRequest (toPod, requestEndpoint, requestsToMake, callback) {
|
||||
if (!callback) callback = function () {}
|
||||
protected makeRequest (toPod, requestEndpoint, requestsToMake, callback) {
|
||||
if (!callback) callback = function () { /* empty */ }
|
||||
|
||||
const params = {
|
||||
toPod: toPod,
|
||||
sign: true, // Prove our identity
|
||||
method: 'POST',
|
||||
path: '/api/' + constants.API_VERSION + '/remote/' + requestEndpoint,
|
||||
path: '/api/' + API_VERSION + '/remote/' + requestEndpoint,
|
||||
data: requestsToMake // Requests we need to make
|
||||
}
|
||||
|
||||
// Make multiple retry requests to all of pods
|
||||
// The function fire some useful callbacks
|
||||
requests.makeSecureRequest(params, (err, res) => {
|
||||
makeSecureRequest(params, (err, res) => {
|
||||
if (err || (res.statusCode !== 200 && res.statusCode !== 201 && res.statusCode !== 204)) {
|
||||
err = err ? err.message : 'Status code not 20x : ' + res.statusCode
|
||||
logger.error('Error sending secure request to %s pod.', toPod.host, { error: err })
|
||||
|
@ -74,7 +90,7 @@ module.exports = class BaseRequestScheduler {
|
|||
}
|
||||
|
||||
// Make all the requests of the scheduler
|
||||
makeRequests () {
|
||||
protected makeRequests () {
|
||||
this.getRequestModel().listWithLimitAndRandom(this.limitPods, this.limitPerPod, (err, requests) => {
|
||||
if (err) {
|
||||
logger.error('Cannot get the list of "%s".', this.description, { err: err })
|
||||
|
@ -95,7 +111,7 @@ module.exports = class BaseRequestScheduler {
|
|||
const goodPods = []
|
||||
const badPods = []
|
||||
|
||||
eachLimit(Object.keys(requestsToMakeGrouped), constants.REQUESTS_IN_PARALLEL, (hashKey, callbackEach) => {
|
||||
eachLimit(Object.keys(requestsToMakeGrouped), REQUESTS_IN_PARALLEL, (hashKey, callbackEach) => {
|
||||
const requestToMake = requestsToMakeGrouped[hashKey]
|
||||
const toPod = requestToMake.toPod
|
||||
|
||||
|
@ -122,15 +138,17 @@ module.exports = class BaseRequestScheduler {
|
|||
})
|
||||
}
|
||||
|
||||
flush (callback) {
|
||||
this.getRequestModel().removeAll(callback)
|
||||
}
|
||||
|
||||
afterRequestHook () {
|
||||
protected afterRequestHook () {
|
||||
// Nothing to do, let children reimplement it
|
||||
}
|
||||
|
||||
afterRequestsHook () {
|
||||
protected afterRequestsHook () {
|
||||
// Nothing to do, let children reimplement it
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
BaseRequestScheduler
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export * from './request-scheduler'
|
||||
export * from './request-video-event-scheduler'
|
||||
export * from './request-video-qadu-scheduler'
|
|
@ -1,17 +1,18 @@
|
|||
'use strict'
|
||||
|
||||
const constants = require('../../initializers/constants')
|
||||
const BaseRequestScheduler = require('./base-request-scheduler')
|
||||
const db = require('../../initializers/database')
|
||||
const logger = require('../../helpers/logger')
|
||||
import { BaseRequestScheduler } from './base-request-scheduler'
|
||||
import { logger } from '../../helpers'
|
||||
import {
|
||||
REQUESTS_LIMIT_PODS,
|
||||
REQUESTS_LIMIT_PER_POD
|
||||
} from '../../initializers'
|
||||
|
||||
module.exports = class RequestScheduler extends BaseRequestScheduler {
|
||||
class RequestScheduler extends BaseRequestScheduler {
|
||||
constructor () {
|
||||
super()
|
||||
|
||||
// We limit the size of the requests
|
||||
this.limitPods = constants.REQUESTS_LIMIT_PODS
|
||||
this.limitPerPod = constants.REQUESTS_LIMIT_PER_POD
|
||||
this.limitPods = REQUESTS_LIMIT_PODS
|
||||
this.limitPerPod = REQUESTS_LIMIT_PER_POD
|
||||
|
||||
this.description = 'requests'
|
||||
}
|
||||
|
@ -95,3 +96,9 @@ module.exports = class RequestScheduler extends BaseRequestScheduler {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
RequestScheduler
|
||||
}
|
|
@ -1,16 +1,18 @@
|
|||
'use strict'
|
||||
|
||||
const BaseRequestScheduler = require('./base-request-scheduler')
|
||||
const constants = require('../../initializers/constants')
|
||||
const db = require('../../initializers/database')
|
||||
import { BaseRequestScheduler } from './base-request-scheduler'
|
||||
import {
|
||||
REQUESTS_VIDEO_EVENT_LIMIT_PODS,
|
||||
REQUESTS_VIDEO_EVENT_LIMIT_PER_POD,
|
||||
REQUEST_VIDEO_EVENT_ENDPOINT
|
||||
} from '../../initializers'
|
||||
|
||||
module.exports = class RequestVideoEventScheduler extends BaseRequestScheduler {
|
||||
class RequestVideoEventScheduler extends BaseRequestScheduler {
|
||||
constructor () {
|
||||
super()
|
||||
|
||||
// We limit the size of the requests
|
||||
this.limitPods = constants.REQUESTS_VIDEO_EVENT_LIMIT_PODS
|
||||
this.limitPerPod = constants.REQUESTS_VIDEO_EVENT_LIMIT_PER_POD
|
||||
this.limitPods = REQUESTS_VIDEO_EVENT_LIMIT_PODS
|
||||
this.limitPerPod = REQUESTS_VIDEO_EVENT_LIMIT_PER_POD
|
||||
|
||||
this.description = 'video event requests'
|
||||
}
|
||||
|
@ -45,7 +47,7 @@ module.exports = class RequestVideoEventScheduler extends BaseRequestScheduler {
|
|||
if (!requestsToMakeGrouped[toPodId]) {
|
||||
requestsToMakeGrouped[toPodId] = {
|
||||
toPod: eventToProcess.pod,
|
||||
endpoint: constants.REQUEST_VIDEO_EVENT_ENDPOINT,
|
||||
endpoint: REQUEST_VIDEO_EVENT_ENDPOINT,
|
||||
ids: [], // request ids, to delete them from the DB in the future
|
||||
datas: [] // requests data
|
||||
}
|
||||
|
@ -94,7 +96,7 @@ module.exports = class RequestVideoEventScheduler extends BaseRequestScheduler {
|
|||
|
||||
if (count === undefined) count = 1
|
||||
|
||||
const dbRequestOptions = {}
|
||||
const dbRequestOptions: { transaction?: any } = {}
|
||||
if (transaction) dbRequestOptions.transaction = transaction
|
||||
|
||||
const createQuery = {
|
||||
|
@ -106,3 +108,9 @@ module.exports = class RequestVideoEventScheduler extends BaseRequestScheduler {
|
|||
return db.RequestVideoEvent.create(createQuery, dbRequestOptions).asCallback(callback)
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
RequestVideoEventScheduler
|
||||
}
|
|
@ -1,17 +1,20 @@
|
|||
'use strict'
|
||||
|
||||
const BaseRequestScheduler = require('./base-request-scheduler')
|
||||
const constants = require('../../initializers/constants')
|
||||
const db = require('../../initializers/database')
|
||||
const logger = require('../../helpers/logger')
|
||||
import { BaseRequestScheduler } from './base-request-scheduler'
|
||||
import { logger } from '../../helpers'
|
||||
import {
|
||||
REQUESTS_VIDEO_QADU_LIMIT_PODS,
|
||||
REQUESTS_VIDEO_QADU_LIMIT_PER_POD,
|
||||
REQUEST_VIDEO_QADU_ENDPOINT,
|
||||
REQUEST_VIDEO_QADU_TYPES
|
||||
} from '../../initializers'
|
||||
|
||||
module.exports = class RequestVideoQaduScheduler extends BaseRequestScheduler {
|
||||
class RequestVideoQaduScheduler extends BaseRequestScheduler {
|
||||
constructor () {
|
||||
super()
|
||||
|
||||
// We limit the size of the requests
|
||||
this.limitPods = constants.REQUESTS_VIDEO_QADU_LIMIT_PODS
|
||||
this.limitPerPod = constants.REQUESTS_VIDEO_QADU_LIMIT_PER_POD
|
||||
this.limitPods = REQUESTS_VIDEO_QADU_LIMIT_PODS
|
||||
this.limitPerPod = REQUESTS_VIDEO_QADU_LIMIT_PER_POD
|
||||
|
||||
this.description = 'video QADU requests'
|
||||
}
|
||||
|
@ -37,7 +40,7 @@ module.exports = class RequestVideoQaduScheduler extends BaseRequestScheduler {
|
|||
if (!requestsToMakeGrouped[hashKey]) {
|
||||
requestsToMakeGrouped[hashKey] = {
|
||||
toPod: pod,
|
||||
endpoint: constants.REQUEST_VIDEO_QADU_ENDPOINT,
|
||||
endpoint: REQUEST_VIDEO_QADU_ENDPOINT,
|
||||
ids: [], // request ids, to delete them from the DB in the future
|
||||
datas: [], // requests data
|
||||
videos: {}
|
||||
|
@ -49,15 +52,15 @@ module.exports = class RequestVideoQaduScheduler extends BaseRequestScheduler {
|
|||
if (!videoData) videoData = {}
|
||||
|
||||
switch (request.type) {
|
||||
case constants.REQUEST_VIDEO_QADU_TYPES.LIKES:
|
||||
case REQUEST_VIDEO_QADU_TYPES.LIKES:
|
||||
videoData.likes = video.likes
|
||||
break
|
||||
|
||||
case constants.REQUEST_VIDEO_QADU_TYPES.DISLIKES:
|
||||
case REQUEST_VIDEO_QADU_TYPES.DISLIKES:
|
||||
videoData.dislikes = video.dislikes
|
||||
break
|
||||
|
||||
case constants.REQUEST_VIDEO_QADU_TYPES.VIEWS:
|
||||
case REQUEST_VIDEO_QADU_TYPES.VIEWS:
|
||||
videoData.views = video.views
|
||||
break
|
||||
|
||||
|
@ -99,7 +102,7 @@ module.exports = class RequestVideoQaduScheduler extends BaseRequestScheduler {
|
|||
const videoId = options.videoId
|
||||
const transaction = options.transaction
|
||||
|
||||
const dbRequestOptions = {}
|
||||
const dbRequestOptions: { transaction?: any } = {}
|
||||
if (transaction) dbRequestOptions.transaction = transaction
|
||||
|
||||
// Send the update to all our friends
|
||||
|
@ -115,3 +118,9 @@ module.exports = class RequestVideoQaduScheduler extends BaseRequestScheduler {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
RequestVideoQaduScheduler
|
||||
}
|
|
@ -1,11 +1,5 @@
|
|||
'use strict'
|
||||
|
||||
const logger = require('../helpers/logger')
|
||||
|
||||
const adminMiddleware = {
|
||||
ensureIsAdmin
|
||||
}
|
||||
|
||||
function ensureIsAdmin (req, res, next) {
|
||||
const user = res.locals.oauth.token.user
|
||||
if (user.isAdmin() === false) {
|
||||
|
@ -18,4 +12,6 @@ function ensureIsAdmin (req, res, next) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = adminMiddleware
|
||||
export {
|
||||
ensureIsAdmin
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const adminMiddleware = require('./admin')
|
||||
const oauthMiddleware = require('./oauth')
|
||||
const paginationMiddleware = require('./pagination')
|
||||
const podsMiddleware = require('./pods')
|
||||
const validatorsMiddleware = require('./validators')
|
||||
const searchMiddleware = require('./search')
|
||||
const sortMiddleware = require('./sort')
|
||||
const secureMiddleware = require('./secure')
|
||||
|
||||
const middlewares = {
|
||||
admin: adminMiddleware,
|
||||
oauth: oauthMiddleware,
|
||||
pagination: paginationMiddleware,
|
||||
pods: podsMiddleware,
|
||||
search: searchMiddleware,
|
||||
secure: secureMiddleware,
|
||||
sort: sortMiddleware,
|
||||
validators: validatorsMiddleware
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = middlewares
|
|
@ -0,0 +1,8 @@
|
|||
export * from './validators';
|
||||
export * from './admin';
|
||||
export * from './oauth';
|
||||
export * from './pagination';
|
||||
export * from './pods';
|
||||
export * from './search';
|
||||
export * from './secure';
|
||||
export * from './sort';
|
|
@ -1,6 +1,4 @@
|
|||
'use strict'
|
||||
|
||||
const OAuthServer = require('express-oauth-server')
|
||||
import OAuthServer = require('express-oauth-server')
|
||||
|
||||
const constants = require('../initializers/constants')
|
||||
const logger = require('../helpers/logger')
|
||||
|
@ -11,11 +9,6 @@ const oAuthServer = new OAuthServer({
|
|||
model: require('../lib/oauth-model')
|
||||
})
|
||||
|
||||
const oAuth = {
|
||||
authenticate,
|
||||
token
|
||||
}
|
||||
|
||||
function authenticate (req, res, next) {
|
||||
oAuthServer.authenticate()(req, res, function (err) {
|
||||
if (err) {
|
||||
|
@ -35,4 +28,7 @@ function token (req, res, next) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = oAuth
|
||||
export {
|
||||
authenticate,
|
||||
token
|
||||
}
|
|
@ -1,14 +1,9 @@
|
|||
'use strict'
|
||||
|
||||
const constants = require('../initializers/constants')
|
||||
|
||||
const paginationMiddleware = {
|
||||
setPagination
|
||||
}
|
||||
|
||||
function setPagination (req, res, next) {
|
||||
if (!req.query.start) req.query.start = 0
|
||||
else req.query.start = parseInt(req.query.start, 10)
|
||||
|
||||
if (!req.query.count) req.query.count = constants.PAGINATION_COUNT_DEFAULT
|
||||
else req.query.count = parseInt(req.query.count, 10)
|
||||
|
||||
|
@ -17,4 +12,6 @@ function setPagination (req, res, next) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = paginationMiddleware
|
||||
export {
|
||||
setPagination
|
||||
}
|
|
@ -2,11 +2,6 @@
|
|||
|
||||
const constants = require('../initializers/constants')
|
||||
|
||||
const podsMiddleware = {
|
||||
setBodyHostsPort,
|
||||
setBodyHostPort
|
||||
}
|
||||
|
||||
function setBodyHostsPort (req, res, next) {
|
||||
if (!req.body.hosts) return next()
|
||||
|
||||
|
@ -41,7 +36,10 @@ function setBodyHostPort (req, res, next) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = podsMiddleware
|
||||
export {
|
||||
setBodyHostsPort,
|
||||
setBodyHostPort
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -1,9 +1,3 @@
|
|||
'use strict'
|
||||
|
||||
const searchMiddleware = {
|
||||
setVideosSearch
|
||||
}
|
||||
|
||||
function setVideosSearch (req, res, next) {
|
||||
if (!req.query.field) req.query.field = 'name'
|
||||
|
||||
|
@ -12,4 +6,6 @@ function setVideosSearch (req, res, next) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = searchMiddleware
|
||||
export {
|
||||
setVideosSearch
|
||||
}
|
|
@ -1,13 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
const db = require('../initializers/database')
|
||||
const logger = require('../helpers/logger')
|
||||
const peertubeCrypto = require('../helpers/peertube-crypto')
|
||||
|
||||
const secureMiddleware = {
|
||||
checkSignature
|
||||
}
|
||||
|
||||
function checkSignature (req, res, next) {
|
||||
const host = req.body.signature.host
|
||||
db.Pod.loadByHost(host, function (err, pod) {
|
||||
|
@ -49,4 +43,6 @@ function checkSignature (req, res, next) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = secureMiddleware
|
||||
export {
|
||||
checkSignature
|
||||
}
|
|
@ -1,11 +1,3 @@
|
|||
'use strict'
|
||||
|
||||
const sortMiddleware = {
|
||||
setUsersSort,
|
||||
setVideoAbusesSort,
|
||||
setVideosSort
|
||||
}
|
||||
|
||||
function setUsersSort (req, res, next) {
|
||||
if (!req.query.sort) req.query.sort = '-createdAt'
|
||||
|
||||
|
@ -26,4 +18,8 @@ function setVideosSort (req, res, next) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = sortMiddleware
|
||||
export {
|
||||
setUsersSort,
|
||||
setVideoAbusesSort,
|
||||
setVideosSort
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const paginationValidators = require('./pagination')
|
||||
const podsValidators = require('./pods')
|
||||
const remoteValidators = require('./remote')
|
||||
const sortValidators = require('./sort')
|
||||
const usersValidators = require('./users')
|
||||
const videosValidators = require('./videos')
|
||||
|
||||
const validators = {
|
||||
pagination: paginationValidators,
|
||||
pods: podsValidators,
|
||||
remote: remoteValidators,
|
||||
sort: sortValidators,
|
||||
users: usersValidators,
|
||||
videos: videosValidators
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = validators
|
|
@ -0,0 +1,6 @@
|
|||
export * from './remote'
|
||||
export * from './pagination'
|
||||
export * from './pods'
|
||||
export * from './sort'
|
||||
export * from './users'
|
||||
export * from './videos'
|
|
@ -1,13 +1,7 @@
|
|||
'use strict'
|
||||
import { checkErrors } from './utils'
|
||||
import { logger } from '../../helpers'
|
||||
|
||||
const checkErrors = require('./utils').checkErrors
|
||||
const logger = require('../../helpers/logger')
|
||||
|
||||
const validatorsPagination = {
|
||||
pagination
|
||||
}
|
||||
|
||||
function pagination (req, res, next) {
|
||||
function paginationValidator (req, res, next) {
|
||||
req.checkQuery('start', 'Should have a number start').optional().isInt()
|
||||
req.checkQuery('count', 'Should have a number count').optional().isInt()
|
||||
|
||||
|
@ -18,4 +12,6 @@ function pagination (req, res, next) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = validatorsPagination
|
||||
export {
|
||||
paginationValidator
|
||||
}
|
|
@ -1,20 +1,13 @@
|
|||
'use strict'
|
||||
|
||||
const checkErrors = require('./utils').checkErrors
|
||||
const constants = require('../../initializers/constants')
|
||||
const db = require('../../initializers/database')
|
||||
const friends = require('../../lib/friends')
|
||||
const logger = require('../../helpers/logger')
|
||||
const utils = require('../../helpers/utils')
|
||||
import { checkErrors } from './utils'
|
||||
import { logger } from '../../helpers'
|
||||
import { CONFIG } from '../../initializers'
|
||||
import { hasFriends } from '../../lib'
|
||||
import { isTestInstance } from '../../helpers'
|
||||
|
||||
const validatorsPod = {
|
||||
makeFriends,
|
||||
podsAdd
|
||||
}
|
||||
|
||||
function makeFriends (req, res, next) {
|
||||
function makeFriendsValidator (req, res, next) {
|
||||
// Force https if the administrator wants to make friends
|
||||
if (utils.isTestInstance() === false && constants.CONFIG.WEBSERVER.SCHEME === 'http') {
|
||||
if (isTestInstance() === false && CONFIG.WEBSERVER.SCHEME === 'http') {
|
||||
return res.status(400).send('Cannot make friends with a non HTTPS webserver.')
|
||||
}
|
||||
|
||||
|
@ -23,13 +16,13 @@ function makeFriends (req, res, next) {
|
|||
logger.debug('Checking makeFriends parameters', { parameters: req.body })
|
||||
|
||||
checkErrors(req, res, function () {
|
||||
friends.hasFriends(function (err, hasFriends) {
|
||||
hasFriends(function (err, heHasFriends) {
|
||||
if (err) {
|
||||
logger.error('Cannot know if we have friends.', { error: err })
|
||||
res.sendStatus(500)
|
||||
}
|
||||
|
||||
if (hasFriends === true) {
|
||||
if (heHasFriends === true) {
|
||||
// We need to quit our friends before make new ones
|
||||
return res.sendStatus(409)
|
||||
}
|
||||
|
@ -39,7 +32,7 @@ function makeFriends (req, res, next) {
|
|||
})
|
||||
}
|
||||
|
||||
function podsAdd (req, res, next) {
|
||||
function podsAddValidator (req, res, next) {
|
||||
req.checkBody('host', 'Should have a host').isHostValid()
|
||||
req.checkBody('email', 'Should have an email').isEmail()
|
||||
req.checkBody('publicKey', 'Should have a public key').notEmpty()
|
||||
|
@ -64,4 +57,7 @@ function podsAdd (req, res, next) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = validatorsPod
|
||||
export {
|
||||
makeFriendsValidator,
|
||||
podsAddValidator
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
'use strict'
|
||||
|
||||
const remoteSignatureValidators = require('./signature')
|
||||
const remoteVideosValidators = require('./videos')
|
||||
|
||||
const validators = {
|
||||
signature: remoteSignatureValidators,
|
||||
videos: remoteVideosValidators
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = validators
|
|
@ -0,0 +1,2 @@
|
|||
export * from './signature'
|
||||
export * from './videos'
|
|
@ -1,13 +1,7 @@
|
|||
'use strict'
|
||||
import { logger } from '../../../helpers'
|
||||
import { checkErrors } from '../utils'
|
||||
|
||||
const checkErrors = require('../utils').checkErrors
|
||||
const logger = require('../../../helpers/logger')
|
||||
|
||||
const validatorsRemoteSignature = {
|
||||
signature
|
||||
}
|
||||
|
||||
function signature (req, res, next) {
|
||||
function signatureValidator (req, res, next) {
|
||||
req.checkBody('signature.host', 'Should have a signature host').isURL()
|
||||
req.checkBody('signature.signature', 'Should have a signature').notEmpty()
|
||||
|
||||
|
@ -18,4 +12,6 @@ function signature (req, res, next) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = validatorsRemoteSignature
|
||||
export {
|
||||
signatureValidator
|
||||
}
|
|
@ -1,15 +1,7 @@
|
|||
'use strict'
|
||||
import { logger } from '../../../helpers'
|
||||
import { checkErrors } from '../utils'
|
||||
|
||||
const checkErrors = require('../utils').checkErrors
|
||||
const logger = require('../../../helpers/logger')
|
||||
|
||||
const validatorsRemoteVideos = {
|
||||
remoteVideos,
|
||||
remoteQaduVideos,
|
||||
remoteEventsVideos
|
||||
}
|
||||
|
||||
function remoteVideos (req, res, next) {
|
||||
function remoteVideosValidator (req, res, next) {
|
||||
req.checkBody('data').isEachRemoteRequestVideosValid()
|
||||
|
||||
logger.debug('Checking remoteVideos parameters', { parameters: req.body })
|
||||
|
@ -17,7 +9,7 @@ function remoteVideos (req, res, next) {
|
|||
checkErrors(req, res, next)
|
||||
}
|
||||
|
||||
function remoteQaduVideos (req, res, next) {
|
||||
function remoteQaduVideosValidator (req, res, next) {
|
||||
req.checkBody('data').isEachRemoteRequestVideosQaduValid()
|
||||
|
||||
logger.debug('Checking remoteQaduVideos parameters', { parameters: req.body })
|
||||
|
@ -25,13 +17,18 @@ function remoteQaduVideos (req, res, next) {
|
|||
checkErrors(req, res, next)
|
||||
}
|
||||
|
||||
function remoteEventsVideos (req, res, next) {
|
||||
function remoteEventsVideosValidator (req, res, next) {
|
||||
req.checkBody('data').isEachRemoteRequestVideosEventsValid()
|
||||
|
||||
logger.debug('Checking remoteEventsVideos parameters', { parameters: req.body })
|
||||
|
||||
checkErrors(req, res, next)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = validatorsRemoteVideos
|
||||
export {
|
||||
remoteVideosValidator,
|
||||
remoteQaduVideosValidator,
|
||||
remoteEventsVideosValidator
|
||||
}
|
|
@ -1,35 +1,31 @@
|
|||
'use strict'
|
||||
|
||||
const checkErrors = require('./utils').checkErrors
|
||||
const constants = require('../../initializers/constants')
|
||||
const logger = require('../../helpers/logger')
|
||||
|
||||
const validatorsSort = {
|
||||
usersSort,
|
||||
videoAbusesSort,
|
||||
videosSort
|
||||
}
|
||||
import { checkErrors } from './utils'
|
||||
import { logger } from '../../helpers'
|
||||
import { SORTABLE_COLUMNS } from '../../initializers'
|
||||
|
||||
// Initialize constants here for better performances
|
||||
const SORTABLE_USERS_COLUMNS = createSortableColumns(constants.SORTABLE_COLUMNS.USERS)
|
||||
const SORTABLE_VIDEO_ABUSES_COLUMNS = createSortableColumns(constants.SORTABLE_COLUMNS.VIDEO_ABUSES)
|
||||
const SORTABLE_VIDEOS_COLUMNS = createSortableColumns(constants.SORTABLE_COLUMNS.VIDEOS)
|
||||
const SORTABLE_USERS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.USERS)
|
||||
const SORTABLE_VIDEO_ABUSES_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEO_ABUSES)
|
||||
const SORTABLE_VIDEOS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.VIDEOS)
|
||||
|
||||
function usersSort (req, res, next) {
|
||||
function usersSortValidator (req, res, next) {
|
||||
checkSort(req, res, next, SORTABLE_USERS_COLUMNS)
|
||||
}
|
||||
|
||||
function videoAbusesSort (req, res, next) {
|
||||
function videoAbusesSortValidator (req, res, next) {
|
||||
checkSort(req, res, next, SORTABLE_VIDEO_ABUSES_COLUMNS)
|
||||
}
|
||||
|
||||
function videosSort (req, res, next) {
|
||||
function videosSortValidator (req, res, next) {
|
||||
checkSort(req, res, next, SORTABLE_VIDEOS_COLUMNS)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = validatorsSort
|
||||
export {
|
||||
usersSortValidator,
|
||||
videoAbusesSortValidator,
|
||||
videosSortValidator
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -1,17 +1,8 @@
|
|||
'use strict'
|
||||
|
||||
const checkErrors = require('./utils').checkErrors
|
||||
const db = require('../../initializers/database')
|
||||
const logger = require('../../helpers/logger')
|
||||
import { checkErrors } from './utils'
|
||||
import { logger } from '../../helpers'
|
||||
|
||||
const validatorsUsers = {
|
||||
usersAdd,
|
||||
usersRemove,
|
||||
usersUpdate,
|
||||
usersVideoRating
|
||||
}
|
||||
|
||||
function usersAdd (req, res, next) {
|
||||
function usersAddValidator (req, res, next) {
|
||||
req.checkBody('username', 'Should have a valid username').isUserUsernameValid()
|
||||
req.checkBody('password', 'Should have a valid password').isUserPasswordValid()
|
||||
req.checkBody('email', 'Should have a valid email').isEmail()
|
||||
|
@ -32,7 +23,7 @@ function usersAdd (req, res, next) {
|
|||
})
|
||||
}
|
||||
|
||||
function usersRemove (req, res, next) {
|
||||
function usersRemoveValidator (req, res, next) {
|
||||
req.checkParams('id', 'Should have a valid id').notEmpty().isInt()
|
||||
|
||||
logger.debug('Checking usersRemove parameters', { parameters: req.params })
|
||||
|
@ -53,7 +44,7 @@ function usersRemove (req, res, next) {
|
|||
})
|
||||
}
|
||||
|
||||
function usersUpdate (req, res, next) {
|
||||
function usersUpdateValidator (req, res, next) {
|
||||
req.checkParams('id', 'Should have a valid id').notEmpty().isInt()
|
||||
// Add old password verification
|
||||
req.checkBody('password', 'Should have a valid password').optional().isUserPasswordValid()
|
||||
|
@ -64,7 +55,7 @@ function usersUpdate (req, res, next) {
|
|||
checkErrors(req, res, next)
|
||||
}
|
||||
|
||||
function usersVideoRating (req, res, next) {
|
||||
function usersVideoRatingValidator (req, res, next) {
|
||||
req.checkParams('videoId', 'Should have a valid video id').notEmpty().isUUID(4)
|
||||
|
||||
logger.debug('Checking usersVideoRating parameters', { parameters: req.params })
|
||||
|
@ -85,4 +76,9 @@ function usersVideoRating (req, res, next) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = validatorsUsers
|
||||
export {
|
||||
usersAddValidator,
|
||||
usersRemoveValidator,
|
||||
usersUpdateValidator,
|
||||
usersVideoRatingValidator
|
||||
}
|
|
@ -1,20 +1,14 @@
|
|||
'use strict'
|
||||
import { inspect } from 'util'
|
||||
|
||||
const util = require('util')
|
||||
import { logger } from '../../helpers'
|
||||
|
||||
const logger = require('../../helpers/logger')
|
||||
|
||||
const validatorsUtils = {
|
||||
checkErrors
|
||||
}
|
||||
|
||||
function checkErrors (req, res, next, statusCode) {
|
||||
function checkErrors (req, res, next, statusCode?) {
|
||||
if (statusCode === undefined) statusCode = 400
|
||||
const errors = req.validationErrors()
|
||||
|
||||
if (errors) {
|
||||
logger.warn('Incorrect request parameters', { path: req.originalUrl, err: errors })
|
||||
return res.status(statusCode).send('There have been validation errors: ' + util.inspect(errors))
|
||||
return res.status(statusCode).send('There have been validation errors: ' + inspect(errors))
|
||||
}
|
||||
|
||||
return next()
|
||||
|
@ -22,4 +16,6 @@ function checkErrors (req, res, next, statusCode) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = validatorsUtils
|
||||
export {
|
||||
checkErrors
|
||||
}
|
|
@ -1,26 +1,9 @@
|
|||
'use strict'
|
||||
|
||||
const checkErrors = require('./utils').checkErrors
|
||||
const constants = require('../../initializers/constants')
|
||||
const customVideosValidators = require('../../helpers/custom-validators').videos
|
||||
const db = require('../../initializers/database')
|
||||
const logger = require('../../helpers/logger')
|
||||
import { checkErrors } from './utils'
|
||||
import { CONSTRAINTS_FIELDS, SEARCHABLE_COLUMNS } from '../../initializers'
|
||||
import { logger, isVideoDurationValid } from '../../helpers'
|
||||
|
||||
const validatorsVideos = {
|
||||
videosAdd,
|
||||
videosUpdate,
|
||||
videosGet,
|
||||
videosRemove,
|
||||
videosSearch,
|
||||
|
||||
videoAbuseReport,
|
||||
|
||||
videoRate,
|
||||
|
||||
videosBlacklist
|
||||
}
|
||||
|
||||
function videosAdd (req, res, next) {
|
||||
function videosAddValidator (req, res, next) {
|
||||
req.checkBody('videofile', 'Should have a valid file').isVideoFile(req.files)
|
||||
req.checkBody('name', 'Should have a valid name').isVideoNameValid()
|
||||
req.checkBody('category', 'Should have a valid category').isVideoCategoryValid()
|
||||
|
@ -40,8 +23,8 @@ function videosAdd (req, res, next) {
|
|||
return res.status(400).send('Cannot retrieve metadata of the file.')
|
||||
}
|
||||
|
||||
if (!customVideosValidators.isVideoDurationValid(duration)) {
|
||||
return res.status(400).send('Duration of the video file is too big (max: ' + constants.CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).')
|
||||
if (!isVideoDurationValid(duration)) {
|
||||
return res.status(400).send('Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).')
|
||||
}
|
||||
|
||||
videoFile.duration = duration
|
||||
|
@ -50,7 +33,7 @@ function videosAdd (req, res, next) {
|
|||
})
|
||||
}
|
||||
|
||||
function videosUpdate (req, res, next) {
|
||||
function videosUpdateValidator (req, res, next) {
|
||||
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
|
||||
req.checkBody('name', 'Should have a valid name').optional().isVideoNameValid()
|
||||
req.checkBody('category', 'Should have a valid category').optional().isVideoCategoryValid()
|
||||
|
@ -78,7 +61,7 @@ function videosUpdate (req, res, next) {
|
|||
})
|
||||
}
|
||||
|
||||
function videosGet (req, res, next) {
|
||||
function videosGetValidator (req, res, next) {
|
||||
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
|
||||
|
||||
logger.debug('Checking videosGet parameters', { parameters: req.params })
|
||||
|
@ -88,7 +71,7 @@ function videosGet (req, res, next) {
|
|||
})
|
||||
}
|
||||
|
||||
function videosRemove (req, res, next) {
|
||||
function videosRemoveValidator (req, res, next) {
|
||||
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
|
||||
|
||||
logger.debug('Checking videosRemove parameters', { parameters: req.params })
|
||||
|
@ -105,8 +88,8 @@ function videosRemove (req, res, next) {
|
|||
})
|
||||
}
|
||||
|
||||
function videosSearch (req, res, next) {
|
||||
const searchableColumns = constants.SEARCHABLE_COLUMNS.VIDEOS
|
||||
function videosSearchValidator (req, res, next) {
|
||||
const searchableColumns = SEARCHABLE_COLUMNS.VIDEOS
|
||||
req.checkParams('value', 'Should have a valid search').notEmpty()
|
||||
req.checkQuery('field', 'Should have correct searchable column').optional().isIn(searchableColumns)
|
||||
|
||||
|
@ -115,7 +98,7 @@ function videosSearch (req, res, next) {
|
|||
checkErrors(req, res, next)
|
||||
}
|
||||
|
||||
function videoAbuseReport (req, res, next) {
|
||||
function videoAbuseReportValidator (req, res, next) {
|
||||
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
|
||||
req.checkBody('reason', 'Should have a valid reason').isVideoAbuseReasonValid()
|
||||
|
||||
|
@ -126,7 +109,7 @@ function videoAbuseReport (req, res, next) {
|
|||
})
|
||||
}
|
||||
|
||||
function videoRate (req, res, next) {
|
||||
function videoRateValidator (req, res, next) {
|
||||
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
|
||||
req.checkBody('rating', 'Should have a valid rate type').isVideoRatingTypeValid()
|
||||
|
||||
|
@ -137,7 +120,7 @@ function videoRate (req, res, next) {
|
|||
})
|
||||
}
|
||||
|
||||
function videosBlacklist (req, res, next) {
|
||||
function videosBlacklistValidator (req, res, next) {
|
||||
req.checkParams('id', 'Should have a valid id').notEmpty().isUUID(4)
|
||||
|
||||
logger.debug('Checking videosBlacklist parameters', { parameters: req.params })
|
||||
|
@ -151,7 +134,19 @@ function videosBlacklist (req, res, next) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = validatorsVideos
|
||||
export {
|
||||
videosAddValidator,
|
||||
videosUpdateValidator,
|
||||
videosGetValidator,
|
||||
videosRemoveValidator,
|
||||
videosSearchValidator,
|
||||
|
||||
videoAbuseReportValidator,
|
||||
|
||||
videoRateValidator,
|
||||
|
||||
videosBlacklistValidator
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
'use strict'
|
||||
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
const Application = sequelize.define('Application',
|
||||
{
|
||||
|
@ -38,7 +36,7 @@ function loadMigrationVersion (callback) {
|
|||
}
|
||||
|
||||
function updateMigrationVersion (newVersion, transaction, callback) {
|
||||
const options = {
|
||||
const options: { where?: any, transaction?: any } = {
|
||||
where: {}
|
||||
}
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
'use strict'
|
||||
|
||||
const customUsersValidators = require('../helpers/custom-validators').users
|
||||
import { isUserUsernameValid } from '../helpers'
|
||||
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
const Author = sequelize.define('Author',
|
||||
|
@ -10,7 +8,7 @@ module.exports = function (sequelize, DataTypes) {
|
|||
allowNull: false,
|
||||
validate: {
|
||||
usernameValid: function (value) {
|
||||
const res = customUsersValidators.isUserUsernameValid(value)
|
||||
const res = isUserUsernameValid(value)
|
||||
if (res === false) throw new Error('Username is not valid.')
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +74,7 @@ function findOrCreateAuthor (name, podId, userId, transaction, callback) {
|
|||
userId
|
||||
}
|
||||
|
||||
const query = {
|
||||
const query: any = {
|
||||
where: author,
|
||||
defaults: author
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
'use strict'
|
||||
import { values } from 'lodash'
|
||||
|
||||
const values = require('lodash/values')
|
||||
|
||||
const constants = require('../initializers/constants')
|
||||
import { JOB_STATES } from '../initializers'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
@ -10,7 +8,7 @@ module.exports = function (sequelize, DataTypes) {
|
|||
const Job = sequelize.define('Job',
|
||||
{
|
||||
state: {
|
||||
type: DataTypes.ENUM(values(constants.JOB_STATES)),
|
||||
type: DataTypes.ENUM(values(JOB_STATES)),
|
||||
allowNull: false
|
||||
},
|
||||
handlerName: {
|
|
@ -1,5 +1,3 @@
|
|||
'use strict'
|
||||
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
const OAuthClient = sequelize.define('OAuthClient',
|
||||
{
|
|
@ -1,6 +1,4 @@
|
|||
'use strict'
|
||||
|
||||
const logger = require('../helpers/logger')
|
||||
import { logger } from '../helpers'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -1,12 +1,8 @@
|
|||
'use strict'
|
||||
import { each, waterfall } from 'async'
|
||||
import { map } from 'lodash'
|
||||
|
||||
const each = require('async/each')
|
||||
const map = require('lodash/map')
|
||||
const waterfall = require('async/waterfall')
|
||||
|
||||
const constants = require('../initializers/constants')
|
||||
const logger = require('../helpers/logger')
|
||||
const customPodsValidators = require('../helpers/custom-validators').pods
|
||||
import { FRIEND_SCORE, PODS_SCORE } from '../initializers'
|
||||
import { logger, isHostValid } from '../helpers'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
@ -18,7 +14,7 @@ module.exports = function (sequelize, DataTypes) {
|
|||
allowNull: false,
|
||||
validate: {
|
||||
isHost: function (value) {
|
||||
const res = customPodsValidators.isHostValid(value)
|
||||
const res = isHostValid(value)
|
||||
if (res === false) throw new Error('Host not valid.')
|
||||
}
|
||||
}
|
||||
|
@ -29,11 +25,11 @@ module.exports = function (sequelize, DataTypes) {
|
|||
},
|
||||
score: {
|
||||
type: DataTypes.INTEGER,
|
||||
defaultValue: constants.FRIEND_SCORE.BASE,
|
||||
defaultValue: FRIEND_SCORE.BASE,
|
||||
allowNull: false,
|
||||
validate: {
|
||||
isInt: true,
|
||||
max: constants.FRIEND_SCORE.MAX
|
||||
max: FRIEND_SCORE.MAX
|
||||
}
|
||||
},
|
||||
email: {
|
||||
|
@ -106,7 +102,7 @@ function countAll (callback) {
|
|||
}
|
||||
|
||||
function incrementScores (ids, value, callback) {
|
||||
if (!callback) callback = function () {}
|
||||
if (!callback) callback = function () { /* empty */ }
|
||||
|
||||
const update = {
|
||||
score: this.sequelize.literal('score +' + value)
|
||||
|
@ -135,7 +131,7 @@ function listAllIds (transaction, callback) {
|
|||
transaction = null
|
||||
}
|
||||
|
||||
const query = {
|
||||
const query: any = {
|
||||
attributes: [ 'id' ]
|
||||
}
|
||||
|
||||
|
@ -223,13 +219,13 @@ function updatePodsScore (goodPods, badPods) {
|
|||
logger.info('Updating %d good pods and %d bad pods scores.', goodPods.length, badPods.length)
|
||||
|
||||
if (goodPods.length !== 0) {
|
||||
this.incrementScores(goodPods, constants.PODS_SCORE.BONUS, function (err) {
|
||||
this.incrementScores(goodPods, PODS_SCORE.BONUS, function (err) {
|
||||
if (err) logger.error('Cannot increment scores of good pods.', { error: err })
|
||||
})
|
||||
}
|
||||
|
||||
if (badPods.length !== 0) {
|
||||
this.incrementScores(badPods, constants.PODS_SCORE.MALUS, function (err) {
|
||||
this.incrementScores(badPods, PODS_SCORE.MALUS, function (err) {
|
||||
if (err) logger.error('Cannot decrement scores of bad pods.', { error: err })
|
||||
removeBadPods.call(self)
|
||||
})
|
||||
|
@ -255,7 +251,7 @@ function removeBadPods () {
|
|||
},
|
||||
|
||||
function removeTheseBadPods (pods, callback) {
|
||||
each(pods, function (pod, callbackEach) {
|
||||
each(pods, function (pod: any, callbackEach) {
|
||||
pod.destroy().asCallback(callbackEach)
|
||||
}, function (err) {
|
||||
return callback(err, pods.length)
|
|
@ -1,7 +1,3 @@
|
|||
'use strict'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
const RequestToPod = sequelize.define('RequestToPod', {}, {
|
||||
indexes: [
|
||||
|
@ -27,7 +23,7 @@ module.exports = function (sequelize, DataTypes) {
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
function removeByRequestIdsAndPod (requestsIds, podId, callback) {
|
||||
if (!callback) callback = function () {}
|
||||
if (!callback) callback = function () { /* empty */ }
|
||||
|
||||
const query = {
|
||||
where: {
|
|
@ -1,13 +1,11 @@
|
|||
'use strict'
|
||||
|
||||
/*
|
||||
Request Video events (likes, dislikes, views...)
|
||||
*/
|
||||
|
||||
const values = require('lodash/values')
|
||||
import { values } from 'lodash'
|
||||
|
||||
const constants = require('../initializers/constants')
|
||||
const customVideosValidators = require('../helpers/custom-validators').videos
|
||||
import { REQUEST_VIDEO_EVENT_TYPES } from '../initializers'
|
||||
import { isVideoEventCountValid } from '../helpers'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
@ -15,7 +13,7 @@ module.exports = function (sequelize, DataTypes) {
|
|||
const RequestVideoEvent = sequelize.define('RequestVideoEvent',
|
||||
{
|
||||
type: {
|
||||
type: DataTypes.ENUM(values(constants.REQUEST_VIDEO_EVENT_TYPES)),
|
||||
type: DataTypes.ENUM(values(REQUEST_VIDEO_EVENT_TYPES)),
|
||||
allowNull: false
|
||||
},
|
||||
count: {
|
||||
|
@ -23,7 +21,7 @@ module.exports = function (sequelize, DataTypes) {
|
|||
allowNull: false,
|
||||
validate: {
|
||||
countValid: function (value) {
|
||||
const res = customVideosValidators.isVideoEventCountValid(value)
|
||||
const res = isVideoEventCountValid(value)
|
||||
if (res === false) throw new Error('Video event count is not valid.')
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue