aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server/helpers/custom-validators/pods.js9
-rw-r--r--server/helpers/custom-validators/videos.js6
-rw-r--r--server/initializers/constants.js2
-rw-r--r--server/initializers/installer.js10
-rw-r--r--server/models/application.js8
-rw-r--r--server/models/author.js13
-rw-r--r--server/models/oauth-client.js11
-rw-r--r--server/models/oauth-token.js19
-rw-r--r--server/models/pod.js34
-rw-r--r--server/models/request.js14
-rw-r--r--server/models/tag.js3
-rw-r--r--server/models/user.js32
-rw-r--r--server/models/video.js74
13 files changed, 162 insertions, 73 deletions
diff --git a/server/helpers/custom-validators/pods.js b/server/helpers/custom-validators/pods.js
index 0154a2424..8bb3733ff 100644
--- a/server/helpers/custom-validators/pods.js
+++ b/server/helpers/custom-validators/pods.js
@@ -5,14 +5,19 @@ const validator = require('express-validator').validator
5const miscValidators = require('./misc') 5const miscValidators = require('./misc')
6 6
7const podsValidators = { 7const podsValidators = {
8 isEachUniqueHostValid 8 isEachUniqueHostValid,
9 isHostValid
10}
11
12function isHostValid (host) {
13 return validator.isURL(host) && host.split('://').length === 1
9} 14}
10 15
11function isEachUniqueHostValid (hosts) { 16function isEachUniqueHostValid (hosts) {
12 return miscValidators.isArray(hosts) && 17 return miscValidators.isArray(hosts) &&
13 hosts.length !== 0 && 18 hosts.length !== 0 &&
14 hosts.every(function (host) { 19 hosts.every(function (host) {
15 return validator.isURL(host) && host.split('://').length === 1 && hosts.indexOf(host) === hosts.lastIndexOf(host) 20 return isHostValid(host) && hosts.indexOf(host) === hosts.lastIndexOf(host)
16 }) 21 })
17} 22}
18 23
diff --git a/server/helpers/custom-validators/videos.js b/server/helpers/custom-validators/videos.js
index be8256a80..da857ba5f 100644
--- a/server/helpers/custom-validators/videos.js
+++ b/server/helpers/custom-validators/videos.js
@@ -15,7 +15,6 @@ const videosValidators = {
15 isVideoDurationValid, 15 isVideoDurationValid,
16 isVideoInfoHashValid, 16 isVideoInfoHashValid,
17 isVideoNameValid, 17 isVideoNameValid,
18 isVideoPodHostValid,
19 isVideoTagsValid, 18 isVideoTagsValid,
20 isVideoThumbnailValid, 19 isVideoThumbnailValid,
21 isVideoThumbnail64Valid 20 isVideoThumbnail64Valid
@@ -74,11 +73,6 @@ function isVideoNameValid (value) {
74 return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME) 73 return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME)
75} 74}
76 75
77function isVideoPodHostValid (value) {
78 // TODO: set options (TLD...)
79 return validator.isURL(value)
80}
81
82function isVideoTagsValid (tags) { 76function isVideoTagsValid (tags) {
83 return miscValidators.isArray(tags) && 77 return miscValidators.isArray(tags) &&
84 validator.isInt(tags.length, VIDEOS_CONSTRAINTS_FIELDS.TAGS) && 78 validator.isInt(tags.length, VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
diff --git a/server/initializers/constants.js b/server/initializers/constants.js
index fc501845a..0af7aca3c 100644
--- a/server/initializers/constants.js
+++ b/server/initializers/constants.js
@@ -69,7 +69,7 @@ const CONSTRAINTS_FIELDS = {
69 NAME: { min: 3, max: 50 }, // Length 69 NAME: { min: 3, max: 50 }, // Length
70 DESCRIPTION: { min: 3, max: 250 }, // Length 70 DESCRIPTION: { min: 3, max: 250 }, // Length
71 EXTNAME: [ '.mp4', '.ogv', '.webm' ], 71 EXTNAME: [ '.mp4', '.ogv', '.webm' ],
72 INFO_HASH: { min: 10, max: 50 }, // Length 72 INFO_HASH: { min: 40, max: 40 }, // Length, infohash is 20 bytes length but we represent it in hexa so 20 * 2
73 DURATION: { min: 1, max: 7200 }, // Number 73 DURATION: { min: 1, max: 7200 }, // Number
74 TAGS: { min: 1, max: 3 }, // Number of total tags 74 TAGS: { min: 1, max: 3 }, // Number of total tags
75 TAG: { min: 2, max: 10 }, // Length 75 TAG: { min: 2, max: 10 }, // Length
diff --git a/server/initializers/installer.js b/server/initializers/installer.js
index d5382364e..fb63b81ac 100644
--- a/server/initializers/installer.js
+++ b/server/initializers/installer.js
@@ -96,6 +96,7 @@ function createOAuthAdminIfNotExist (callback) {
96 96
97 const username = 'root' 97 const username = 'root'
98 const role = constants.USER_ROLES.ADMIN 98 const role = constants.USER_ROLES.ADMIN
99 const createOptions = {}
99 let password = '' 100 let password = ''
100 101
101 // Do not generate a random password for tests 102 // Do not generate a random password for tests
@@ -105,17 +106,20 @@ function createOAuthAdminIfNotExist (callback) {
105 if (process.env.NODE_APP_INSTANCE) { 106 if (process.env.NODE_APP_INSTANCE) {
106 password += process.env.NODE_APP_INSTANCE 107 password += process.env.NODE_APP_INSTANCE
107 } 108 }
109
110 // Our password is weak so do not validate it
111 createOptions.validate = false
108 } else { 112 } else {
109 password = passwordGenerator(8, true) 113 password = passwordGenerator(8, true)
110 } 114 }
111 115
112 const user = db.User.build({ 116 const userData = {
113 username, 117 username,
114 password, 118 password,
115 role 119 role
116 }) 120 }
117 121
118 user.save().asCallback(function (err, createdUser) { 122 db.User.create(userData, createOptions).asCallback(function (err, createdUser) {
119 if (err) return callback(err) 123 if (err) return callback(err)
120 124
121 logger.info('Username: ' + username) 125 logger.info('Username: ' + username)
diff --git a/server/models/application.js b/server/models/application.js
index 4114ed76d..46dcfde33 100644
--- a/server/models/application.js
+++ b/server/models/application.js
@@ -1,9 +1,15 @@
1'use strict'
2
1module.exports = function (sequelize, DataTypes) { 3module.exports = function (sequelize, DataTypes) {
2 const Application = sequelize.define('Application', 4 const Application = sequelize.define('Application',
3 { 5 {
4 migrationVersion: { 6 migrationVersion: {
5 type: DataTypes.INTEGER, 7 type: DataTypes.INTEGER,
6 defaultValue: 0 8 defaultValue: 0,
9 allowNull: false,
10 validate: {
11 isInt: true
12 }
7 } 13 }
8 }, 14 },
9 { 15 {
diff --git a/server/models/author.js b/server/models/author.js
index 493c2ca11..e0ac868ea 100644
--- a/server/models/author.js
+++ b/server/models/author.js
@@ -1,8 +1,19 @@
1'use strict'
2
3const customUsersValidators = require('../helpers/custom-validators').users
4
1module.exports = function (sequelize, DataTypes) { 5module.exports = function (sequelize, DataTypes) {
2 const Author = sequelize.define('Author', 6 const Author = sequelize.define('Author',
3 { 7 {
4 name: { 8 name: {
5 type: DataTypes.STRING 9 type: DataTypes.STRING,
10 allowNull: false,
11 validate: {
12 usernameValid: function (value) {
13 const res = customUsersValidators.isUserUsernameValid(value)
14 if (res === false) throw new Error('Username is not valid.')
15 }
16 }
6 } 17 }
7 }, 18 },
8 { 19 {
diff --git a/server/models/oauth-client.js b/server/models/oauth-client.js
index 15118591a..b56838d4c 100644
--- a/server/models/oauth-client.js
+++ b/server/models/oauth-client.js
@@ -1,11 +1,15 @@
1'use strict'
2
1module.exports = function (sequelize, DataTypes) { 3module.exports = function (sequelize, DataTypes) {
2 const OAuthClient = sequelize.define('OAuthClient', 4 const OAuthClient = sequelize.define('OAuthClient',
3 { 5 {
4 clientId: { 6 clientId: {
5 type: DataTypes.STRING 7 type: DataTypes.STRING,
8 allowNull: false
6 }, 9 },
7 clientSecret: { 10 clientSecret: {
8 type: DataTypes.STRING 11 type: DataTypes.STRING,
12 allowNull: false
9 }, 13 },
10 grants: { 14 grants: {
11 type: DataTypes.ARRAY(DataTypes.STRING) 15 type: DataTypes.ARRAY(DataTypes.STRING)
@@ -28,9 +32,6 @@ module.exports = function (sequelize, DataTypes) {
28 return OAuthClient 32 return OAuthClient
29} 33}
30 34
31// TODO: validation
32// OAuthClientSchema.path('clientSecret').required(true)
33
34// --------------------------------------------------------------------------- 35// ---------------------------------------------------------------------------
35 36
36function associate (models) { 37function associate (models) {
diff --git a/server/models/oauth-token.js b/server/models/oauth-token.js
index c9108bf95..f8de4e916 100644
--- a/server/models/oauth-token.js
+++ b/server/models/oauth-token.js
@@ -1,3 +1,5 @@
1'use strict'
2
1const logger = require('../helpers/logger') 3const logger = require('../helpers/logger')
2 4
3// --------------------------------------------------------------------------- 5// ---------------------------------------------------------------------------
@@ -6,16 +8,20 @@ module.exports = function (sequelize, DataTypes) {
6 const OAuthToken = sequelize.define('OAuthToken', 8 const OAuthToken = sequelize.define('OAuthToken',
7 { 9 {
8 accessToken: { 10 accessToken: {
9 type: DataTypes.STRING 11 type: DataTypes.STRING,
12 allowNull: false
10 }, 13 },
11 accessTokenExpiresAt: { 14 accessTokenExpiresAt: {
12 type: DataTypes.DATE 15 type: DataTypes.DATE,
16 allowNull: false
13 }, 17 },
14 refreshToken: { 18 refreshToken: {
15 type: DataTypes.STRING 19 type: DataTypes.STRING,
20 allowNull: false
16 }, 21 },
17 refreshTokenExpiresAt: { 22 refreshTokenExpiresAt: {
18 type: DataTypes.DATE 23 type: DataTypes.DATE,
24 allowNull: false
19 } 25 }
20 }, 26 },
21 { 27 {
@@ -33,11 +39,6 @@ module.exports = function (sequelize, DataTypes) {
33 return OAuthToken 39 return OAuthToken
34} 40}
35 41
36// TODO: validation
37// OAuthTokenSchema.path('accessToken').required(true)
38// OAuthTokenSchema.path('client').required(true)
39// OAuthTokenSchema.path('user').required(true)
40
41// --------------------------------------------------------------------------- 42// ---------------------------------------------------------------------------
42 43
43function associate (models) { 44function associate (models) {
diff --git a/server/models/pod.js b/server/models/pod.js
index fff6970a7..84f78f200 100644
--- a/server/models/pod.js
+++ b/server/models/pod.js
@@ -3,6 +3,7 @@
3const map = require('lodash/map') 3const map = require('lodash/map')
4 4
5const constants = require('../initializers/constants') 5const constants = require('../initializers/constants')
6const customPodsValidators = require('../helpers/custom-validators').pods
6 7
7// --------------------------------------------------------------------------- 8// ---------------------------------------------------------------------------
8 9
@@ -10,14 +11,27 @@ module.exports = function (sequelize, DataTypes) {
10 const Pod = sequelize.define('Pod', 11 const Pod = sequelize.define('Pod',
11 { 12 {
12 host: { 13 host: {
13 type: DataTypes.STRING 14 type: DataTypes.STRING,
15 allowNull: false,
16 validate: {
17 isHost: function (value) {
18 const res = customPodsValidators.isHostValid(value)
19 if (res === false) throw new Error('Host not valid.')
20 }
21 }
14 }, 22 },
15 publicKey: { 23 publicKey: {
16 type: DataTypes.STRING(5000) 24 type: DataTypes.STRING(5000),
25 allowNull: false
17 }, 26 },
18 score: { 27 score: {
19 type: DataTypes.INTEGER, 28 type: DataTypes.INTEGER,
20 defaultValue: constants.FRIEND_SCORE.BASE 29 defaultValue: constants.FRIEND_SCORE.BASE,
30 allowNull: false,
31 validate: {
32 isInt: true,
33 max: constants.FRIEND_SCORE.MAX
34 }
21 } 35 }
22 }, 36 },
23 { 37 {
@@ -42,12 +56,6 @@ module.exports = function (sequelize, DataTypes) {
42 return Pod 56 return Pod
43} 57}
44 58
45// TODO: max score -> constants.FRIENDS_SCORE.MAX
46// TODO: validation
47// PodSchema.path('host').validate(validator.isURL)
48// PodSchema.path('publicKey').required(true)
49// PodSchema.path('score').validate(function (value) { return !isNaN(value) })
50
51// ------------------------------ METHODS ------------------------------ 59// ------------------------------ METHODS ------------------------------
52 60
53function toFormatedJSON () { 61function toFormatedJSON () {
@@ -82,15 +90,17 @@ function incrementScores (ids, value, callback) {
82 score: this.sequelize.literal('score +' + value) 90 score: this.sequelize.literal('score +' + value)
83 } 91 }
84 92
85 const query = { 93 const options = {
86 where: { 94 where: {
87 id: { 95 id: {
88 $in: ids 96 $in: ids
89 } 97 }
90 } 98 },
99 // In this case score is a literal and not an integer so we do not validate it
100 validate: false
91 } 101 }
92 102
93 return this.update(update, query).asCallback(callback) 103 return this.update(update, options).asCallback(callback)
94} 104}
95 105
96function list (callback) { 106function list (callback) {
diff --git a/server/models/request.js b/server/models/request.js
index 70aa32610..e18f8fe3d 100644
--- a/server/models/request.js
+++ b/server/models/request.js
@@ -3,6 +3,7 @@
3const each = require('async/each') 3const each = require('async/each')
4const eachLimit = require('async/eachLimit') 4const eachLimit = require('async/eachLimit')
5const waterfall = require('async/waterfall') 5const waterfall = require('async/waterfall')
6const values = require('lodash/values')
6 7
7const constants = require('../initializers/constants') 8const constants = require('../initializers/constants')
8const logger = require('../helpers/logger') 9const logger = require('../helpers/logger')
@@ -17,11 +18,12 @@ module.exports = function (sequelize, DataTypes) {
17 const Request = sequelize.define('Request', 18 const Request = sequelize.define('Request',
18 { 19 {
19 request: { 20 request: {
20 type: DataTypes.JSON 21 type: DataTypes.JSON,
22 allowNull: false
21 }, 23 },
22 endpoint: { 24 endpoint: {
23 // TODO: enum? 25 type: DataTypes.ENUM(values(constants.REQUEST_ENDPOINTS)),
24 type: DataTypes.STRING 26 allowNull: false
25 } 27 }
26 }, 28 },
27 { 29 {
@@ -196,7 +198,7 @@ function makeRequests () {
196 198
197 makeRequest(toPod, requestToMake.endpoint, requestToMake.datas, function (success) { 199 makeRequest(toPod, requestToMake.endpoint, requestToMake.datas, function (success) {
198 if (success === true) { 200 if (success === true) {
199 logger.debug('Removing requests for %s pod.', requestToMake.toPodId, { requestsIds: requestToMake.ids }) 201 logger.debug('Removing requests for pod %s.', requestToMake.toPodId, { requestsIds: requestToMake.ids })
200 202
201 goodPods.push(requestToMake.toPodId) 203 goodPods.push(requestToMake.toPodId)
202 204
@@ -261,13 +263,13 @@ function updatePodsScore (goodPods, badPods) {
261 263
262 if (goodPods.length !== 0) { 264 if (goodPods.length !== 0) {
263 Pod.incrementScores(goodPods, constants.PODS_SCORE.BONUS, function (err) { 265 Pod.incrementScores(goodPods, constants.PODS_SCORE.BONUS, function (err) {
264 if (err) logger.error('Cannot increment scores of good pods.') 266 if (err) logger.error('Cannot increment scores of good pods.', { error: err })
265 }) 267 })
266 } 268 }
267 269
268 if (badPods.length !== 0) { 270 if (badPods.length !== 0) {
269 Pod.incrementScores(badPods, constants.PODS_SCORE.MALUS, function (err) { 271 Pod.incrementScores(badPods, constants.PODS_SCORE.MALUS, function (err) {
270 if (err) logger.error('Cannot decrement scores of bad pods.') 272 if (err) logger.error('Cannot decrement scores of bad pods.', { error: err })
271 removeBadPods.call(self) 273 removeBadPods.call(self)
272 }) 274 })
273 } 275 }
diff --git a/server/models/tag.js b/server/models/tag.js
index 874e88842..d6c2d3bb1 100644
--- a/server/models/tag.js
+++ b/server/models/tag.js
@@ -6,7 +6,8 @@ module.exports = function (sequelize, DataTypes) {
6 const Tag = sequelize.define('Tag', 6 const Tag = sequelize.define('Tag',
7 { 7 {
8 name: { 8 name: {
9 type: DataTypes.STRING 9 type: DataTypes.STRING,
10 allowNull: false
10 } 11 }
11 }, 12 },
12 { 13 {
diff --git a/server/models/user.js b/server/models/user.js
index e50eb96ea..944986a44 100644
--- a/server/models/user.js
+++ b/server/models/user.js
@@ -1,5 +1,11 @@
1'use strict'
2
3const values = require('lodash/values')
4
1const modelUtils = require('./utils') 5const modelUtils = require('./utils')
6const constants = require('../initializers/constants')
2const peertubeCrypto = require('../helpers/peertube-crypto') 7const peertubeCrypto = require('../helpers/peertube-crypto')
8const customUsersValidators = require('../helpers/custom-validators').users
3 9
4// --------------------------------------------------------------------------- 10// ---------------------------------------------------------------------------
5 11
@@ -7,13 +13,28 @@ module.exports = function (sequelize, DataTypes) {
7 const User = sequelize.define('User', 13 const User = sequelize.define('User',
8 { 14 {
9 password: { 15 password: {
10 type: DataTypes.STRING 16 type: DataTypes.STRING,
17 allowNull: false,
18 validate: {
19 passwordValid: function (value) {
20 const res = customUsersValidators.isUserPasswordValid(value)
21 if (res === false) throw new Error('Password not valid.')
22 }
23 }
11 }, 24 },
12 username: { 25 username: {
13 type: DataTypes.STRING 26 type: DataTypes.STRING,
27 allowNull: false,
28 validate: {
29 usernameValid: function (value) {
30 const res = customUsersValidators.isUserUsernameValid(value)
31 if (res === false) throw new Error('Username not valid.')
32 }
33 }
14 }, 34 },
15 role: { 35 role: {
16 type: DataTypes.STRING 36 type: DataTypes.ENUM(values(constants.USER_ROLES)),
37 allowNull: false
17 } 38 }
18 }, 39 },
19 { 40 {
@@ -41,11 +62,6 @@ module.exports = function (sequelize, DataTypes) {
41 return User 62 return User
42} 63}
43 64
44// TODO: Validation
45// UserSchema.path('password').required(customUsersValidators.isUserPasswordValid)
46// UserSchema.path('username').required(customUsersValidators.isUserUsernameValid)
47// UserSchema.path('role').validate(customUsersValidators.isUserRoleValid)
48
49function beforeCreateOrUpdate (user, options, next) { 65function beforeCreateOrUpdate (user, options, next) {
50 peertubeCrypto.cryptPassword(user.password, function (err, hash) { 66 peertubeCrypto.cryptPassword(user.password, function (err, hash) {
51 if (err) return next(err) 67 if (err) return next(err)
diff --git a/server/models/video.js b/server/models/video.js
index 04478c8d7..3ebc48ad4 100644
--- a/server/models/video.js
+++ b/server/models/video.js
@@ -8,10 +8,12 @@ const map = require('lodash/map')
8const parallel = require('async/parallel') 8const parallel = require('async/parallel')
9const parseTorrent = require('parse-torrent') 9const parseTorrent = require('parse-torrent')
10const pathUtils = require('path') 10const pathUtils = require('path')
11const values = require('lodash/values')
11 12
12const constants = require('../initializers/constants') 13const constants = require('../initializers/constants')
13const logger = require('../helpers/logger') 14const logger = require('../helpers/logger')
14const modelUtils = require('./utils') 15const modelUtils = require('./utils')
16const customVideosValidators = require('../helpers/custom-validators').videos
15 17
16// --------------------------------------------------------------------------- 18// ---------------------------------------------------------------------------
17 19
@@ -22,26 +24,61 @@ module.exports = function (sequelize, DataTypes) {
22 id: { 24 id: {
23 type: DataTypes.UUID, 25 type: DataTypes.UUID,
24 defaultValue: DataTypes.UUIDV4, 26 defaultValue: DataTypes.UUIDV4,
25 primaryKey: true 27 primaryKey: true,
28 validate: {
29 isUUID: 4
30 }
26 }, 31 },
27 name: { 32 name: {
28 type: DataTypes.STRING 33 type: DataTypes.STRING,
34 allowNull: false,
35 validate: {
36 nameValid: function (value) {
37 const res = customVideosValidators.isVideoNameValid(value)
38 if (res === false) throw new Error('Video name is not valid.')
39 }
40 }
29 }, 41 },
30 extname: { 42 extname: {
31 // TODO: enum? 43 type: DataTypes.ENUM(values(constants.CONSTRAINTS_FIELDS.VIDEOS.EXTNAME)),
32 type: DataTypes.STRING 44 allowNull: false
33 }, 45 },
34 remoteId: { 46 remoteId: {
35 type: DataTypes.UUID 47 type: DataTypes.UUID,
48 allowNull: true,
49 validate: {
50 isUUID: 4
51 }
36 }, 52 },
37 description: { 53 description: {
38 type: DataTypes.STRING 54 type: DataTypes.STRING,
55 allowNull: false,
56 validate: {
57 descriptionValid: function (value) {
58 const res = customVideosValidators.isVideoDescriptionValid(value)
59 if (res === false) throw new Error('Video description is not valid.')
60 }
61 }
39 }, 62 },
40 infoHash: { 63 infoHash: {
41 type: DataTypes.STRING 64 type: DataTypes.STRING,
65 allowNull: false,
66 validate: {
67 infoHashValid: function (value) {
68 const res = customVideosValidators.isVideoInfoHashValid(value)
69 if (res === false) throw new Error('Video info hash is not valid.')
70 }
71 }
42 }, 72 },
43 duration: { 73 duration: {
44 type: DataTypes.INTEGER 74 type: DataTypes.INTEGER,
75 allowNull: false,
76 validate: {
77 durationValid: function (value) {
78 const res = customVideosValidators.isVideoDurationValid(value)
79 if (res === false) throw new Error('Video duration is not valid.')
80 }
81 }
45 } 82 }
46 }, 83 },
47 { 84 {
@@ -71,6 +108,7 @@ module.exports = function (sequelize, DataTypes) {
71 toRemoteJSON 108 toRemoteJSON
72 }, 109 },
73 hooks: { 110 hooks: {
111 beforeValidate,
74 beforeCreate, 112 beforeCreate,
75 afterDestroy 113 afterDestroy
76 } 114 }
@@ -80,13 +118,14 @@ module.exports = function (sequelize, DataTypes) {
80 return Video 118 return Video
81} 119}
82 120
83// TODO: Validation 121function beforeValidate (video, options, next) {
84// VideoSchema.path('name').validate(customVideosValidators.isVideoNameValid) 122 if (video.isOwned()) {
85// VideoSchema.path('description').validate(customVideosValidators.isVideoDescriptionValid) 123 // 40 hexa length
86// VideoSchema.path('podHost').validate(customVideosValidators.isVideoPodHostValid) 124 video.infoHash = '0123456789abcdef0123456789abcdef01234567'
87// VideoSchema.path('author').validate(customVideosValidators.isVideoAuthorValid) 125 }
88// VideoSchema.path('duration').validate(customVideosValidators.isVideoDurationValid) 126
89// VideoSchema.path('tags').validate(customVideosValidators.isVideoTagsValid) 127 return next(null)
128}
90 129
91function beforeCreate (video, options, next) { 130function beforeCreate (video, options, next) {
92 const tasks = [] 131 const tasks = []
@@ -113,9 +152,8 @@ function beforeCreate (video, options, next) {
113 if (err) return callback(err) 152 if (err) return callback(err)
114 153
115 const parsedTorrent = parseTorrent(torrent) 154 const parsedTorrent = parseTorrent(torrent)
116 video.infoHash = parsedTorrent.infoHash 155 video.set('infoHash', parsedTorrent.infoHash)
117 156 video.validate().asCallback(callback)
118 callback(null)
119 }) 157 })
120 }) 158 })
121 }, 159 },