aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/initializers
diff options
context:
space:
mode:
Diffstat (limited to 'server/initializers')
-rw-r--r--server/initializers/checker.js14
-rw-r--r--server/initializers/constants.js175
-rw-r--r--server/initializers/database.js11
-rw-r--r--server/initializers/installer.js22
-rw-r--r--server/initializers/migrations/0005-create-application.js17
-rw-r--r--server/initializers/migrations/0010-users-password.js22
-rw-r--r--server/initializers/migrations/0015-admin-role.js16
-rw-r--r--server/initializers/migrator.js56
8 files changed, 262 insertions, 71 deletions
diff --git a/server/initializers/checker.js b/server/initializers/checker.js
index 3831efb8d..91fbcfaf9 100644
--- a/server/initializers/checker.js
+++ b/server/initializers/checker.js
@@ -7,9 +7,9 @@ const Client = mongoose.model('OAuthClient')
7const User = mongoose.model('User') 7const User = mongoose.model('User')
8 8
9const checker = { 9const checker = {
10 checkConfig: checkConfig, 10 checkConfig,
11 clientsExist: clientsExist, 11 clientsExist,
12 usersExist: usersExist 12 usersExist
13} 13}
14 14
15// Check the config files 15// Check the config files
@@ -17,8 +17,8 @@ function checkConfig () {
17 const required = [ 'listen.port', 17 const required = [ 'listen.port',
18 'webserver.https', 'webserver.host', 'webserver.port', 18 'webserver.https', 'webserver.host', 'webserver.port',
19 'database.host', 'database.port', 'database.suffix', 19 'database.host', 'database.port', 'database.suffix',
20 'storage.certs', 'storage.uploads', 'storage.logs', 20 'storage.certs', 'storage.uploads', 'storage.logs', 'storage.thumbnails',
21 'network.friends', 'electron.debug' ] 21 'electron.debug' ]
22 const miss = [] 22 const miss = []
23 23
24 for (const key of required) { 24 for (const key of required) {
@@ -39,10 +39,10 @@ function clientsExist (callback) {
39} 39}
40 40
41function usersExist (callback) { 41function usersExist (callback) {
42 User.list(function (err, users) { 42 User.countTotal(function (err, totalUsers) {
43 if (err) return callback(err) 43 if (err) return callback(err)
44 44
45 return callback(null, users.length !== 0) 45 return callback(null, totalUsers !== 0)
46 }) 46 })
47} 47}
48 48
diff --git a/server/initializers/constants.js b/server/initializers/constants.js
index e0ea188af..be2e3e943 100644
--- a/server/initializers/constants.js
+++ b/server/initializers/constants.js
@@ -1,24 +1,103 @@
1'use strict' 1'use strict'
2 2
3// API version of our pod 3const config = require('config')
4const path = require('path')
5
6// ---------------------------------------------------------------------------
7
8// API version
4const API_VERSION = 'v1' 9const API_VERSION = 'v1'
5 10
6// Score a pod has when we create it as a friend 11// Number of results by default for the pagination
7const FRIEND_SCORE = { 12const PAGINATION_COUNT_DEFAULT = 15
8 BASE: 100, 13
9 MAX: 1000 14// Sortable columns per schema
15const SEARCHABLE_COLUMNS = {
16 VIDEOS: [ 'name', 'magnetUri', 'podUrl', 'author', 'tags' ]
10} 17}
11 18
12// Time to wait between requests to the friends (10 min) 19// Sortable columns per schema
13let INTERVAL = 600000 20const SORTABLE_COLUMNS = {
21 USERS: [ 'username', '-username', 'createdDate', '-createdDate' ],
22 VIDEOS: [ 'name', '-name', 'duration', '-duration', 'createdDate', '-createdDate' ]
23}
14 24
15const OAUTH_LIFETIME = { 25const OAUTH_LIFETIME = {
16 ACCESS_TOKEN: 3600 * 4, // 4 hours 26 ACCESS_TOKEN: 3600 * 4, // 4 hours
17 REFRESH_TOKEN: 1209600 // 2 weeks 27 REFRESH_TOKEN: 1209600 // 2 weeks
18} 28}
19 29
20// Number of results by default for the pagination 30// ---------------------------------------------------------------------------
21const PAGINATION_COUNT_DEFAULT = 15 31
32const CONFIG = {
33 DATABASE: {
34 DBNAME: 'peertube' + config.get('database.suffix'),
35 HOST: config.get('database.host'),
36 PORT: config.get('database.port')
37 },
38 ELECTRON: {
39 DEBUG: config.get('electron.debug')
40 },
41 STORAGE: {
42 CERT_DIR: path.join(__dirname, '..', '..', config.get('storage.certs')),
43 LOG_DIR: path.join(__dirname, '..', '..', config.get('storage.logs')),
44 UPLOAD_DIR: path.join(__dirname, '..', '..', config.get('storage.uploads')),
45 THUMBNAILS_DIR: path.join(__dirname, '..', '..', config.get('storage.thumbnails'))
46 },
47 WEBSERVER: {
48 SCHEME: config.get('webserver.https') === true ? 'https' : 'http',
49 HOST: config.get('webserver.host'),
50 PORT: config.get('webserver.port')
51 }
52}
53CONFIG.WEBSERVER.URL = CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOST + ':' + CONFIG.WEBSERVER.PORT
54
55// ---------------------------------------------------------------------------
56
57const CONSTRAINTS_FIELDS = {
58 USERS: {
59 USERNAME: { min: 3, max: 20 }, // Length
60 PASSWORD: { min: 6, max: 255 } // Length
61 },
62 VIDEOS: {
63 NAME: { min: 3, max: 50 }, // Length
64 DESCRIPTION: { min: 3, max: 250 }, // Length
65 MAGNET_URI: { min: 10 }, // Length
66 DURATION: { min: 1, max: 7200 }, // Number
67 TAGS: { min: 1, max: 3 }, // Number of total tags
68 TAG: { min: 2, max: 10 }, // Length
69 THUMBNAIL: { min: 2, max: 30 },
70 THUMBNAIL64: { min: 0, max: 20000 } // Bytes
71 }
72}
73
74// ---------------------------------------------------------------------------
75
76// Score a pod has when we create it as a friend
77const FRIEND_SCORE = {
78 BASE: 100,
79 MAX: 1000
80}
81
82// ---------------------------------------------------------------------------
83
84const MONGO_MIGRATION_SCRIPTS = [
85 {
86 script: '0005-create-application',
87 version: 5
88 },
89 {
90 script: '0010-users-password',
91 version: 10
92 },
93 {
94 script: '0015-admin-role',
95 version: 15
96 }
97]
98const LAST_MONGO_SCHEMA_VERSION = 15
99
100// ---------------------------------------------------------------------------
22 101
23// Number of points we add/remove from a friend after a successful/bad request 102// Number of points we add/remove from a friend after a successful/bad request
24const PODS_SCORE = { 103const PODS_SCORE = {
@@ -26,28 +105,22 @@ const PODS_SCORE = {
26 BONUS: 10 105 BONUS: 10
27} 106}
28 107
108// Time to wait between requests to the friends (10 min)
109let REQUESTS_INTERVAL = 600000
110
29// Number of requests in parallel we can make 111// Number of requests in parallel we can make
30const REQUESTS_IN_PARALLEL = 10 112const REQUESTS_IN_PARALLEL = 10
31 113
32// How many requests we put in request (request scheduler) 114// How many requests we put in request
33const REQUESTS_LIMIT = 10 115const REQUESTS_LIMIT = 10
34 116
35// Number of requests to retry for replay requests module 117// Number of requests to retry for replay requests module
36const RETRY_REQUESTS = 5 118const RETRY_REQUESTS = 5
37 119
38// Sortable columns per schema 120// ---------------------------------------------------------------------------
39const SEARCHABLE_COLUMNS = {
40 VIDEOS: [ 'name', 'magnetUri', 'podUrl', 'author', 'tags' ]
41}
42
43// Seeds in parallel we send to electron when "seed all"
44// Once a video is in seeding state we seed another video etc
45const SEEDS_IN_PARALLEL = 3
46 121
47// Sortable columns per schema 122// Password encryption
48const SORTABLE_COLUMNS = { 123const BCRYPT_SALT_SIZE = 10
49 VIDEOS: [ 'name', '-name', 'duration', '-duration', 'createdDate', '-createdDate' ]
50}
51 124
52// Express static paths (router) 125// Express static paths (router)
53const STATIC_PATHS = { 126const STATIC_PATHS = {
@@ -59,43 +132,47 @@ const STATIC_PATHS = {
59// Videos thumbnail size 132// Videos thumbnail size
60const THUMBNAILS_SIZE = '200x110' 133const THUMBNAILS_SIZE = '200x110'
61 134
62const VIDEOS_CONSTRAINTS_FIELDS = { 135const USER_ROLES = {
63 NAME: { min: 3, max: 50 }, // Length 136 ADMIN: 'admin',
64 DESCRIPTION: { min: 3, max: 250 }, // Length 137 USER: 'user'
65 MAGNET_URI: { min: 10 }, // Length
66 DURATION: { min: 1, max: 7200 }, // Number
67 AUTHOR: { min: 3, max: 20 }, // Length
68 TAGS: { min: 1, max: 3 }, // Number of total tags
69 TAG: { min: 2, max: 10 }, // Length
70 THUMBNAIL: { min: 2, max: 30 },
71 THUMBNAIL64: { min: 0, max: 20000 } // Bytes
72} 138}
73 139
140// Seeds in parallel we send to electron when "seed all"
141// Once a video is in seeding state we seed another video etc
142const SEEDS_IN_PARALLEL = 3
143
144// ---------------------------------------------------------------------------
145
74// Special constants for a test instance 146// Special constants for a test instance
75if (isTestInstance() === true) { 147if (isTestInstance() === true) {
148 CONSTRAINTS_FIELDS.VIDEOS.DURATION.max = 14
76 FRIEND_SCORE.BASE = 20 149 FRIEND_SCORE.BASE = 20
77 INTERVAL = 10000 150 REQUESTS_INTERVAL = 10000
78 VIDEOS_CONSTRAINTS_FIELDS.DURATION.max = 14
79} 151}
80 152
81// --------------------------------------------------------------------------- 153// ---------------------------------------------------------------------------
82 154
83module.exports = { 155module.exports = {
84 API_VERSION: API_VERSION, 156 API_VERSION,
85 FRIEND_SCORE: FRIEND_SCORE, 157 BCRYPT_SALT_SIZE,
86 INTERVAL: INTERVAL, 158 CONFIG,
87 OAUTH_LIFETIME: OAUTH_LIFETIME, 159 CONSTRAINTS_FIELDS,
88 PAGINATION_COUNT_DEFAULT: PAGINATION_COUNT_DEFAULT, 160 FRIEND_SCORE,
89 PODS_SCORE: PODS_SCORE, 161 LAST_MONGO_SCHEMA_VERSION,
90 REQUESTS_IN_PARALLEL: REQUESTS_IN_PARALLEL, 162 MONGO_MIGRATION_SCRIPTS,
91 REQUESTS_LIMIT: REQUESTS_LIMIT, 163 OAUTH_LIFETIME,
92 RETRY_REQUESTS: RETRY_REQUESTS, 164 PAGINATION_COUNT_DEFAULT,
93 SEARCHABLE_COLUMNS: SEARCHABLE_COLUMNS, 165 PODS_SCORE,
94 SEEDS_IN_PARALLEL: SEEDS_IN_PARALLEL, 166 REQUESTS_IN_PARALLEL,
95 SORTABLE_COLUMNS: SORTABLE_COLUMNS, 167 REQUESTS_INTERVAL,
96 STATIC_PATHS: STATIC_PATHS, 168 REQUESTS_LIMIT,
97 THUMBNAILS_SIZE: THUMBNAILS_SIZE, 169 RETRY_REQUESTS,
98 VIDEOS_CONSTRAINTS_FIELDS: VIDEOS_CONSTRAINTS_FIELDS 170 SEARCHABLE_COLUMNS,
171 SEEDS_IN_PARALLEL,
172 SORTABLE_COLUMNS,
173 STATIC_PATHS,
174 THUMBNAILS_SIZE,
175 USER_ROLES
99} 176}
100 177
101// --------------------------------------------------------------------------- 178// ---------------------------------------------------------------------------
diff --git a/server/initializers/database.js b/server/initializers/database.js
index 8626895ee..45c8a240d 100644
--- a/server/initializers/database.js
+++ b/server/initializers/database.js
@@ -1,30 +1,27 @@
1'use strict' 1'use strict'
2 2
3const config = require('config')
4const mongoose = require('mongoose') 3const mongoose = require('mongoose')
5 4
5const constants = require('../initializers/constants')
6const logger = require('../helpers/logger') 6const logger = require('../helpers/logger')
7 7
8// Bootstrap models 8// Bootstrap models
9require('../models/application')
10require('../models/oauth-token')
9require('../models/user') 11require('../models/user')
10require('../models/oauth-client') 12require('../models/oauth-client')
11require('../models/oauth-token')
12require('../models/pods') 13require('../models/pods')
13require('../models/video') 14require('../models/video')
14// Request model needs Video model 15// Request model needs Video model
15require('../models/request') 16require('../models/request')
16 17
17const dbname = 'peertube' + config.get('database.suffix')
18const host = config.get('database.host')
19const port = config.get('database.port')
20
21const database = { 18const database = {
22 connect: connect 19 connect: connect
23} 20}
24 21
25function connect () { 22function connect () {
26 mongoose.Promise = global.Promise 23 mongoose.Promise = global.Promise
27 mongoose.connect('mongodb://' + host + ':' + port + '/' + dbname) 24 mongoose.connect('mongodb://' + constants.CONFIG.DATABASE.HOST + ':' + constants.CONFIG.DATABASE.PORT + '/' + constants.CONFIG.DATABASE.DBNAME)
28 mongoose.connection.on('error', function () { 25 mongoose.connection.on('error', function () {
29 throw new Error('Mongodb connection error.') 26 throw new Error('Mongodb connection error.')
30 }) 27 })
diff --git a/server/initializers/installer.js b/server/initializers/installer.js
index 32830d4da..1df300ba8 100644
--- a/server/initializers/installer.js
+++ b/server/initializers/installer.js
@@ -9,14 +9,16 @@ const path = require('path')
9const series = require('async/series') 9const series = require('async/series')
10 10
11const checker = require('./checker') 11const checker = require('./checker')
12const constants = require('./constants')
12const logger = require('../helpers/logger') 13const logger = require('../helpers/logger')
13const peertubeCrypto = require('../helpers/peertube-crypto') 14const peertubeCrypto = require('../helpers/peertube-crypto')
14 15
16const Application = mongoose.model('Application')
15const Client = mongoose.model('OAuthClient') 17const Client = mongoose.model('OAuthClient')
16const User = mongoose.model('User') 18const User = mongoose.model('User')
17 19
18const installer = { 20const installer = {
19 installApplication: installApplication 21 installApplication
20} 22}
21 23
22function installApplication (callback) { 24function installApplication (callback) {
@@ -34,7 +36,7 @@ function installApplication (callback) {
34 }, 36 },
35 37
36 function createOAuthUser (callbackAsync) { 38 function createOAuthUser (callbackAsync) {
37 createOAuthUserIfNotExist(callbackAsync) 39 createOAuthAdminIfNotExist(callbackAsync)
38 } 40 }
39 ], callback) 41 ], callback)
40} 42}
@@ -80,7 +82,7 @@ function createOAuthClientIfNotExist (callback) {
80 }) 82 })
81} 83}
82 84
83function createOAuthUserIfNotExist (callback) { 85function createOAuthAdminIfNotExist (callback) {
84 checker.usersExist(function (err, exist) { 86 checker.usersExist(function (err, exist) {
85 if (err) return callback(err) 87 if (err) return callback(err)
86 88
@@ -90,6 +92,7 @@ function createOAuthUserIfNotExist (callback) {
90 logger.info('Creating the administrator.') 92 logger.info('Creating the administrator.')
91 93
92 const username = 'root' 94 const username = 'root'
95 const role = constants.USER_ROLES.ADMIN
93 let password = '' 96 let password = ''
94 97
95 // Do not generate a random password for tests 98 // Do not generate a random password for tests
@@ -104,17 +107,20 @@ function createOAuthUserIfNotExist (callback) {
104 } 107 }
105 108
106 const user = new User({ 109 const user = new User({
107 username: username, 110 username,
108 password: password 111 password,
112 role
109 }) 113 })
110 114
111 user.save(function (err, createdUser) { 115 user.save(function (err, createdUser) {
112 if (err) return callback(err) 116 if (err) return callback(err)
113 117
114 logger.info('Username: ' + createdUser.username) 118 logger.info('Username: ' + username)
115 logger.info('User password: ' + createdUser.password) 119 logger.info('User password: ' + password)
116 120
117 return callback(null) 121 logger.info('Creating Application collection.')
122 const application = new Application({ mongoSchemaVersion: constants.LAST_MONGO_SCHEMA_VERSION })
123 application.save(callback)
118 }) 124 })
119 }) 125 })
120} 126}
diff --git a/server/initializers/migrations/0005-create-application.js b/server/initializers/migrations/0005-create-application.js
new file mode 100644
index 000000000..e99dec019
--- /dev/null
+++ b/server/initializers/migrations/0005-create-application.js
@@ -0,0 +1,17 @@
1/*
2 Create the application collection in MongoDB.
3 Used to store the actual MongoDB scheme version.
4*/
5
6const mongoose = require('mongoose')
7
8const Application = mongoose.model('Application')
9
10exports.up = function (callback) {
11 const application = new Application()
12 application.save(callback)
13}
14
15exports.down = function (callback) {
16 throw new Error('Not implemented.')
17}
diff --git a/server/initializers/migrations/0010-users-password.js b/server/initializers/migrations/0010-users-password.js
new file mode 100644
index 000000000..a0616a269
--- /dev/null
+++ b/server/initializers/migrations/0010-users-password.js
@@ -0,0 +1,22 @@
1/*
2 Convert plain user password to encrypted user password.
3*/
4
5const eachSeries = require('async/eachSeries')
6const mongoose = require('mongoose')
7
8const User = mongoose.model('User')
9
10exports.up = function (callback) {
11 User.list(function (err, users) {
12 if (err) return callback(err)
13
14 eachSeries(users, function (user, callbackEach) {
15 user.save(callbackEach)
16 }, callback)
17 })
18}
19
20exports.down = function (callback) {
21 throw new Error('Not implemented.')
22}
diff --git a/server/initializers/migrations/0015-admin-role.js b/server/initializers/migrations/0015-admin-role.js
new file mode 100644
index 000000000..af06dca9e
--- /dev/null
+++ b/server/initializers/migrations/0015-admin-role.js
@@ -0,0 +1,16 @@
1/*
2 Set the admin role to the root user.
3*/
4
5const constants = require('../constants')
6const mongoose = require('mongoose')
7
8const User = mongoose.model('User')
9
10exports.up = function (callback) {
11 User.update({ username: 'root' }, { role: constants.USER_ROLES.ADMIN }, callback)
12}
13
14exports.down = function (callback) {
15 throw new Error('Not implemented.')
16}
diff --git a/server/initializers/migrator.js b/server/initializers/migrator.js
new file mode 100644
index 000000000..6b31d994f
--- /dev/null
+++ b/server/initializers/migrator.js
@@ -0,0 +1,56 @@
1'use strict'
2
3const eachSeries = require('async/eachSeries')
4const mongoose = require('mongoose')
5const path = require('path')
6
7const constants = require('./constants')
8const logger = require('../helpers/logger')
9
10const Application = mongoose.model('Application')
11
12const migrator = {
13 migrate: migrate
14}
15
16function migrate (callback) {
17 Application.loadMongoSchemaVersion(function (err, actualVersion) {
18 if (err) return callback(err)
19
20 // If there are a new mongo schemas
21 if (!actualVersion || actualVersion < constants.LAST_MONGO_SCHEMA_VERSION) {
22 logger.info('Begin migrations.')
23
24 eachSeries(constants.MONGO_MIGRATION_SCRIPTS, function (entity, callbackEach) {
25 const versionScript = entity.version
26
27 // Do not execute old migration scripts
28 if (versionScript <= actualVersion) return callbackEach(null)
29
30 // Load the migration module and run it
31 const migrationScriptName = entity.script
32 logger.info('Executing %s migration script.', migrationScriptName)
33
34 const migrationScript = require(path.join(__dirname, 'migrations', migrationScriptName))
35 migrationScript.up(function (err) {
36 if (err) return callbackEach(err)
37
38 // Update the new mongo version schema
39 Application.updateMongoSchemaVersion(versionScript, callbackEach)
40 })
41 }, function (err) {
42 if (err) return callback(err)
43
44 logger.info('Migrations finished. New mongo version schema: %s', constants.LAST_MONGO_SCHEMA_VERSION)
45 return callback(null)
46 })
47 } else {
48 return callback(null)
49 }
50 })
51}
52
53// ---------------------------------------------------------------------------
54
55module.exports = migrator
56