diff options
33 files changed, 500 insertions, 665 deletions
diff --git a/server/controllers/activitypub/client.ts b/server/controllers/activitypub/client.ts index 41272bca0..62cde1fc7 100644 --- a/server/controllers/activitypub/client.ts +++ b/server/controllers/activitypub/client.ts | |||
@@ -19,22 +19,22 @@ import { VideoShareInstance } from '../../models/video/video-share-interface' | |||
19 | const activityPubClientRouter = express.Router() | 19 | const activityPubClientRouter = express.Router() |
20 | 20 | ||
21 | activityPubClientRouter.get('/account/:name', | 21 | activityPubClientRouter.get('/account/:name', |
22 | executeIfActivityPub(localAccountValidator), | 22 | executeIfActivityPub(asyncMiddleware(localAccountValidator)), |
23 | executeIfActivityPub(accountController) | 23 | executeIfActivityPub(accountController) |
24 | ) | 24 | ) |
25 | 25 | ||
26 | activityPubClientRouter.get('/account/:name/followers', | 26 | activityPubClientRouter.get('/account/:name/followers', |
27 | executeIfActivityPub(localAccountValidator), | 27 | executeIfActivityPub(asyncMiddleware(localAccountValidator)), |
28 | executeIfActivityPub(asyncMiddleware(accountFollowersController)) | 28 | executeIfActivityPub(asyncMiddleware(accountFollowersController)) |
29 | ) | 29 | ) |
30 | 30 | ||
31 | activityPubClientRouter.get('/account/:name/following', | 31 | activityPubClientRouter.get('/account/:name/following', |
32 | executeIfActivityPub(localAccountValidator), | 32 | executeIfActivityPub(asyncMiddleware(localAccountValidator)), |
33 | executeIfActivityPub(asyncMiddleware(accountFollowingController)) | 33 | executeIfActivityPub(asyncMiddleware(accountFollowingController)) |
34 | ) | 34 | ) |
35 | 35 | ||
36 | activityPubClientRouter.get('/videos/watch/:id', | 36 | activityPubClientRouter.get('/videos/watch/:id', |
37 | executeIfActivityPub(videosGetValidator), | 37 | executeIfActivityPub(asyncMiddleware(videosGetValidator)), |
38 | executeIfActivityPub(videoController) | 38 | executeIfActivityPub(videoController) |
39 | ) | 39 | ) |
40 | 40 | ||
@@ -44,7 +44,7 @@ activityPubClientRouter.get('/videos/watch/:id/announces/:accountId', | |||
44 | ) | 44 | ) |
45 | 45 | ||
46 | activityPubClientRouter.get('/video-channels/:id', | 46 | activityPubClientRouter.get('/video-channels/:id', |
47 | executeIfActivityPub(videoChannelsGetValidator), | 47 | executeIfActivityPub(asyncMiddleware(videoChannelsGetValidator)), |
48 | executeIfActivityPub(asyncMiddleware(videoChannelController)) | 48 | executeIfActivityPub(asyncMiddleware(videoChannelController)) |
49 | ) | 49 | ) |
50 | 50 | ||
diff --git a/server/controllers/api/server/follows.ts b/server/controllers/api/server/follows.ts index 535d530f7..c2fb37c39 100644 --- a/server/controllers/api/server/follows.ts +++ b/server/controllers/api/server/follows.ts | |||
@@ -41,7 +41,7 @@ serverFollowsRouter.post('/following', | |||
41 | serverFollowsRouter.delete('/following/:accountId', | 41 | serverFollowsRouter.delete('/following/:accountId', |
42 | authenticate, | 42 | authenticate, |
43 | ensureUserHasRight(UserRight.MANAGE_SERVER_FOLLOW), | 43 | ensureUserHasRight(UserRight.MANAGE_SERVER_FOLLOW), |
44 | removeFollowingValidator, | 44 | asyncMiddleware(removeFollowingValidator), |
45 | asyncMiddleware(removeFollow) | 45 | asyncMiddleware(removeFollow) |
46 | ) | 46 | ) |
47 | 47 | ||
diff --git a/server/controllers/api/users.ts b/server/controllers/api/users.ts index ac7c87517..721b23301 100644 --- a/server/controllers/api/users.ts +++ b/server/controllers/api/users.ts | |||
@@ -43,7 +43,7 @@ usersRouter.get('/me/videos', | |||
43 | 43 | ||
44 | usersRouter.get('/me/videos/:videoId/rating', | 44 | usersRouter.get('/me/videos/:videoId/rating', |
45 | authenticate, | 45 | authenticate, |
46 | usersVideoRatingValidator, | 46 | asyncMiddleware(usersVideoRatingValidator), |
47 | asyncMiddleware(getUserVideoRating) | 47 | asyncMiddleware(getUserVideoRating) |
48 | ) | 48 | ) |
49 | 49 | ||
@@ -56,20 +56,20 @@ usersRouter.get('/', | |||
56 | ) | 56 | ) |
57 | 57 | ||
58 | usersRouter.get('/:id', | 58 | usersRouter.get('/:id', |
59 | usersGetValidator, | 59 | asyncMiddleware(usersGetValidator), |
60 | getUser | 60 | getUser |
61 | ) | 61 | ) |
62 | 62 | ||
63 | usersRouter.post('/', | 63 | usersRouter.post('/', |
64 | authenticate, | 64 | authenticate, |
65 | ensureUserHasRight(UserRight.MANAGE_USERS), | 65 | ensureUserHasRight(UserRight.MANAGE_USERS), |
66 | usersAddValidator, | 66 | asyncMiddleware(usersAddValidator), |
67 | createUserRetryWrapper | 67 | asyncMiddleware(createUserRetryWrapper) |
68 | ) | 68 | ) |
69 | 69 | ||
70 | usersRouter.post('/register', | 70 | usersRouter.post('/register', |
71 | ensureUserRegistrationAllowed, | 71 | asyncMiddleware(ensureUserRegistrationAllowed), |
72 | usersRegisterValidator, | 72 | asyncMiddleware(usersRegisterValidator), |
73 | asyncMiddleware(registerUserRetryWrapper) | 73 | asyncMiddleware(registerUserRetryWrapper) |
74 | ) | 74 | ) |
75 | 75 | ||
@@ -82,14 +82,14 @@ usersRouter.put('/me', | |||
82 | usersRouter.put('/:id', | 82 | usersRouter.put('/:id', |
83 | authenticate, | 83 | authenticate, |
84 | ensureUserHasRight(UserRight.MANAGE_USERS), | 84 | ensureUserHasRight(UserRight.MANAGE_USERS), |
85 | usersUpdateValidator, | 85 | asyncMiddleware(usersUpdateValidator), |
86 | asyncMiddleware(updateUser) | 86 | asyncMiddleware(updateUser) |
87 | ) | 87 | ) |
88 | 88 | ||
89 | usersRouter.delete('/:id', | 89 | usersRouter.delete('/:id', |
90 | authenticate, | 90 | authenticate, |
91 | ensureUserHasRight(UserRight.MANAGE_USERS), | 91 | ensureUserHasRight(UserRight.MANAGE_USERS), |
92 | usersRemoveValidator, | 92 | asyncMiddleware(usersRemoveValidator), |
93 | asyncMiddleware(removeUser) | 93 | asyncMiddleware(removeUser) |
94 | ) | 94 | ) |
95 | 95 | ||
diff --git a/server/controllers/api/videos/abuse.ts b/server/controllers/api/videos/abuse.ts index 88b3d538d..29e1175c5 100644 --- a/server/controllers/api/videos/abuse.ts +++ b/server/controllers/api/videos/abuse.ts | |||
@@ -33,7 +33,7 @@ abuseVideoRouter.get('/abuse', | |||
33 | ) | 33 | ) |
34 | abuseVideoRouter.post('/:id/abuse', | 34 | abuseVideoRouter.post('/:id/abuse', |
35 | authenticate, | 35 | authenticate, |
36 | videoAbuseReportValidator, | 36 | asyncMiddleware(videoAbuseReportValidator), |
37 | asyncMiddleware(reportVideoAbuseRetryWrapper) | 37 | asyncMiddleware(reportVideoAbuseRetryWrapper) |
38 | ) | 38 | ) |
39 | 39 | ||
diff --git a/server/controllers/api/videos/blacklist.ts b/server/controllers/api/videos/blacklist.ts index be7cf6ea4..06333c271 100644 --- a/server/controllers/api/videos/blacklist.ts +++ b/server/controllers/api/videos/blacklist.ts | |||
@@ -21,7 +21,7 @@ const blacklistRouter = express.Router() | |||
21 | blacklistRouter.post('/:videoId/blacklist', | 21 | blacklistRouter.post('/:videoId/blacklist', |
22 | authenticate, | 22 | authenticate, |
23 | ensureUserHasRight(UserRight.MANAGE_VIDEO_BLACKLIST), | 23 | ensureUserHasRight(UserRight.MANAGE_VIDEO_BLACKLIST), |
24 | videosBlacklistAddValidator, | 24 | asyncMiddleware(videosBlacklistAddValidator), |
25 | asyncMiddleware(addVideoToBlacklist) | 25 | asyncMiddleware(addVideoToBlacklist) |
26 | ) | 26 | ) |
27 | 27 | ||
@@ -38,7 +38,7 @@ blacklistRouter.get('/blacklist', | |||
38 | blacklistRouter.delete('/:videoId/blacklist', | 38 | blacklistRouter.delete('/:videoId/blacklist', |
39 | authenticate, | 39 | authenticate, |
40 | ensureUserHasRight(UserRight.MANAGE_VIDEO_BLACKLIST), | 40 | ensureUserHasRight(UserRight.MANAGE_VIDEO_BLACKLIST), |
41 | videosBlacklistRemoveValidator, | 41 | asyncMiddleware(videosBlacklistRemoveValidator), |
42 | asyncMiddleware(removeVideoFromBlacklistController) | 42 | asyncMiddleware(removeVideoFromBlacklistController) |
43 | ) | 43 | ) |
44 | 44 | ||
diff --git a/server/controllers/api/videos/channel.ts b/server/controllers/api/videos/channel.ts index ce2656e71..d99f47c32 100644 --- a/server/controllers/api/videos/channel.ts +++ b/server/controllers/api/videos/channel.ts | |||
@@ -3,6 +3,7 @@ import { VideoChannelCreate, VideoChannelUpdate } from '../../../../shared' | |||
3 | import { getFormattedObjects, logger, resetSequelizeInstance, retryTransactionWrapper } from '../../../helpers' | 3 | import { getFormattedObjects, logger, resetSequelizeInstance, retryTransactionWrapper } from '../../../helpers' |
4 | import { database as db } from '../../../initializers' | 4 | import { database as db } from '../../../initializers' |
5 | import { createVideoChannel } from '../../../lib' | 5 | import { createVideoChannel } from '../../../lib' |
6 | import { sendUpdateVideoChannel } from '../../../lib/activitypub/send/send-update' | ||
6 | import { | 7 | import { |
7 | asyncMiddleware, | 8 | asyncMiddleware, |
8 | authenticate, | 9 | authenticate, |
@@ -10,14 +11,13 @@ import { | |||
10 | paginationValidator, | 11 | paginationValidator, |
11 | setPagination, | 12 | setPagination, |
12 | setVideoChannelsSort, | 13 | setVideoChannelsSort, |
13 | videoChannelsGetValidator, | ||
14 | videoChannelsAddValidator, | 14 | videoChannelsAddValidator, |
15 | videoChannelsGetValidator, | ||
15 | videoChannelsRemoveValidator, | 16 | videoChannelsRemoveValidator, |
16 | videoChannelsSortValidator, | 17 | videoChannelsSortValidator, |
17 | videoChannelsUpdateValidator | 18 | videoChannelsUpdateValidator |
18 | } from '../../../middlewares' | 19 | } from '../../../middlewares' |
19 | import { AccountInstance, VideoChannelInstance } from '../../../models' | 20 | import { AccountInstance, VideoChannelInstance } from '../../../models' |
20 | import { sendUpdateVideoChannel } from '../../../lib/activitypub/send/send-update' | ||
21 | 21 | ||
22 | const videoChannelRouter = express.Router() | 22 | const videoChannelRouter = express.Router() |
23 | 23 | ||
@@ -30,7 +30,7 @@ videoChannelRouter.get('/channels', | |||
30 | ) | 30 | ) |
31 | 31 | ||
32 | videoChannelRouter.get('/accounts/:accountId/channels', | 32 | videoChannelRouter.get('/accounts/:accountId/channels', |
33 | listVideoAccountChannelsValidator, | 33 | asyncMiddleware(listVideoAccountChannelsValidator), |
34 | asyncMiddleware(listVideoAccountChannels) | 34 | asyncMiddleware(listVideoAccountChannels) |
35 | ) | 35 | ) |
36 | 36 | ||
@@ -42,18 +42,18 @@ videoChannelRouter.post('/channels', | |||
42 | 42 | ||
43 | videoChannelRouter.put('/channels/:id', | 43 | videoChannelRouter.put('/channels/:id', |
44 | authenticate, | 44 | authenticate, |
45 | videoChannelsUpdateValidator, | 45 | asyncMiddleware(videoChannelsUpdateValidator), |
46 | updateVideoChannelRetryWrapper | 46 | updateVideoChannelRetryWrapper |
47 | ) | 47 | ) |
48 | 48 | ||
49 | videoChannelRouter.delete('/channels/:id', | 49 | videoChannelRouter.delete('/channels/:id', |
50 | authenticate, | 50 | authenticate, |
51 | videoChannelsRemoveValidator, | 51 | asyncMiddleware(videoChannelsRemoveValidator), |
52 | asyncMiddleware(removeVideoChannelRetryWrapper) | 52 | asyncMiddleware(removeVideoChannelRetryWrapper) |
53 | ) | 53 | ) |
54 | 54 | ||
55 | videoChannelRouter.get('/channels/:id', | 55 | videoChannelRouter.get('/channels/:id', |
56 | videoChannelsGetValidator, | 56 | asyncMiddleware(videoChannelsGetValidator), |
57 | asyncMiddleware(getVideoChannel) | 57 | asyncMiddleware(getVideoChannel) |
58 | ) | 58 | ) |
59 | 59 | ||
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index 2b5afd632..244d91914 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts | |||
@@ -86,7 +86,7 @@ videosRouter.get('/', | |||
86 | ) | 86 | ) |
87 | videosRouter.put('/:id', | 87 | videosRouter.put('/:id', |
88 | authenticate, | 88 | authenticate, |
89 | videosUpdateValidator, | 89 | asyncMiddleware(videosUpdateValidator), |
90 | asyncMiddleware(updateVideoRetryWrapper) | 90 | asyncMiddleware(updateVideoRetryWrapper) |
91 | ) | 91 | ) |
92 | videosRouter.post('/upload', | 92 | videosRouter.post('/upload', |
@@ -97,17 +97,17 @@ videosRouter.post('/upload', | |||
97 | ) | 97 | ) |
98 | 98 | ||
99 | videosRouter.get('/:id/description', | 99 | videosRouter.get('/:id/description', |
100 | videosGetValidator, | 100 | asyncMiddleware(videosGetValidator), |
101 | asyncMiddleware(getVideoDescription) | 101 | asyncMiddleware(getVideoDescription) |
102 | ) | 102 | ) |
103 | videosRouter.get('/:id', | 103 | videosRouter.get('/:id', |
104 | videosGetValidator, | 104 | asyncMiddleware(videosGetValidator), |
105 | getVideo | 105 | getVideo |
106 | ) | 106 | ) |
107 | 107 | ||
108 | videosRouter.delete('/:id', | 108 | videosRouter.delete('/:id', |
109 | authenticate, | 109 | authenticate, |
110 | videosRemoveValidator, | 110 | asyncMiddleware(videosRemoveValidator), |
111 | asyncMiddleware(removeVideoRetryWrapper) | 111 | asyncMiddleware(removeVideoRetryWrapper) |
112 | ) | 112 | ) |
113 | 113 | ||
diff --git a/server/controllers/api/videos/rate.ts b/server/controllers/api/videos/rate.ts index 134284df7..0c6a988cf 100644 --- a/server/controllers/api/videos/rate.ts +++ b/server/controllers/api/videos/rate.ts | |||
@@ -12,7 +12,7 @@ const rateVideoRouter = express.Router() | |||
12 | 12 | ||
13 | rateVideoRouter.put('/:id/rate', | 13 | rateVideoRouter.put('/:id/rate', |
14 | authenticate, | 14 | authenticate, |
15 | videoRateValidator, | 15 | asyncMiddleware(videoRateValidator), |
16 | asyncMiddleware(rateVideoRetryWrapper) | 16 | asyncMiddleware(rateVideoRetryWrapper) |
17 | ) | 17 | ) |
18 | 18 | ||
diff --git a/server/controllers/services.ts b/server/controllers/services.ts index 0db6e5498..0c325678c 100644 --- a/server/controllers/services.ts +++ b/server/controllers/services.ts | |||
@@ -1,12 +1,16 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | 2 | ||
3 | import { CONFIG, PREVIEWS_SIZE, EMBED_SIZE } from '../initializers' | 3 | import { CONFIG, EMBED_SIZE, PREVIEWS_SIZE } from '../initializers' |
4 | import { oembedValidator } from '../middlewares' | 4 | import { oembedValidator } from '../middlewares' |
5 | import { asyncMiddleware } from '../middlewares/async' | ||
5 | import { VideoInstance } from '../models' | 6 | import { VideoInstance } from '../models' |
6 | 7 | ||
7 | const servicesRouter = express.Router() | 8 | const servicesRouter = express.Router() |
8 | 9 | ||
9 | servicesRouter.use('/oembed', oembedValidator, generateOEmbed) | 10 | servicesRouter.use('/oembed', |
11 | asyncMiddleware(oembedValidator), | ||
12 | generateOEmbed | ||
13 | ) | ||
10 | 14 | ||
11 | // --------------------------------------------------------------------------- | 15 | // --------------------------------------------------------------------------- |
12 | 16 | ||
diff --git a/server/controllers/webfinger.ts b/server/controllers/webfinger.ts index cc28a8909..1cea513a1 100644 --- a/server/controllers/webfinger.ts +++ b/server/controllers/webfinger.ts | |||
@@ -1,11 +1,12 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { asyncMiddleware } from '../middlewares/async' | ||
2 | import { webfingerValidator } from '../middlewares/validators/webfinger' | 3 | import { webfingerValidator } from '../middlewares/validators/webfinger' |
3 | import { AccountInstance } from '../models/account/account-interface' | 4 | import { AccountInstance } from '../models/account/account-interface' |
4 | 5 | ||
5 | const webfingerRouter = express.Router() | 6 | const webfingerRouter = express.Router() |
6 | 7 | ||
7 | webfingerRouter.get('/.well-known/webfinger', | 8 | webfingerRouter.get('/.well-known/webfinger', |
8 | webfingerValidator, | 9 | asyncMiddleware(webfingerValidator), |
9 | webfingerController | 10 | webfingerController |
10 | ) | 11 | ) |
11 | 12 | ||
diff --git a/server/helpers/custom-validators/accounts.ts b/server/helpers/custom-validators/accounts.ts index a6d7f2b82..e3c477414 100644 --- a/server/helpers/custom-validators/accounts.ts +++ b/server/helpers/custom-validators/accounts.ts | |||
@@ -1,17 +1,16 @@ | |||
1 | import * as Bluebird from 'bluebird' | 1 | import * as Bluebird from 'bluebird' |
2 | import * as express from 'express' | 2 | import { Response } from 'express' |
3 | import 'express-validator' | 3 | import 'express-validator' |
4 | import * as validator from 'validator' | 4 | import * as validator from 'validator' |
5 | import { database as db } from '../../initializers' | 5 | import { database as db } from '../../initializers' |
6 | import { AccountInstance } from '../../models' | 6 | import { AccountInstance } from '../../models' |
7 | import { logger } from '../logger' | ||
8 | import { isUserUsernameValid } from './users' | 7 | import { isUserUsernameValid } from './users' |
9 | 8 | ||
10 | function isAccountNameValid (value: string) { | 9 | function isAccountNameValid (value: string) { |
11 | return isUserUsernameValid(value) | 10 | return isUserUsernameValid(value) |
12 | } | 11 | } |
13 | 12 | ||
14 | function checkAccountIdExists (id: number | string, res: express.Response, callback: (err: Error, account: AccountInstance) => any) { | 13 | function isAccountIdExist (id: number | string, res: Response) { |
15 | let promise: Bluebird<AccountInstance> | 14 | let promise: Bluebird<AccountInstance> |
16 | 15 | ||
17 | if (validator.isInt('' + id)) { | 16 | if (validator.isInt('' + id)) { |
@@ -20,36 +19,35 @@ function checkAccountIdExists (id: number | string, res: express.Response, callb | |||
20 | promise = db.Account.loadByUUID('' + id) | 19 | promise = db.Account.loadByUUID('' + id) |
21 | } | 20 | } |
22 | 21 | ||
23 | return checkAccountExists(promise, res, callback) | 22 | return isAccountExist(promise, res) |
24 | } | 23 | } |
25 | 24 | ||
26 | function checkLocalAccountNameExists (name: string, res: express.Response, callback: (err: Error, account: AccountInstance) => any) { | 25 | function isLocalAccountNameExist (name: string, res: Response) { |
27 | const p = db.Account.loadLocalByName(name) | 26 | const promise = db.Account.loadLocalByName(name) |
28 | 27 | ||
29 | return checkAccountExists(p, res, callback) | 28 | return isAccountExist(promise, res) |
30 | } | 29 | } |
31 | 30 | ||
32 | function checkAccountExists (p: Bluebird<AccountInstance>, res: express.Response, callback: (err: Error, account: AccountInstance) => any) { | 31 | async function isAccountExist (p: Bluebird<AccountInstance>, res: Response) { |
33 | p.then(account => { | 32 | const account = await p |
34 | if (!account) { | 33 | |
35 | return res.status(404) | 34 | if (!account) { |
36 | .send({ error: 'Account not found' }) | 35 | res.status(404) |
37 | .end() | 36 | .send({ error: 'Account not found' }) |
38 | } | 37 | .end() |
39 | 38 | ||
40 | res.locals.account = account | 39 | return false |
41 | return callback(null, account) | 40 | } |
42 | }) | 41 | |
43 | .catch(err => { | 42 | res.locals.account = account |
44 | logger.error('Error in account request validator.', err) | 43 | |
45 | return res.sendStatus(500) | 44 | return true |
46 | }) | ||
47 | } | 45 | } |
48 | 46 | ||
49 | // --------------------------------------------------------------------------- | 47 | // --------------------------------------------------------------------------- |
50 | 48 | ||
51 | export { | 49 | export { |
52 | checkAccountIdExists, | 50 | isAccountIdExist, |
53 | checkLocalAccountNameExists, | 51 | isLocalAccountNameExist, |
54 | isAccountNameValid | 52 | isAccountNameValid |
55 | } | 53 | } |
diff --git a/server/helpers/custom-validators/activitypub/account.ts b/server/helpers/custom-validators/activitypub/account.ts index 645f55a5a..cab39a654 100644 --- a/server/helpers/custom-validators/activitypub/account.ts +++ b/server/helpers/custom-validators/activitypub/account.ts | |||
@@ -5,31 +5,19 @@ import { exists, isUUIDValid } from '../misc' | |||
5 | import { isActivityPubUrlValid, isBaseActivityValid } from './misc' | 5 | import { isActivityPubUrlValid, isBaseActivityValid } from './misc' |
6 | 6 | ||
7 | function isAccountEndpointsObjectValid (endpointObject: any) { | 7 | function isAccountEndpointsObjectValid (endpointObject: any) { |
8 | return isAccountSharedInboxValid(endpointObject.sharedInbox) | 8 | return isActivityPubUrlValid(endpointObject.sharedInbox) |
9 | } | ||
10 | |||
11 | function isAccountSharedInboxValid (sharedInbox: string) { | ||
12 | return isActivityPubUrlValid(sharedInbox) | ||
13 | } | 9 | } |
14 | 10 | ||
15 | function isAccountPublicKeyObjectValid (publicKeyObject: any) { | 11 | function isAccountPublicKeyObjectValid (publicKeyObject: any) { |
16 | return isAccountPublicKeyIdValid(publicKeyObject.id) && | 12 | return isActivityPubUrlValid(publicKeyObject.id) && |
17 | isAccountPublicKeyOwnerValid(publicKeyObject.owner) && | 13 | isActivityPubUrlValid(publicKeyObject.owner) && |
18 | isAccountPublicKeyValid(publicKeyObject.publicKeyPem) | 14 | isAccountPublicKeyValid(publicKeyObject.publicKeyPem) |
19 | } | 15 | } |
20 | 16 | ||
21 | function isAccountPublicKeyIdValid (id: string) { | ||
22 | return isActivityPubUrlValid(id) | ||
23 | } | ||
24 | |||
25 | function isAccountTypeValid (type: string) { | 17 | function isAccountTypeValid (type: string) { |
26 | return type === 'Person' || type === 'Application' | 18 | return type === 'Person' || type === 'Application' |
27 | } | 19 | } |
28 | 20 | ||
29 | function isAccountPublicKeyOwnerValid (owner: string) { | ||
30 | return isActivityPubUrlValid(owner) | ||
31 | } | ||
32 | |||
33 | function isAccountPublicKeyValid (publicKey: string) { | 21 | function isAccountPublicKeyValid (publicKey: string) { |
34 | return exists(publicKey) && | 22 | return exists(publicKey) && |
35 | typeof publicKey === 'string' && | 23 | typeof publicKey === 'string' && |
@@ -38,34 +26,10 @@ function isAccountPublicKeyValid (publicKey: string) { | |||
38 | validator.isLength(publicKey, CONSTRAINTS_FIELDS.ACCOUNTS.PUBLIC_KEY) | 26 | validator.isLength(publicKey, CONSTRAINTS_FIELDS.ACCOUNTS.PUBLIC_KEY) |
39 | } | 27 | } |
40 | 28 | ||
41 | function isAccountIdValid (id: string) { | ||
42 | return isActivityPubUrlValid(id) | ||
43 | } | ||
44 | |||
45 | function isAccountFollowingValid (id: string) { | ||
46 | return isActivityPubUrlValid(id) | ||
47 | } | ||
48 | |||
49 | function isAccountFollowersValid (id: string) { | ||
50 | return isActivityPubUrlValid(id) | ||
51 | } | ||
52 | |||
53 | function isAccountInboxValid (inbox: string) { | ||
54 | return isActivityPubUrlValid(inbox) | ||
55 | } | ||
56 | |||
57 | function isAccountOutboxValid (outbox: string) { | ||
58 | return isActivityPubUrlValid(outbox) | ||
59 | } | ||
60 | |||
61 | function isAccountPreferredUsernameValid (preferredUsername: string) { | 29 | function isAccountPreferredUsernameValid (preferredUsername: string) { |
62 | return isAccountNameValid(preferredUsername) | 30 | return isAccountNameValid(preferredUsername) |
63 | } | 31 | } |
64 | 32 | ||
65 | function isAccountUrlValid (url: string) { | ||
66 | return isActivityPubUrlValid(url) | ||
67 | } | ||
68 | |||
69 | function isAccountPrivateKeyValid (privateKey: string) { | 33 | function isAccountPrivateKeyValid (privateKey: string) { |
70 | return exists(privateKey) && | 34 | return exists(privateKey) && |
71 | typeof privateKey === 'string' && | 35 | typeof privateKey === 'string' && |
@@ -75,15 +39,15 @@ function isAccountPrivateKeyValid (privateKey: string) { | |||
75 | } | 39 | } |
76 | 40 | ||
77 | function isRemoteAccountValid (remoteAccount: any) { | 41 | function isRemoteAccountValid (remoteAccount: any) { |
78 | return isAccountIdValid(remoteAccount.id) && | 42 | return isActivityPubUrlValid(remoteAccount.id) && |
79 | isUUIDValid(remoteAccount.uuid) && | 43 | isUUIDValid(remoteAccount.uuid) && |
80 | isAccountTypeValid(remoteAccount.type) && | 44 | isAccountTypeValid(remoteAccount.type) && |
81 | isAccountFollowingValid(remoteAccount.following) && | 45 | isActivityPubUrlValid(remoteAccount.following) && |
82 | isAccountFollowersValid(remoteAccount.followers) && | 46 | isActivityPubUrlValid(remoteAccount.followers) && |
83 | isAccountInboxValid(remoteAccount.inbox) && | 47 | isActivityPubUrlValid(remoteAccount.inbox) && |
84 | isAccountOutboxValid(remoteAccount.outbox) && | 48 | isActivityPubUrlValid(remoteAccount.outbox) && |
85 | isAccountPreferredUsernameValid(remoteAccount.preferredUsername) && | 49 | isAccountPreferredUsernameValid(remoteAccount.preferredUsername) && |
86 | isAccountUrlValid(remoteAccount.url) && | 50 | isActivityPubUrlValid(remoteAccount.url) && |
87 | isAccountPublicKeyObjectValid(remoteAccount.publicKey) && | 51 | isAccountPublicKeyObjectValid(remoteAccount.publicKey) && |
88 | isAccountEndpointsObjectValid(remoteAccount.endpoints) | 52 | isAccountEndpointsObjectValid(remoteAccount.endpoints) |
89 | } | 53 | } |
@@ -113,19 +77,10 @@ function isAccountAcceptActivityValid (activity: any) { | |||
113 | 77 | ||
114 | export { | 78 | export { |
115 | isAccountEndpointsObjectValid, | 79 | isAccountEndpointsObjectValid, |
116 | isAccountSharedInboxValid, | ||
117 | isAccountPublicKeyObjectValid, | 80 | isAccountPublicKeyObjectValid, |
118 | isAccountPublicKeyIdValid, | ||
119 | isAccountTypeValid, | 81 | isAccountTypeValid, |
120 | isAccountPublicKeyOwnerValid, | ||
121 | isAccountPublicKeyValid, | 82 | isAccountPublicKeyValid, |
122 | isAccountIdValid, | ||
123 | isAccountFollowingValid, | ||
124 | isAccountFollowersValid, | ||
125 | isAccountInboxValid, | ||
126 | isAccountOutboxValid, | ||
127 | isAccountPreferredUsernameValid, | 83 | isAccountPreferredUsernameValid, |
128 | isAccountUrlValid, | ||
129 | isAccountPrivateKeyValid, | 84 | isAccountPrivateKeyValid, |
130 | isRemoteAccountValid, | 85 | isRemoteAccountValid, |
131 | isAccountFollowingCountValid, | 86 | isAccountFollowingCountValid, |
diff --git a/server/helpers/custom-validators/activitypub/videos.ts b/server/helpers/custom-validators/activitypub/videos.ts index 55e79c4e8..12c672fd2 100644 --- a/server/helpers/custom-validators/activitypub/videos.ts +++ b/server/helpers/custom-validators/activitypub/videos.ts | |||
@@ -8,7 +8,6 @@ import { | |||
8 | isVideoNSFWValid, | 8 | isVideoNSFWValid, |
9 | isVideoTagValid, | 9 | isVideoTagValid, |
10 | isVideoTruncatedDescriptionValid, | 10 | isVideoTruncatedDescriptionValid, |
11 | isVideoUrlValid, | ||
12 | isVideoViewsValid | 11 | isVideoViewsValid |
13 | } from '../videos' | 12 | } from '../videos' |
14 | import { isActivityPubUrlValid, isBaseActivityValid } from './misc' | 13 | import { isActivityPubUrlValid, isBaseActivityValid } from './misc' |
@@ -77,12 +76,11 @@ export { | |||
77 | function setValidRemoteTags (video: any) { | 76 | function setValidRemoteTags (video: any) { |
78 | if (Array.isArray(video.tag) === false) return false | 77 | if (Array.isArray(video.tag) === false) return false |
79 | 78 | ||
80 | const newTag = video.tag.filter(t => { | 79 | video.tag = video.tag.filter(t => { |
81 | return t.type === 'Hashtag' && | 80 | return t.type === 'Hashtag' && |
82 | isVideoTagValid(t.name) | 81 | isVideoTagValid(t.name) |
83 | }) | 82 | }) |
84 | 83 | ||
85 | video.tag = newTag | ||
86 | return true | 84 | return true |
87 | } | 85 | } |
88 | 86 | ||
@@ -96,7 +94,7 @@ function isRemoteVideoContentValid (mediaType: string, content: string) { | |||
96 | 94 | ||
97 | function isRemoteVideoIconValid (icon: any) { | 95 | function isRemoteVideoIconValid (icon: any) { |
98 | return icon.type === 'Image' && | 96 | return icon.type === 'Image' && |
99 | isVideoUrlValid(icon.url) && | 97 | isActivityPubUrlValid(icon.url) && |
100 | icon.mediaType === 'image/jpeg' && | 98 | icon.mediaType === 'image/jpeg' && |
101 | validator.isInt(icon.width + '', { min: 0 }) && | 99 | validator.isInt(icon.width + '', { min: 0 }) && |
102 | validator.isInt(icon.height + '', { min: 0 }) | 100 | validator.isInt(icon.height + '', { min: 0 }) |
@@ -105,8 +103,7 @@ function isRemoteVideoIconValid (icon: any) { | |||
105 | function setValidRemoteVideoUrls (video: any) { | 103 | function setValidRemoteVideoUrls (video: any) { |
106 | if (Array.isArray(video.url) === false) return false | 104 | if (Array.isArray(video.url) === false) return false |
107 | 105 | ||
108 | const newUrl = video.url.filter(u => isRemoteVideoUrlValid(u)) | 106 | video.url = video.url.filter(u => isRemoteVideoUrlValid(u)) |
109 | video.url = newUrl | ||
110 | 107 | ||
111 | return true | 108 | return true |
112 | } | 109 | } |
@@ -115,13 +112,13 @@ function isRemoteVideoUrlValid (url: any) { | |||
115 | return url.type === 'Link' && | 112 | return url.type === 'Link' && |
116 | ( | 113 | ( |
117 | ACTIVITY_PUB.URL_MIME_TYPES.VIDEO.indexOf(url.mimeType) !== -1 && | 114 | ACTIVITY_PUB.URL_MIME_TYPES.VIDEO.indexOf(url.mimeType) !== -1 && |
118 | isVideoUrlValid(url.url) && | 115 | isActivityPubUrlValid(url.url) && |
119 | validator.isInt(url.width + '', { min: 0 }) && | 116 | validator.isInt(url.width + '', { min: 0 }) && |
120 | validator.isInt(url.size + '', { min: 0 }) | 117 | validator.isInt(url.size + '', { min: 0 }) |
121 | ) || | 118 | ) || |
122 | ( | 119 | ( |
123 | ACTIVITY_PUB.URL_MIME_TYPES.TORRENT.indexOf(url.mimeType) !== -1 && | 120 | ACTIVITY_PUB.URL_MIME_TYPES.TORRENT.indexOf(url.mimeType) !== -1 && |
124 | isVideoUrlValid(url.url) && | 121 | isActivityPubUrlValid(url.url) && |
125 | validator.isInt(url.width + '', { min: 0 }) | 122 | validator.isInt(url.width + '', { min: 0 }) |
126 | ) || | 123 | ) || |
127 | ( | 124 | ( |
diff --git a/server/helpers/custom-validators/video-channels.ts b/server/helpers/custom-validators/video-channels.ts index 267d987fc..3de9f041b 100644 --- a/server/helpers/custom-validators/video-channels.ts +++ b/server/helpers/custom-validators/video-channels.ts | |||
@@ -1,21 +1,13 @@ | |||
1 | import * as Bluebird from 'bluebird' | ||
2 | import * as express from 'express' | 1 | import * as express from 'express' |
3 | import 'express-validator' | 2 | import 'express-validator' |
4 | import 'multer' | 3 | import 'multer' |
5 | import * as validator from 'validator' | 4 | import * as validator from 'validator' |
6 | |||
7 | import { CONSTRAINTS_FIELDS, database as db } from '../../initializers' | 5 | import { CONSTRAINTS_FIELDS, database as db } from '../../initializers' |
8 | import { VideoChannelInstance } from '../../models' | 6 | import { VideoChannelInstance } from '../../models' |
9 | import { logger } from '../logger' | ||
10 | import { isActivityPubUrlValid } from './index' | ||
11 | import { exists } from './misc' | 7 | import { exists } from './misc' |
12 | 8 | ||
13 | const VIDEO_CHANNELS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_CHANNELS | 9 | const VIDEO_CHANNELS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_CHANNELS |
14 | 10 | ||
15 | function isVideoChannelUrlValid (value: string) { | ||
16 | return isActivityPubUrlValid(value) | ||
17 | } | ||
18 | |||
19 | function isVideoChannelDescriptionValid (value: string) { | 11 | function isVideoChannelDescriptionValid (value: string) { |
20 | return value === null || validator.isLength(value, VIDEO_CHANNELS_CONSTRAINTS_FIELDS.DESCRIPTION) | 12 | return value === null || validator.isLength(value, VIDEO_CHANNELS_CONSTRAINTS_FIELDS.DESCRIPTION) |
21 | } | 13 | } |
@@ -24,31 +16,7 @@ function isVideoChannelNameValid (value: string) { | |||
24 | return exists(value) && validator.isLength(value, VIDEO_CHANNELS_CONSTRAINTS_FIELDS.NAME) | 16 | return exists(value) && validator.isLength(value, VIDEO_CHANNELS_CONSTRAINTS_FIELDS.NAME) |
25 | } | 17 | } |
26 | 18 | ||
27 | function checkVideoChannelExists (id: string, res: express.Response, callback: () => void) { | 19 | async function isVideoChannelExist (id: string, res: express.Response) { |
28 | let promise: Bluebird<VideoChannelInstance> | ||
29 | if (validator.isInt(id)) { | ||
30 | promise = db.VideoChannel.loadAndPopulateAccount(+id) | ||
31 | } else { // UUID | ||
32 | promise = db.VideoChannel.loadByUUIDAndPopulateAccount(id) | ||
33 | } | ||
34 | |||
35 | promise.then(videoChannel => { | ||
36 | if (!videoChannel) { | ||
37 | return res.status(404) | ||
38 | .json({ error: 'Video channel not found' }) | ||
39 | .end() | ||
40 | } | ||
41 | |||
42 | res.locals.videoChannel = videoChannel | ||
43 | callback() | ||
44 | }) | ||
45 | .catch(err => { | ||
46 | logger.error('Error in video channel request validator.', err) | ||
47 | return res.sendStatus(500) | ||
48 | }) | ||
49 | } | ||
50 | |||
51 | async function isVideoChannelExistsPromise (id: string, res: express.Response) { | ||
52 | let videoChannel: VideoChannelInstance | 20 | let videoChannel: VideoChannelInstance |
53 | if (validator.isInt(id)) { | 21 | if (validator.isInt(id)) { |
54 | videoChannel = await db.VideoChannel.loadAndPopulateAccount(+id) | 22 | videoChannel = await db.VideoChannel.loadAndPopulateAccount(+id) |
@@ -72,8 +40,6 @@ async function isVideoChannelExistsPromise (id: string, res: express.Response) { | |||
72 | 40 | ||
73 | export { | 41 | export { |
74 | isVideoChannelDescriptionValid, | 42 | isVideoChannelDescriptionValid, |
75 | checkVideoChannelExists, | ||
76 | isVideoChannelNameValid, | 43 | isVideoChannelNameValid, |
77 | isVideoChannelExistsPromise, | 44 | isVideoChannelExist |
78 | isVideoChannelUrlValid | ||
79 | } | 45 | } |
diff --git a/server/helpers/custom-validators/videos.ts b/server/helpers/custom-validators/videos.ts index 276354626..f13178c54 100644 --- a/server/helpers/custom-validators/videos.ts +++ b/server/helpers/custom-validators/videos.ts | |||
@@ -1,4 +1,3 @@ | |||
1 | import * as Bluebird from 'bluebird' | ||
2 | import { Response } from 'express' | 1 | import { Response } from 'express' |
3 | import 'express-validator' | 2 | import 'express-validator' |
4 | import { values } from 'lodash' | 3 | import { values } from 'lodash' |
@@ -6,12 +5,10 @@ import 'multer' | |||
6 | import * as validator from 'validator' | 5 | import * as validator from 'validator' |
7 | import { VideoRateType } from '../../../shared' | 6 | import { VideoRateType } from '../../../shared' |
8 | import { CONSTRAINTS_FIELDS, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_RATE_TYPES } from '../../initializers' | 7 | import { CONSTRAINTS_FIELDS, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_RATE_TYPES } from '../../initializers' |
8 | import { VIDEO_PRIVACIES } from '../../initializers/constants' | ||
9 | import { database as db } from '../../initializers/database' | 9 | import { database as db } from '../../initializers/database' |
10 | import { VideoInstance } from '../../models/video/video-interface' | 10 | import { VideoInstance } from '../../models/video/video-interface' |
11 | import { logger } from '../logger' | ||
12 | import { isActivityPubUrlValid } from './activitypub/misc' | ||
13 | import { exists, isArray } from './misc' | 11 | import { exists, isArray } from './misc' |
14 | import { VIDEO_PRIVACIES } from '../../initializers/constants' | ||
15 | 12 | ||
16 | const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS | 13 | const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS |
17 | const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES | 14 | const VIDEO_ABUSES_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_ABUSES |
@@ -20,10 +17,6 @@ function isVideoCategoryValid (value: number) { | |||
20 | return VIDEO_CATEGORIES[value] !== undefined | 17 | return VIDEO_CATEGORIES[value] !== undefined |
21 | } | 18 | } |
22 | 19 | ||
23 | function isVideoUrlValid (value: string) { | ||
24 | return isActivityPubUrlValid(value) | ||
25 | } | ||
26 | |||
27 | function isVideoLicenceValid (value: number) { | 20 | function isVideoLicenceValid (value: number) { |
28 | return VIDEO_LICENCES[value] !== undefined | 21 | return VIDEO_LICENCES[value] !== undefined |
29 | } | 22 | } |
@@ -106,31 +99,7 @@ function isVideoFileSizeValid (value: string) { | |||
106 | return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE) | 99 | return exists(value) && validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.FILE_SIZE) |
107 | } | 100 | } |
108 | 101 | ||
109 | function checkVideoExists (id: string, res: Response, callback: () => void) { | 102 | async function isVideoExist (id: string, res: Response) { |
110 | let promise: Bluebird<VideoInstance> | ||
111 | if (validator.isInt(id)) { | ||
112 | promise = db.Video.loadAndPopulateAccountAndServerAndTags(+id) | ||
113 | } else { // UUID | ||
114 | promise = db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(id) | ||
115 | } | ||
116 | |||
117 | promise.then(video => { | ||
118 | if (!video) { | ||
119 | return res.status(404) | ||
120 | .json({ error: 'Video not found' }) | ||
121 | .end() | ||
122 | } | ||
123 | |||
124 | res.locals.video = video | ||
125 | callback() | ||
126 | }) | ||
127 | .catch(err => { | ||
128 | logger.error('Error in video request validator.', err) | ||
129 | return res.sendStatus(500) | ||
130 | }) | ||
131 | } | ||
132 | |||
133 | async function isVideoExistsPromise (id: string, res: Response) { | ||
134 | let video: VideoInstance | 103 | let video: VideoInstance |
135 | 104 | ||
136 | if (validator.isInt(id)) { | 105 | if (validator.isInt(id)) { |
@@ -169,10 +138,8 @@ export { | |||
169 | isVideoRatingTypeValid, | 138 | isVideoRatingTypeValid, |
170 | isVideoDurationValid, | 139 | isVideoDurationValid, |
171 | isVideoTagValid, | 140 | isVideoTagValid, |
172 | isVideoUrlValid, | ||
173 | isVideoPrivacyValid, | 141 | isVideoPrivacyValid, |
174 | isVideoFileResolutionValid, | 142 | isVideoFileResolutionValid, |
175 | isVideoFileSizeValid, | 143 | isVideoFileSizeValid, |
176 | checkVideoExists, | 144 | isVideoExist |
177 | isVideoExistsPromise | ||
178 | } | 145 | } |
diff --git a/server/middlewares/async.ts b/server/middlewares/async.ts index 9692f9be7..534891899 100644 --- a/server/middlewares/async.ts +++ b/server/middlewares/async.ts | |||
@@ -1,9 +1,12 @@ | |||
1 | import { Request, Response, NextFunction, RequestHandler } from 'express' | ||
2 | import { eachSeries } from 'async' | 1 | import { eachSeries } from 'async' |
2 | import { NextFunction, Request, RequestHandler, Response } from 'express' | ||
3 | 3 | ||
4 | // Syntactic sugar to avoid try/catch in express controllers | 4 | // Syntactic sugar to avoid try/catch in express controllers |
5 | // Thanks: https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016 | 5 | // Thanks: https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016 |
6 | function asyncMiddleware (fun: RequestHandler | RequestHandler[]) { | 6 | |
7 | export type RequestPromiseHandler = (req: Request, res: Response, next: NextFunction) => Promise<any> | ||
8 | |||
9 | function asyncMiddleware (fun: RequestPromiseHandler | RequestPromiseHandler[]) { | ||
7 | return (req: Request, res: Response, next: NextFunction) => { | 10 | return (req: Request, res: Response, next: NextFunction) => { |
8 | if (Array.isArray(fun) === true) { | 11 | if (Array.isArray(fun) === true) { |
9 | return eachSeries(fun as RequestHandler[], (f, cb) => { | 12 | return eachSeries(fun as RequestHandler[], (f, cb) => { |
diff --git a/server/middlewares/validators/account.ts b/server/middlewares/validators/account.ts index 47ed6a7bb..70f4e4d3b 100644 --- a/server/middlewares/validators/account.ts +++ b/server/middlewares/validators/account.ts | |||
@@ -1,18 +1,19 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { param } from 'express-validator/check' | 2 | import { param } from 'express-validator/check' |
3 | import { logger } from '../../helpers' | 3 | import { logger, isLocalAccountNameExist } from '../../helpers' |
4 | import { checkLocalAccountNameExists, isAccountNameValid } from '../../helpers/custom-validators/accounts' | 4 | import { isAccountNameValid } from '../../helpers/custom-validators/accounts' |
5 | import { checkErrors } from './utils' | 5 | import { areValidationErrors } from './utils' |
6 | 6 | ||
7 | const localAccountValidator = [ | 7 | const localAccountValidator = [ |
8 | param('name').custom(isAccountNameValid).withMessage('Should have a valid account name'), | 8 | param('name').custom(isAccountNameValid).withMessage('Should have a valid account name'), |
9 | 9 | ||
10 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 10 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
11 | logger.debug('Checking localAccountValidator parameters', { parameters: req.params }) | 11 | logger.debug('Checking localAccountValidator parameters', { parameters: req.params }) |
12 | 12 | ||
13 | checkErrors(req, res, () => { | 13 | if (areValidationErrors(req, res)) return |
14 | checkLocalAccountNameExists(req.params.name, res, next) | 14 | if (!await isLocalAccountNameExist(req.params.name, res)) return |
15 | }) | 15 | |
16 | return next() | ||
16 | } | 17 | } |
17 | ] | 18 | ] |
18 | 19 | ||
diff --git a/server/middlewares/validators/activitypub/activity.ts b/server/middlewares/validators/activitypub/activity.ts index 0de8b2d85..8aa82298c 100644 --- a/server/middlewares/validators/activitypub/activity.ts +++ b/server/middlewares/validators/activitypub/activity.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { body } from 'express-validator/check' | 2 | import { body } from 'express-validator/check' |
3 | import { isRootActivityValid, logger } from '../../../helpers' | 3 | import { isRootActivityValid, logger } from '../../../helpers' |
4 | import { checkErrors } from '../utils' | 4 | import { areValidationErrors } from '../utils' |
5 | 5 | ||
6 | const activityPubValidator = [ | 6 | const activityPubValidator = [ |
7 | body('').custom((value, { req }) => isRootActivityValid(req.body)), | 7 | body('').custom((value, { req }) => isRootActivityValid(req.body)), |
@@ -9,7 +9,9 @@ const activityPubValidator = [ | |||
9 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 9 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
10 | logger.debug('Checking activity pub parameters', { parameters: req.body }) | 10 | logger.debug('Checking activity pub parameters', { parameters: req.body }) |
11 | 11 | ||
12 | checkErrors(req, res, next) | 12 | if (areValidationErrors(req, res)) return |
13 | |||
14 | return next() | ||
13 | } | 15 | } |
14 | ] | 16 | ] |
15 | 17 | ||
diff --git a/server/middlewares/validators/activitypub/signature.ts b/server/middlewares/validators/activitypub/signature.ts index 0ce15c1f6..360685512 100644 --- a/server/middlewares/validators/activitypub/signature.ts +++ b/server/middlewares/validators/activitypub/signature.ts | |||
@@ -1,14 +1,7 @@ | |||
1 | import { body } from 'express-validator/check' | ||
2 | import * as express from 'express' | 1 | import * as express from 'express' |
3 | 2 | import { body } from 'express-validator/check' | |
4 | import { | 3 | import { isDateValid, isSignatureCreatorValid, isSignatureTypeValid, isSignatureValueValid, logger } from '../../../helpers' |
5 | logger, | 4 | import { areValidationErrors } from '../utils' |
6 | isDateValid, | ||
7 | isSignatureTypeValid, | ||
8 | isSignatureCreatorValid, | ||
9 | isSignatureValueValid | ||
10 | } from '../../../helpers' | ||
11 | import { checkErrors } from '../utils' | ||
12 | 5 | ||
13 | const signatureValidator = [ | 6 | const signatureValidator = [ |
14 | body('signature.type').custom(isSignatureTypeValid).withMessage('Should have a valid signature type'), | 7 | body('signature.type').custom(isSignatureTypeValid).withMessage('Should have a valid signature type'), |
@@ -19,7 +12,9 @@ const signatureValidator = [ | |||
19 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 12 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
20 | logger.debug('Checking activitypub signature parameter', { parameters: { signature: req.body.signature } }) | 13 | logger.debug('Checking activitypub signature parameter', { parameters: { signature: req.body.signature } }) |
21 | 14 | ||
22 | checkErrors(req, res, next) | 15 | if (areValidationErrors(req, res)) return |
16 | |||
17 | return next() | ||
23 | } | 18 | } |
24 | ] | 19 | ] |
25 | 20 | ||
diff --git a/server/middlewares/validators/follows.ts b/server/middlewares/validators/follows.ts index ddc4c1de1..605872ecf 100644 --- a/server/middlewares/validators/follows.ts +++ b/server/middlewares/validators/follows.ts | |||
@@ -4,7 +4,7 @@ import { isTestInstance } from '../../helpers/core-utils' | |||
4 | import { isEachUniqueHostValid } from '../../helpers/custom-validators/servers' | 4 | import { isEachUniqueHostValid } from '../../helpers/custom-validators/servers' |
5 | import { logger } from '../../helpers/logger' | 5 | import { logger } from '../../helpers/logger' |
6 | import { CONFIG, database as db } from '../../initializers' | 6 | import { CONFIG, database as db } from '../../initializers' |
7 | import { checkErrors } from './utils' | 7 | import { areValidationErrors } from './utils' |
8 | import { getServerAccount } from '../../helpers/utils' | 8 | import { getServerAccount } from '../../helpers/utils' |
9 | import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' | 9 | import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' |
10 | 10 | ||
@@ -23,34 +23,30 @@ const followValidator = [ | |||
23 | 23 | ||
24 | logger.debug('Checking follow parameters', { parameters: req.body }) | 24 | logger.debug('Checking follow parameters', { parameters: req.body }) |
25 | 25 | ||
26 | checkErrors(req, res, next) | 26 | if (areValidationErrors(req, res)) return |
27 | |||
28 | return next() | ||
27 | } | 29 | } |
28 | ] | 30 | ] |
29 | 31 | ||
30 | const removeFollowingValidator = [ | 32 | const removeFollowingValidator = [ |
31 | param('accountId').custom(isIdOrUUIDValid).withMessage('Should have a valid account id'), | 33 | param('accountId').custom(isIdOrUUIDValid).withMessage('Should have a valid account id'), |
32 | 34 | ||
33 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 35 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
34 | logger.debug('Checking unfollow parameters', { parameters: req.params }) | 36 | logger.debug('Checking unfollow parameters', { parameters: req.params }) |
35 | 37 | ||
36 | checkErrors(req, res, async () => { | 38 | if (areValidationErrors(req, res)) return |
37 | try { | ||
38 | const serverAccount = await getServerAccount() | ||
39 | const follow = await db.AccountFollow.loadByAccountAndTarget(serverAccount.id, req.params.accountId) | ||
40 | 39 | ||
41 | if (!follow) { | 40 | const serverAccount = await getServerAccount() |
42 | return res.status(404) | 41 | const follow = await db.AccountFollow.loadByAccountAndTarget(serverAccount.id, req.params.accountId) |
43 | .end() | ||
44 | } | ||
45 | 42 | ||
46 | res.locals.follow = follow | 43 | if (!follow) { |
44 | return res.status(404) | ||
45 | .end() | ||
46 | } | ||
47 | 47 | ||
48 | return next() | 48 | res.locals.follow = follow |
49 | } catch (err) { | 49 | return next() |
50 | logger.error('Error in remove following validator.', err) | ||
51 | return res.sendStatus(500) | ||
52 | } | ||
53 | }) | ||
54 | } | 50 | } |
55 | ] | 51 | ] |
56 | 52 | ||
diff --git a/server/middlewares/validators/oembed.ts b/server/middlewares/validators/oembed.ts index f8e34d2d4..31f06dc65 100644 --- a/server/middlewares/validators/oembed.ts +++ b/server/middlewares/validators/oembed.ts | |||
@@ -1,15 +1,10 @@ | |||
1 | import { query } from 'express-validator/check' | ||
2 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { query } from 'express-validator/check' | ||
3 | import { join } from 'path' | 3 | import { join } from 'path' |
4 | 4 | import { isIdOrUUIDValid, isTestInstance, logger } from '../../helpers' | |
5 | import { checkErrors } from './utils' | ||
6 | import { CONFIG } from '../../initializers' | 5 | import { CONFIG } from '../../initializers' |
7 | import { | 6 | import { areValidationErrors } from './utils' |
8 | logger, | 7 | import { isVideoExist } from '../../helpers/custom-validators/videos' |
9 | isTestInstance, | ||
10 | checkVideoExists, | ||
11 | isIdOrUUIDValid | ||
12 | } from '../../helpers' | ||
13 | 8 | ||
14 | const urlShouldStartWith = CONFIG.WEBSERVER.SCHEME + '://' + join(CONFIG.WEBSERVER.HOST, 'videos', 'watch') + '/' | 9 | const urlShouldStartWith = CONFIG.WEBSERVER.SCHEME + '://' + join(CONFIG.WEBSERVER.HOST, 'videos', 'watch') + '/' |
15 | const videoWatchRegex = new RegExp('([^/]+)$') | 10 | const videoWatchRegex = new RegExp('([^/]+)$') |
@@ -29,33 +24,35 @@ const oembedValidator = [ | |||
29 | query('maxheight').optional().isInt().withMessage('Should have a valid max height'), | 24 | query('maxheight').optional().isInt().withMessage('Should have a valid max height'), |
30 | query('format').optional().isIn([ 'xml', 'json' ]).withMessage('Should have a valid format'), | 25 | query('format').optional().isIn([ 'xml', 'json' ]).withMessage('Should have a valid format'), |
31 | 26 | ||
32 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 27 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
33 | logger.debug('Checking oembed parameters', { parameters: req.query }) | 28 | logger.debug('Checking oembed parameters', { parameters: req.query }) |
34 | 29 | ||
35 | checkErrors(req, res, () => { | 30 | if (areValidationErrors(req, res)) return |
36 | if (req.query.format !== undefined && req.query.format !== 'json') { | 31 | |
37 | return res.status(501) | 32 | if (req.query.format !== undefined && req.query.format !== 'json') { |
38 | .json({ error: 'Requested format is not implemented on server.' }) | 33 | return res.status(501) |
39 | .end() | 34 | .json({ error: 'Requested format is not implemented on server.' }) |
40 | } | 35 | .end() |
36 | } | ||
37 | |||
38 | const startIsOk = req.query.url.startsWith(urlShouldStartWith) | ||
39 | const matches = videoWatchRegex.exec(req.query.url) | ||
40 | if (startIsOk === false || matches === null) { | ||
41 | return res.status(400) | ||
42 | .json({ error: 'Invalid url.' }) | ||
43 | .end() | ||
44 | } | ||
41 | 45 | ||
42 | const startIsOk = req.query.url.startsWith(urlShouldStartWith) | 46 | const videoId = matches[1] |
43 | const matches = videoWatchRegex.exec(req.query.url) | 47 | if (isIdOrUUIDValid(videoId) === false) { |
44 | if (startIsOk === false || matches === null) { | 48 | return res.status(400) |
45 | return res.status(400) | 49 | .json({ error: 'Invalid video id.' }) |
46 | .json({ error: 'Invalid url.' }) | 50 | .end() |
47 | .end() | 51 | } |
48 | } | ||
49 | 52 | ||
50 | const videoId = matches[1] | 53 | if (!await isVideoExist(videoId, res)) return |
51 | if (isIdOrUUIDValid(videoId) === false) { | ||
52 | return res.status(400) | ||
53 | .json({ error: 'Invalid video id.' }) | ||
54 | .end() | ||
55 | } | ||
56 | 54 | ||
57 | checkVideoExists(videoId, res, next) | 55 | return next() |
58 | }) | ||
59 | } | 56 | } |
60 | ] | 57 | ] |
61 | 58 | ||
diff --git a/server/middlewares/validators/pagination.ts b/server/middlewares/validators/pagination.ts index a5a542cdf..0895b4eb8 100644 --- a/server/middlewares/validators/pagination.ts +++ b/server/middlewares/validators/pagination.ts | |||
@@ -1,8 +1,7 @@ | |||
1 | import { query } from 'express-validator/check' | ||
2 | import * as express from 'express' | 1 | import * as express from 'express' |
3 | 2 | import { query } from 'express-validator/check' | |
4 | import { checkErrors } from './utils' | ||
5 | import { logger } from '../../helpers' | 3 | import { logger } from '../../helpers' |
4 | import { areValidationErrors } from './utils' | ||
6 | 5 | ||
7 | const paginationValidator = [ | 6 | const paginationValidator = [ |
8 | query('start').optional().isInt().withMessage('Should have a number start'), | 7 | query('start').optional().isInt().withMessage('Should have a number start'), |
@@ -11,7 +10,9 @@ const paginationValidator = [ | |||
11 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 10 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
12 | logger.debug('Checking pagination parameters', { parameters: req.query }) | 11 | logger.debug('Checking pagination parameters', { parameters: req.query }) |
13 | 12 | ||
14 | checkErrors(req, res, next) | 13 | if (areValidationErrors(req, res)) return |
14 | |||
15 | return next() | ||
15 | } | 16 | } |
16 | ] | 17 | ] |
17 | 18 | ||
diff --git a/server/middlewares/validators/sort.ts b/server/middlewares/validators/sort.ts index 6fea41bb8..636f68885 100644 --- a/server/middlewares/validators/sort.ts +++ b/server/middlewares/validators/sort.ts | |||
@@ -1,9 +1,9 @@ | |||
1 | import { query } from 'express-validator/check' | 1 | import { query } from 'express-validator/check' |
2 | import * as express from 'express' | 2 | import * as express from 'express' |
3 | 3 | ||
4 | import { checkErrors } from './utils' | ||
5 | import { logger } from '../../helpers' | 4 | import { logger } from '../../helpers' |
6 | import { SORTABLE_COLUMNS } from '../../initializers' | 5 | import { SORTABLE_COLUMNS } from '../../initializers' |
6 | import { areValidationErrors } from './utils' | ||
7 | 7 | ||
8 | // Initialize constants here for better performances | 8 | // Initialize constants here for better performances |
9 | const SORTABLE_USERS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.USERS) | 9 | const SORTABLE_USERS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.USERS) |
@@ -43,7 +43,9 @@ function checkSort (sortableColumns: string[]) { | |||
43 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 43 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
44 | logger.debug('Checking sort parameters', { parameters: req.query }) | 44 | logger.debug('Checking sort parameters', { parameters: req.query }) |
45 | 45 | ||
46 | checkErrors(req, res, next) | 46 | if (areValidationErrors(req, res)) return |
47 | |||
48 | return next() | ||
47 | } | 49 | } |
48 | ] | 50 | ] |
49 | } | 51 | } |
diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts index 6b845f62b..ac7435b7d 100644 --- a/server/middlewares/validators/users.ts +++ b/server/middlewares/validators/users.ts | |||
@@ -1,22 +1,19 @@ | |||
1 | import { body, param } from 'express-validator/check' | ||
2 | import 'express-validator' | ||
3 | import * as express from 'express' | 1 | import * as express from 'express' |
4 | import * as Promise from 'bluebird' | 2 | import 'express-validator' |
5 | import * as validator from 'validator' | 3 | import { body, param } from 'express-validator/check' |
6 | |||
7 | import { database as db } from '../../initializers/database' | ||
8 | import { checkErrors } from './utils' | ||
9 | import { | 4 | import { |
5 | isIdOrUUIDValid, | ||
10 | isSignupAllowed, | 6 | isSignupAllowed, |
11 | logger, | 7 | isUserDisplayNSFWValid, |
12 | isUserUsernameValid, | ||
13 | isUserPasswordValid, | 8 | isUserPasswordValid, |
9 | isUserRoleValid, | ||
10 | isUserUsernameValid, | ||
14 | isUserVideoQuotaValid, | 11 | isUserVideoQuotaValid, |
15 | isUserDisplayNSFWValid, | 12 | logger |
16 | isIdOrUUIDValid, | ||
17 | isUserRoleValid | ||
18 | } from '../../helpers' | 13 | } from '../../helpers' |
19 | import { UserInstance, VideoInstance } from '../../models' | 14 | import { isVideoExist } from '../../helpers/custom-validators/videos' |
15 | import { database as db } from '../../initializers/database' | ||
16 | import { areValidationErrors } from './utils' | ||
20 | 17 | ||
21 | const usersAddValidator = [ | 18 | const usersAddValidator = [ |
22 | body('username').custom(isUserUsernameValid).withMessage('Should have a valid username (lowercase alphanumeric characters)'), | 19 | body('username').custom(isUserUsernameValid).withMessage('Should have a valid username (lowercase alphanumeric characters)'), |
@@ -25,12 +22,13 @@ const usersAddValidator = [ | |||
25 | body('videoQuota').custom(isUserVideoQuotaValid).withMessage('Should have a valid user quota'), | 22 | body('videoQuota').custom(isUserVideoQuotaValid).withMessage('Should have a valid user quota'), |
26 | body('role').custom(isUserRoleValid).withMessage('Should have a valid role'), | 23 | body('role').custom(isUserRoleValid).withMessage('Should have a valid role'), |
27 | 24 | ||
28 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 25 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
29 | logger.debug('Checking usersAdd parameters', { parameters: req.body }) | 26 | logger.debug('Checking usersAdd parameters', { parameters: req.body }) |
30 | 27 | ||
31 | checkErrors(req, res, () => { | 28 | if (areValidationErrors(req, res)) return |
32 | checkUserDoesNotAlreadyExist(req.body.username, req.body.email, res, next) | 29 | if (!await checkUserNameOrEmailDoesNotAlreadyExist(req.body.username, req.body.email, res)) return |
33 | }) | 30 | |
31 | return next() | ||
34 | } | 32 | } |
35 | ] | 33 | ] |
36 | 34 | ||
@@ -39,37 +37,33 @@ const usersRegisterValidator = [ | |||
39 | body('password').custom(isUserPasswordValid).withMessage('Should have a valid password'), | 37 | body('password').custom(isUserPasswordValid).withMessage('Should have a valid password'), |
40 | body('email').isEmail().withMessage('Should have a valid email'), | 38 | body('email').isEmail().withMessage('Should have a valid email'), |
41 | 39 | ||
42 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 40 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
43 | logger.debug('Checking usersRegister parameters', { parameters: req.body }) | 41 | logger.debug('Checking usersRegister parameters', { parameters: req.body }) |
44 | 42 | ||
45 | checkErrors(req, res, () => { | 43 | if (areValidationErrors(req, res)) return |
46 | checkUserDoesNotAlreadyExist(req.body.username, req.body.email, res, next) | 44 | if (!await checkUserNameOrEmailDoesNotAlreadyExist(req.body.username, req.body.email, res)) return |
47 | }) | 45 | |
46 | return next() | ||
48 | } | 47 | } |
49 | ] | 48 | ] |
50 | 49 | ||
51 | const usersRemoveValidator = [ | 50 | const usersRemoveValidator = [ |
52 | param('id').isInt().not().isEmpty().withMessage('Should have a valid id'), | 51 | param('id').isInt().not().isEmpty().withMessage('Should have a valid id'), |
53 | 52 | ||
54 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 53 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
55 | logger.debug('Checking usersRemove parameters', { parameters: req.params }) | 54 | logger.debug('Checking usersRemove parameters', { parameters: req.params }) |
56 | 55 | ||
57 | checkErrors(req, res, () => { | 56 | if (areValidationErrors(req, res)) return |
58 | checkUserExists(req.params.id, res, (err, user) => { | 57 | if (!await checkUserIdExist(req.params.id, res)) return |
59 | if (err) { | 58 | |
60 | logger.error('Error in usersRemoveValidator.', err) | 59 | const user = res.locals.user |
61 | return res.sendStatus(500) | 60 | if (user.username === 'root') { |
62 | } | 61 | return res.status(400) |
63 | 62 | .send({ error: 'Cannot remove the root user' }) | |
64 | if (user.username === 'root') { | 63 | .end() |
65 | return res.status(400) | 64 | } |
66 | .send({ error: 'Cannot remove the root user' }) | 65 | |
67 | .end() | 66 | return next() |
68 | } | ||
69 | |||
70 | return next() | ||
71 | }) | ||
72 | }) | ||
73 | } | 67 | } |
74 | ] | 68 | ] |
75 | 69 | ||
@@ -79,12 +73,13 @@ const usersUpdateValidator = [ | |||
79 | body('videoQuota').optional().custom(isUserVideoQuotaValid).withMessage('Should have a valid user quota'), | 73 | body('videoQuota').optional().custom(isUserVideoQuotaValid).withMessage('Should have a valid user quota'), |
80 | body('role').optional().custom(isUserRoleValid).withMessage('Should have a valid role'), | 74 | body('role').optional().custom(isUserRoleValid).withMessage('Should have a valid role'), |
81 | 75 | ||
82 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 76 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
83 | logger.debug('Checking usersUpdate parameters', { parameters: req.body }) | 77 | logger.debug('Checking usersUpdate parameters', { parameters: req.body }) |
84 | 78 | ||
85 | checkErrors(req, res, () => { | 79 | if (areValidationErrors(req, res)) return |
86 | checkUserExists(req.params.id, res, next) | 80 | if (!await checkUserIdExist(req.params.id, res)) return |
87 | }) | 81 | |
82 | return next() | ||
88 | } | 83 | } |
89 | ] | 84 | ] |
90 | 85 | ||
@@ -97,64 +92,48 @@ const usersUpdateMeValidator = [ | |||
97 | // TODO: Add old password verification | 92 | // TODO: Add old password verification |
98 | logger.debug('Checking usersUpdateMe parameters', { parameters: req.body }) | 93 | logger.debug('Checking usersUpdateMe parameters', { parameters: req.body }) |
99 | 94 | ||
100 | checkErrors(req, res, next) | 95 | if (areValidationErrors(req, res)) return |
96 | |||
97 | return next() | ||
101 | } | 98 | } |
102 | ] | 99 | ] |
103 | 100 | ||
104 | const usersGetValidator = [ | 101 | const usersGetValidator = [ |
105 | param('id').isInt().not().isEmpty().withMessage('Should have a valid id'), | 102 | param('id').isInt().not().isEmpty().withMessage('Should have a valid id'), |
106 | 103 | ||
107 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 104 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
108 | checkErrors(req, res, () => { | 105 | logger.debug('Checking usersGet parameters', { parameters: req.body }) |
109 | checkUserExists(req.params.id, res, next) | 106 | |
110 | }) | 107 | if (areValidationErrors(req, res)) return |
108 | if (!await checkUserIdExist(req.params.id, res)) return | ||
109 | |||
110 | return next() | ||
111 | } | 111 | } |
112 | ] | 112 | ] |
113 | 113 | ||
114 | const usersVideoRatingValidator = [ | 114 | const usersVideoRatingValidator = [ |
115 | param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'), | 115 | param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'), |
116 | 116 | ||
117 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 117 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
118 | logger.debug('Checking usersVideoRating parameters', { parameters: req.params }) | 118 | logger.debug('Checking usersVideoRating parameters', { parameters: req.params }) |
119 | 119 | ||
120 | checkErrors(req, res, () => { | 120 | if (areValidationErrors(req, res)) return |
121 | let videoPromise: Promise<VideoInstance> | 121 | if (!await isVideoExist(req.params.videoId, res)) return |
122 | 122 | ||
123 | if (validator.isUUID(req.params.videoId)) { | 123 | return next() |
124 | videoPromise = db.Video.loadByUUID(req.params.videoId) | ||
125 | } else { | ||
126 | videoPromise = db.Video.load(req.params.videoId) | ||
127 | } | ||
128 | |||
129 | videoPromise | ||
130 | .then(video => { | ||
131 | if (!video) { | ||
132 | return res.status(404) | ||
133 | .json({ error: 'Video not found' }) | ||
134 | .end() | ||
135 | } | ||
136 | |||
137 | return next() | ||
138 | }) | ||
139 | .catch(err => { | ||
140 | logger.error('Error in user request validator.', err) | ||
141 | return res.sendStatus(500) | ||
142 | }) | ||
143 | }) | ||
144 | } | 124 | } |
145 | ] | 125 | ] |
146 | 126 | ||
147 | const ensureUserRegistrationAllowed = [ | 127 | const ensureUserRegistrationAllowed = [ |
148 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 128 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
149 | isSignupAllowed().then(allowed => { | 129 | const allowed = await isSignupAllowed() |
150 | if (allowed === false) { | 130 | if (allowed === false) { |
151 | return res.status(403) | 131 | return res.status(403) |
152 | .send({ error: 'User registration is not enabled or user limit is reached.' }) | 132 | .send({ error: 'User registration is not enabled or user limit is reached.' }) |
153 | .end() | 133 | .end() |
154 | } | 134 | } |
155 | 135 | ||
156 | return next() | 136 | return next() |
157 | }) | ||
158 | } | 137 | } |
159 | ] | 138 | ] |
160 | 139 | ||
@@ -173,37 +152,30 @@ export { | |||
173 | 152 | ||
174 | // --------------------------------------------------------------------------- | 153 | // --------------------------------------------------------------------------- |
175 | 154 | ||
176 | function checkUserExists (id: number, res: express.Response, callback: (err: Error, user: UserInstance) => void) { | 155 | async function checkUserIdExist (id: number, res: express.Response) { |
177 | db.User.loadById(id) | 156 | const user = await db.User.loadById(id) |
178 | .then(user => { | 157 | |
179 | if (!user) { | 158 | if (!user) { |
180 | return res.status(404) | 159 | res.status(404) |
181 | .send({ error: 'User not found' }) | 160 | .send({ error: 'User not found' }) |
182 | .end() | 161 | .end() |
183 | } | 162 | |
184 | 163 | return false | |
185 | res.locals.user = user | 164 | } |
186 | return callback(null, user) | 165 | |
187 | }) | 166 | res.locals.user = user |
188 | .catch(err => { | 167 | return true |
189 | logger.error('Error in user request validator.', err) | ||
190 | return res.sendStatus(500) | ||
191 | }) | ||
192 | } | 168 | } |
193 | 169 | ||
194 | function checkUserDoesNotAlreadyExist (username: string, email: string, res: express.Response, callback: () => void) { | 170 | async function checkUserNameOrEmailDoesNotAlreadyExist (username: string, email: string, res: express.Response) { |
195 | db.User.loadByUsernameOrEmail(username, email) | 171 | const user = await db.User.loadByUsernameOrEmail(username, email) |
196 | .then(user => { | 172 | |
197 | if (user) { | 173 | if (user) { |
198 | return res.status(409) | 174 | res.status(409) |
199 | .send({ error: 'User with this username of email already exists.' }) | 175 | .send({ error: 'User with this username of email already exists.' }) |
200 | .end() | 176 | .end() |
201 | } | 177 | return false |
202 | 178 | } | |
203 | return callback() | 179 | |
204 | }) | 180 | return true |
205 | .catch(err => { | ||
206 | logger.error('Error in usersAdd request validator.', err) | ||
207 | return res.sendStatus(500) | ||
208 | }) | ||
209 | } | 181 | } |
diff --git a/server/middlewares/validators/utils.ts b/server/middlewares/validators/utils.ts index 77a1a0d4b..ca80acf29 100644 --- a/server/middlewares/validators/utils.ts +++ b/server/middlewares/validators/utils.ts | |||
@@ -1,19 +1,8 @@ | |||
1 | import { validationResult } from 'express-validator/check' | ||
2 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { validationResult } from 'express-validator/check' | ||
3 | 3 | ||
4 | import { logger } from '../../helpers' | 4 | import { logger } from '../../helpers' |
5 | 5 | ||
6 | function checkErrors (req: express.Request, res: express.Response, next: express.NextFunction) { | ||
7 | const errors = validationResult(req) | ||
8 | |||
9 | if (!errors.isEmpty()) { | ||
10 | logger.warn('Incorrect request parameters', { path: req.originalUrl, err: errors.mapped() }) | ||
11 | return res.status(400).json({ errors: errors.mapped() }) | ||
12 | } | ||
13 | |||
14 | return next() | ||
15 | } | ||
16 | |||
17 | function areValidationErrors (req: express.Request, res: express.Response) { | 6 | function areValidationErrors (req: express.Request, res: express.Response) { |
18 | const errors = validationResult(req) | 7 | const errors = validationResult(req) |
19 | 8 | ||
@@ -30,6 +19,5 @@ function areValidationErrors (req: express.Request, res: express.Response) { | |||
30 | // --------------------------------------------------------------------------- | 19 | // --------------------------------------------------------------------------- |
31 | 20 | ||
32 | export { | 21 | export { |
33 | checkErrors, | ||
34 | areValidationErrors | 22 | areValidationErrors |
35 | } | 23 | } |
diff --git a/server/middlewares/validators/video-blacklist.ts b/server/middlewares/validators/video-blacklist.ts index 3c8c31519..f1cc04950 100644 --- a/server/middlewares/validators/video-blacklist.ts +++ b/server/middlewares/validators/video-blacklist.ts | |||
@@ -1,35 +1,36 @@ | |||
1 | import { param } from 'express-validator/check' | ||
2 | import * as express from 'express' | 1 | import * as express from 'express' |
3 | 2 | import { param } from 'express-validator/check' | |
3 | import { isIdOrUUIDValid, logger } from '../../helpers' | ||
4 | import { isVideoExist } from '../../helpers/custom-validators/videos' | ||
4 | import { database as db } from '../../initializers/database' | 5 | import { database as db } from '../../initializers/database' |
5 | import { checkErrors } from './utils' | 6 | import { VideoInstance } from '../../models/video/video-interface' |
6 | import { logger, isIdOrUUIDValid, checkVideoExists } from '../../helpers' | 7 | import { areValidationErrors } from './utils' |
7 | 8 | ||
8 | const videosBlacklistRemoveValidator = [ | 9 | const videosBlacklistRemoveValidator = [ |
9 | param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'), | 10 | param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'), |
10 | 11 | ||
11 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 12 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
12 | logger.debug('Checking blacklistRemove parameters.', { parameters: req.params }) | 13 | logger.debug('Checking blacklistRemove parameters.', { parameters: req.params }) |
13 | 14 | ||
14 | checkErrors(req, res, () => { | 15 | if (areValidationErrors(req, res)) return |
15 | checkVideoExists(req.params.videoId, res, () => { | 16 | if (!await isVideoExist(req.params.videoId, res)) return |
16 | checkVideoIsBlacklisted(req, res, next) | 17 | if (!await checkVideoIsBlacklisted(res.locals.video, res)) return |
17 | }) | 18 | |
18 | }) | 19 | return next() |
19 | } | 20 | } |
20 | ] | 21 | ] |
21 | 22 | ||
22 | const videosBlacklistAddValidator = [ | 23 | const videosBlacklistAddValidator = [ |
23 | param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'), | 24 | param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'), |
24 | 25 | ||
25 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 26 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
26 | logger.debug('Checking videosBlacklist parameters', { parameters: req.params }) | 27 | logger.debug('Checking videosBlacklist parameters', { parameters: req.params }) |
27 | 28 | ||
28 | checkErrors(req, res, () => { | 29 | if (areValidationErrors(req, res)) return |
29 | checkVideoExists(req.params.videoId, res, () => { | 30 | if (!await isVideoExist(req.params.videoId, res)) return |
30 | checkVideoIsBlacklistable(req, res, next) | 31 | if (!checkVideoIsBlacklistable(res.locals.video, res)) return |
31 | }) | 32 | |
32 | }) | 33 | return next() |
33 | } | 34 | } |
34 | ] | 35 | ] |
35 | 36 | ||
@@ -41,27 +42,27 @@ export { | |||
41 | } | 42 | } |
42 | // --------------------------------------------------------------------------- | 43 | // --------------------------------------------------------------------------- |
43 | 44 | ||
44 | function checkVideoIsBlacklistable (req: express.Request, res: express.Response, callback: () => void) { | 45 | function checkVideoIsBlacklistable (video: VideoInstance, res: express.Response) { |
45 | if (res.locals.video.isOwned() === true) { | 46 | if (video.isOwned() === true) { |
46 | return res.status(403) | 47 | res.status(403) |
47 | .json({ error: 'Cannot blacklist a local video' }) | 48 | .json({ error: 'Cannot blacklist a local video' }) |
48 | .end() | 49 | .end() |
50 | |||
51 | return false | ||
49 | } | 52 | } |
50 | 53 | ||
51 | callback() | 54 | return true |
52 | } | 55 | } |
53 | 56 | ||
54 | function checkVideoIsBlacklisted (req: express.Request, res: express.Response, callback: () => void) { | 57 | async function checkVideoIsBlacklisted (video: VideoInstance, res: express.Response) { |
55 | db.BlacklistedVideo.loadByVideoId(res.locals.video.id) | 58 | const blacklistedVideo = await db.BlacklistedVideo.loadByVideoId(video.id) |
56 | .then(blacklistedVideo => { | 59 | if (!blacklistedVideo) { |
57 | if (!blacklistedVideo) return res.status(404).send('Blacklisted video not found') | 60 | res.status(404) |
61 | .send('Blacklisted video not found') | ||
58 | 62 | ||
59 | res.locals.blacklistedVideo = blacklistedVideo | 63 | return false |
64 | } | ||
60 | 65 | ||
61 | callback() | 66 | res.locals.blacklistedVideo = blacklistedVideo |
62 | }) | 67 | return true |
63 | .catch(err => { | ||
64 | logger.error('Error in blacklistRemove request validator', { error: err }) | ||
65 | return res.sendStatus(500) | ||
66 | }) | ||
67 | } | 68 | } |
diff --git a/server/middlewares/validators/video-channels.ts b/server/middlewares/validators/video-channels.ts index f30fbf0dc..4683c91e1 100644 --- a/server/middlewares/validators/video-channels.ts +++ b/server/middlewares/validators/video-channels.ts | |||
@@ -1,29 +1,30 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { body, param } from 'express-validator/check' | 2 | import { body, param } from 'express-validator/check' |
3 | import { UserRight } from '../../../shared' | 3 | import { UserRight } from '../../../shared' |
4 | import { checkAccountIdExists } from '../../helpers/custom-validators/accounts' | ||
5 | import { isIdValid } from '../../helpers/custom-validators/misc' | 4 | import { isIdValid } from '../../helpers/custom-validators/misc' |
6 | import { | 5 | import { |
7 | checkVideoChannelExists, | ||
8 | isVideoChannelDescriptionValid, | 6 | isVideoChannelDescriptionValid, |
9 | isVideoChannelExistsPromise, | 7 | isVideoChannelExist, |
10 | isVideoChannelNameValid | 8 | isVideoChannelNameValid |
11 | } from '../../helpers/custom-validators/video-channels' | 9 | } from '../../helpers/custom-validators/video-channels' |
12 | import { isIdOrUUIDValid } from '../../helpers/index' | 10 | import { isIdOrUUIDValid } from '../../helpers/index' |
13 | import { logger } from '../../helpers/logger' | 11 | import { logger } from '../../helpers/logger' |
14 | import { database as db } from '../../initializers' | 12 | import { database as db } from '../../initializers' |
15 | import { UserInstance } from '../../models' | 13 | import { UserInstance } from '../../models' |
16 | import { areValidationErrors, checkErrors } from './utils' | 14 | import { areValidationErrors } from './utils' |
15 | import { isAccountIdExist } from '../../helpers/custom-validators/accounts' | ||
16 | import { VideoChannelInstance } from '../../models/video/video-channel-interface' | ||
17 | 17 | ||
18 | const listVideoAccountChannelsValidator = [ | 18 | const listVideoAccountChannelsValidator = [ |
19 | param('accountId').custom(isIdOrUUIDValid).withMessage('Should have a valid account id'), | 19 | param('accountId').custom(isIdOrUUIDValid).withMessage('Should have a valid account id'), |
20 | 20 | ||
21 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 21 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
22 | logger.debug('Checking listVideoAccountChannelsValidator parameters', { parameters: req.body }) | 22 | logger.debug('Checking listVideoAccountChannelsValidator parameters', { parameters: req.body }) |
23 | 23 | ||
24 | checkErrors(req, res, () => { | 24 | if (areValidationErrors(req, res)) return |
25 | checkAccountIdExists(req.params.accountId, res, next) | 25 | if (!await isAccountIdExist(req.params.accountId, res)) return |
26 | }) | 26 | |
27 | return next() | ||
27 | } | 28 | } |
28 | ] | 29 | ] |
29 | 30 | ||
@@ -34,7 +35,9 @@ const videoChannelsAddValidator = [ | |||
34 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 35 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
35 | logger.debug('Checking videoChannelsAdd parameters', { parameters: req.body }) | 36 | logger.debug('Checking videoChannelsAdd parameters', { parameters: req.body }) |
36 | 37 | ||
37 | checkErrors(req, res, next) | 38 | if (areValidationErrors(req, res)) return |
39 | |||
40 | return next() | ||
38 | } | 41 | } |
39 | ] | 42 | ] |
40 | 43 | ||
@@ -43,56 +46,56 @@ const videoChannelsUpdateValidator = [ | |||
43 | body('name').optional().custom(isVideoChannelNameValid).withMessage('Should have a valid name'), | 46 | body('name').optional().custom(isVideoChannelNameValid).withMessage('Should have a valid name'), |
44 | body('description').optional().custom(isVideoChannelDescriptionValid).withMessage('Should have a valid description'), | 47 | body('description').optional().custom(isVideoChannelDescriptionValid).withMessage('Should have a valid description'), |
45 | 48 | ||
46 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 49 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
47 | logger.debug('Checking videoChannelsUpdate parameters', { parameters: req.body }) | 50 | logger.debug('Checking videoChannelsUpdate parameters', { parameters: req.body }) |
48 | 51 | ||
49 | checkErrors(req, res, () => { | 52 | if (areValidationErrors(req, res)) return |
50 | checkVideoChannelExists(req.params.id, res, () => { | 53 | if (!await isVideoChannelExist(req.params.id, res)) return |
51 | // We need to make additional checks | 54 | |
52 | if (res.locals.videoChannel.isOwned() === false) { | 55 | // We need to make additional checks |
53 | return res.status(403) | 56 | if (res.locals.videoChannel.isOwned() === false) { |
54 | .json({ error: 'Cannot update video channel of another server' }) | 57 | return res.status(403) |
55 | .end() | 58 | .json({ error: 'Cannot update video channel of another server' }) |
56 | } | 59 | .end() |
57 | 60 | } | |
58 | if (res.locals.videoChannel.Account.userId !== res.locals.oauth.token.User.id) { | 61 | |
59 | return res.status(403) | 62 | if (res.locals.videoChannel.Account.userId !== res.locals.oauth.token.User.id) { |
60 | .json({ error: 'Cannot update video channel of another user' }) | 63 | return res.status(403) |
61 | .end() | 64 | .json({ error: 'Cannot update video channel of another user' }) |
62 | } | 65 | .end() |
63 | 66 | } | |
64 | next() | 67 | |
65 | }) | 68 | return next() |
66 | }) | ||
67 | } | 69 | } |
68 | ] | 70 | ] |
69 | 71 | ||
70 | const videoChannelsRemoveValidator = [ | 72 | const videoChannelsRemoveValidator = [ |
71 | param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), | 73 | param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), |
72 | 74 | ||
73 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 75 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
74 | logger.debug('Checking videoChannelsRemove parameters', { parameters: req.params }) | 76 | logger.debug('Checking videoChannelsRemove parameters', { parameters: req.params }) |
75 | 77 | ||
76 | checkErrors(req, res, () => { | 78 | if (areValidationErrors(req, res)) return |
77 | checkVideoChannelExists(req.params.id, res, () => { | 79 | if (!await isVideoChannelExist(req.params.id, res)) return |
78 | // Check if the user who did the request is able to delete the video | 80 | |
79 | checkUserCanDeleteVideoChannel(res, () => { | 81 | // Check if the user who did the request is able to delete the video |
80 | checkVideoChannelIsNotTheLastOne(res, next) | 82 | if (!checkUserCanDeleteVideoChannel(res.locals.user, res.locals.videoChannel, res)) return |
81 | }) | 83 | if (!await checkVideoChannelIsNotTheLastOne(res)) return |
82 | }) | 84 | |
83 | }) | 85 | return next() |
84 | } | 86 | } |
85 | ] | 87 | ] |
86 | 88 | ||
87 | const videoChannelsGetValidator = [ | 89 | const videoChannelsGetValidator = [ |
88 | param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), | 90 | param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), |
89 | 91 | ||
90 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 92 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
91 | logger.debug('Checking videoChannelsGet parameters', { parameters: req.params }) | 93 | logger.debug('Checking videoChannelsGet parameters', { parameters: req.params }) |
92 | 94 | ||
93 | checkErrors(req, res, () => { | 95 | if (areValidationErrors(req, res)) return |
94 | checkVideoChannelExists(req.params.id, res, next) | 96 | if (!await isVideoChannelExist(req.params.id, res)) return |
95 | }) | 97 | |
98 | return next() | ||
96 | } | 99 | } |
97 | ] | 100 | ] |
98 | 101 | ||
@@ -104,7 +107,7 @@ const videoChannelsShareValidator = [ | |||
104 | logger.debug('Checking videoChannelShare parameters', { parameters: req.params }) | 107 | logger.debug('Checking videoChannelShare parameters', { parameters: req.params }) |
105 | 108 | ||
106 | if (areValidationErrors(req, res)) return | 109 | if (areValidationErrors(req, res)) return |
107 | if (!await isVideoChannelExistsPromise(req.params.id, res)) return | 110 | if (!await isVideoChannelExist(req.params.id, res)) return |
108 | 111 | ||
109 | const share = await db.VideoChannelShare.load(res.locals.video.id, req.params.accountId) | 112 | const share = await db.VideoChannelShare.load(res.locals.video.id, req.params.accountId) |
110 | if (!share) { | 113 | if (!share) { |
@@ -131,38 +134,40 @@ export { | |||
131 | 134 | ||
132 | // --------------------------------------------------------------------------- | 135 | // --------------------------------------------------------------------------- |
133 | 136 | ||
134 | function checkUserCanDeleteVideoChannel (res: express.Response, callback: () => void) { | 137 | function checkUserCanDeleteVideoChannel (user: UserInstance, videoChannel: VideoChannelInstance, res: express.Response) { |
135 | const user: UserInstance = res.locals.oauth.token.User | ||
136 | |||
137 | // Retrieve the user who did the request | 138 | // Retrieve the user who did the request |
138 | if (res.locals.videoChannel.isOwned() === false) { | 139 | if (videoChannel.isOwned() === false) { |
139 | return res.status(403) | 140 | res.status(403) |
140 | .json({ error: 'Cannot remove video channel of another server.' }) | 141 | .json({ error: 'Cannot remove video channel of another server.' }) |
141 | .end() | 142 | .end() |
143 | |||
144 | return false | ||
142 | } | 145 | } |
143 | 146 | ||
144 | // Check if the user can delete the video channel | 147 | // Check if the user can delete the video channel |
145 | // The user can delete it if s/he is an admin | 148 | // The user can delete it if s/he is an admin |
146 | // Or if s/he is the video channel's account | 149 | // Or if s/he is the video channel's account |
147 | if (user.hasRight(UserRight.REMOVE_ANY_VIDEO_CHANNEL) === false && res.locals.videoChannel.Account.userId !== user.id) { | 150 | if (user.hasRight(UserRight.REMOVE_ANY_VIDEO_CHANNEL) === false && videoChannel.Account.userId !== user.id) { |
148 | return res.status(403) | 151 | res.status(403) |
149 | .json({ error: 'Cannot remove video channel of another user' }) | 152 | .json({ error: 'Cannot remove video channel of another user' }) |
150 | .end() | 153 | .end() |
154 | |||
155 | return false | ||
151 | } | 156 | } |
152 | 157 | ||
153 | // If we reach this comment, we can delete the video | 158 | return true |
154 | callback() | ||
155 | } | 159 | } |
156 | 160 | ||
157 | function checkVideoChannelIsNotTheLastOne (res: express.Response, callback: () => void) { | 161 | async function checkVideoChannelIsNotTheLastOne (res: express.Response) { |
158 | db.VideoChannel.countByAccount(res.locals.oauth.token.User.Account.id) | 162 | const count = await db.VideoChannel.countByAccount(res.locals.oauth.token.User.Account.id) |
159 | .then(count => { | 163 | |
160 | if (count <= 1) { | 164 | if (count <= 1) { |
161 | return res.status(409) | 165 | res.status(409) |
162 | .json({ error: 'Cannot remove the last channel of this user' }) | 166 | .json({ error: 'Cannot remove the last channel of this user' }) |
163 | .end() | 167 | .end() |
164 | } | 168 | |
165 | 169 | return false | |
166 | callback() | 170 | } |
167 | }) | 171 | |
172 | return true | ||
168 | } | 173 | } |
diff --git a/server/middlewares/validators/videos.ts b/server/middlewares/validators/videos.ts index 5ffc85210..3cbf98312 100644 --- a/server/middlewares/validators/videos.ts +++ b/server/middlewares/validators/videos.ts | |||
@@ -3,11 +3,11 @@ import { body, param, query } from 'express-validator/check' | |||
3 | import { UserRight, VideoPrivacy } from '../../../shared' | 3 | import { UserRight, VideoPrivacy } from '../../../shared' |
4 | import { isIdOrUUIDValid, isIdValid } from '../../helpers/custom-validators/misc' | 4 | import { isIdOrUUIDValid, isIdValid } from '../../helpers/custom-validators/misc' |
5 | import { | 5 | import { |
6 | checkVideoExists, | ||
7 | isVideoAbuseReasonValid, | 6 | isVideoAbuseReasonValid, |
8 | isVideoCategoryValid, | 7 | isVideoCategoryValid, |
9 | isVideoDescriptionValid, | 8 | isVideoDescriptionValid, |
10 | isVideoDurationValid, | 9 | isVideoDurationValid, |
10 | isVideoExist, | ||
11 | isVideoFile, | 11 | isVideoFile, |
12 | isVideoLanguageValid, | 12 | isVideoLanguageValid, |
13 | isVideoLicenceValid, | 13 | isVideoLicenceValid, |
@@ -20,12 +20,11 @@ import { | |||
20 | import { getDurationFromVideoFile } from '../../helpers/ffmpeg-utils' | 20 | import { getDurationFromVideoFile } from '../../helpers/ffmpeg-utils' |
21 | import { logger } from '../../helpers/logger' | 21 | import { logger } from '../../helpers/logger' |
22 | import { CONSTRAINTS_FIELDS, SEARCHABLE_COLUMNS } from '../../initializers' | 22 | import { CONSTRAINTS_FIELDS, SEARCHABLE_COLUMNS } from '../../initializers' |
23 | |||
24 | import { database as db } from '../../initializers/database' | 23 | import { database as db } from '../../initializers/database' |
25 | import { UserInstance } from '../../models/account/user-interface' | 24 | import { UserInstance } from '../../models/account/user-interface' |
25 | import { VideoInstance } from '../../models/video/video-interface' | ||
26 | import { authenticate } from '../oauth' | 26 | import { authenticate } from '../oauth' |
27 | import { areValidationErrors, checkErrors } from './utils' | 27 | import { areValidationErrors } from './utils' |
28 | import { isVideoExistsPromise } from '../../helpers/index' | ||
29 | 28 | ||
30 | const videosAddValidator = [ | 29 | const videosAddValidator = [ |
31 | body('videofile').custom((value, { req }) => isVideoFile(req.files)).withMessage( | 30 | body('videofile').custom((value, { req }) => isVideoFile(req.files)).withMessage( |
@@ -42,68 +41,58 @@ const videosAddValidator = [ | |||
42 | body('privacy').custom(isVideoPrivacyValid).withMessage('Should have correct video privacy'), | 41 | body('privacy').custom(isVideoPrivacyValid).withMessage('Should have correct video privacy'), |
43 | body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'), | 42 | body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'), |
44 | 43 | ||
45 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 44 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
46 | logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files }) | 45 | logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files }) |
47 | 46 | ||
48 | checkErrors(req, res, () => { | 47 | if (areValidationErrors(req, res)) return |
49 | const videoFile: Express.Multer.File = req.files['videofile'][0] | 48 | |
50 | const user = res.locals.oauth.token.User | 49 | const videoFile: Express.Multer.File = req.files['videofile'][0] |
50 | const user = res.locals.oauth.token.User | ||
51 | 51 | ||
52 | return db.VideoChannel.loadByIdAndAccount(req.body.channelId, user.Account.id) | 52 | const videoChannel = await db.VideoChannel.loadByIdAndAccount(req.body.channelId, user.Account.id) |
53 | .then(videoChannel => { | 53 | if (!videoChannel) { |
54 | if (!videoChannel) { | 54 | res.status(400) |
55 | res.status(400) | 55 | .json({ error: 'Unknown video video channel for this account.' }) |
56 | .json({ error: 'Unknown video video channel for this account.' }) | 56 | .end() |
57 | .end() | ||
58 | 57 | ||
59 | return undefined | 58 | return |
60 | } | 59 | } |
61 | 60 | ||
62 | res.locals.videoChannel = videoChannel | 61 | res.locals.videoChannel = videoChannel |
63 | 62 | ||
64 | return user.isAbleToUploadVideo(videoFile) | 63 | const isAble = await user.isAbleToUploadVideo(videoFile) |
65 | }) | 64 | if (isAble === false) { |
66 | .then(isAble => { | 65 | res.status(403) |
67 | if (isAble === false) { | 66 | .json({ error: 'The user video quota is exceeded with this video.' }) |
68 | res.status(403) | 67 | .end() |
69 | .json({ error: 'The user video quota is exceeded with this video.' }) | 68 | |
70 | .end() | 69 | return |
71 | 70 | } | |
72 | return undefined | 71 | |
73 | } | 72 | let duration: number |
74 | 73 | ||
75 | return getDurationFromVideoFile(videoFile.path) | 74 | try { |
76 | .catch(err => { | 75 | duration = await getDurationFromVideoFile(videoFile.path) |
77 | logger.error('Invalid input file in videosAddValidator.', err) | 76 | } catch (err) { |
78 | res.status(400) | 77 | logger.error('Invalid input file in videosAddValidator.', err) |
79 | .json({ error: 'Invalid input file.' }) | 78 | res.status(400) |
80 | .end() | 79 | .json({ error: 'Invalid input file.' }) |
81 | 80 | .end() | |
82 | return undefined | 81 | |
83 | }) | 82 | return |
84 | }) | 83 | } |
85 | .then(duration => { | 84 | |
86 | // Previous test failed, abort | 85 | if (!isVideoDurationValid('' + duration)) { |
87 | if (duration === undefined) return undefined | 86 | return res.status(400) |
88 | 87 | .json({ | |
89 | if (!isVideoDurationValid('' + duration)) { | 88 | error: 'Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).' |
90 | return res.status(400) | 89 | }) |
91 | .json({ | 90 | .end() |
92 | error: 'Duration of the video file is too big (max: ' + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).' | 91 | } |
93 | }) | 92 | |
94 | .end() | 93 | videoFile['duration'] = duration |
95 | } | 94 | |
96 | 95 | return next() | |
97 | videoFile['duration'] = duration | ||
98 | next() | ||
99 | }) | ||
100 | .catch(err => { | ||
101 | logger.error('Error in video add validator', err) | ||
102 | res.sendStatus(500) | ||
103 | |||
104 | return undefined | ||
105 | }) | ||
106 | }) | ||
107 | } | 96 | } |
108 | ] | 97 | ] |
109 | 98 | ||
@@ -118,61 +107,59 @@ const videosUpdateValidator = [ | |||
118 | body('description').optional().custom(isVideoDescriptionValid).withMessage('Should have a valid description'), | 107 | body('description').optional().custom(isVideoDescriptionValid).withMessage('Should have a valid description'), |
119 | body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'), | 108 | body('tags').optional().custom(isVideoTagsValid).withMessage('Should have correct tags'), |
120 | 109 | ||
121 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 110 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
122 | logger.debug('Checking videosUpdate parameters', { parameters: req.body }) | 111 | logger.debug('Checking videosUpdate parameters', { parameters: req.body }) |
123 | 112 | ||
124 | checkErrors(req, res, () => { | 113 | if (areValidationErrors(req, res)) return |
125 | checkVideoExists(req.params.id, res, () => { | 114 | if (!await isVideoExist(req.params.id, res)) return |
126 | const video = res.locals.video | 115 | |
127 | 116 | const video = res.locals.video | |
128 | // We need to make additional checks | 117 | |
129 | if (video.isOwned() === false) { | 118 | // We need to make additional checks |
130 | return res.status(403) | 119 | if (video.isOwned() === false) { |
131 | .json({ error: 'Cannot update video of another server' }) | 120 | return res.status(403) |
132 | .end() | 121 | .json({ error: 'Cannot update video of another server' }) |
133 | } | 122 | .end() |
134 | 123 | } | |
135 | if (video.VideoChannel.Account.userId !== res.locals.oauth.token.User.id) { | 124 | |
136 | return res.status(403) | 125 | if (video.VideoChannel.Account.userId !== res.locals.oauth.token.User.id) { |
137 | .json({ error: 'Cannot update video of another user' }) | 126 | return res.status(403) |
138 | .end() | 127 | .json({ error: 'Cannot update video of another user' }) |
139 | } | 128 | .end() |
140 | 129 | } | |
141 | if (video.privacy !== VideoPrivacy.PRIVATE && req.body.privacy === VideoPrivacy.PRIVATE) { | 130 | |
142 | return res.status(409) | 131 | if (video.privacy !== VideoPrivacy.PRIVATE && req.body.privacy === VideoPrivacy.PRIVATE) { |
143 | .json({ error: 'Cannot set "private" a video that was not private anymore.' }) | 132 | return res.status(409) |
144 | .end() | 133 | .json({ error: 'Cannot set "private" a video that was not private anymore.' }) |
145 | } | 134 | .end() |
146 | 135 | } | |
147 | next() | 136 | |
148 | }) | 137 | return next() |
149 | }) | ||
150 | } | 138 | } |
151 | ] | 139 | ] |
152 | 140 | ||
153 | const videosGetValidator = [ | 141 | const videosGetValidator = [ |
154 | param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), | 142 | param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), |
155 | 143 | ||
156 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 144 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
157 | logger.debug('Checking videosGet parameters', { parameters: req.params }) | 145 | logger.debug('Checking videosGet parameters', { parameters: req.params }) |
158 | 146 | ||
159 | checkErrors(req, res, () => { | 147 | if (areValidationErrors(req, res)) return |
160 | checkVideoExists(req.params.id, res, () => { | 148 | if (!await isVideoExist(req.params.id, res)) return |
161 | const video = res.locals.video | ||
162 | 149 | ||
163 | // Video is not private, anyone can access it | 150 | const video = res.locals.video |
164 | if (video.privacy !== VideoPrivacy.PRIVATE) return next() | ||
165 | 151 | ||
166 | authenticate(req, res, () => { | 152 | // Video is not private, anyone can access it |
167 | if (video.VideoChannel.Account.userId !== res.locals.oauth.token.User.id) { | 153 | if (video.privacy !== VideoPrivacy.PRIVATE) return next() |
168 | return res.status(403) | ||
169 | .json({ error: 'Cannot get this private video of another user' }) | ||
170 | .end() | ||
171 | } | ||
172 | 154 | ||
173 | next() | 155 | authenticate(req, res, () => { |
174 | }) | 156 | if (video.VideoChannel.Account.userId !== res.locals.oauth.token.User.id) { |
175 | }) | 157 | return res.status(403) |
158 | .json({ error: 'Cannot get this private video of another user' }) | ||
159 | .end() | ||
160 | } | ||
161 | |||
162 | return next() | ||
176 | }) | 163 | }) |
177 | } | 164 | } |
178 | ] | 165 | ] |
@@ -180,17 +167,16 @@ const videosGetValidator = [ | |||
180 | const videosRemoveValidator = [ | 167 | const videosRemoveValidator = [ |
181 | param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), | 168 | param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), |
182 | 169 | ||
183 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 170 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
184 | logger.debug('Checking videosRemove parameters', { parameters: req.params }) | 171 | logger.debug('Checking videosRemove parameters', { parameters: req.params }) |
185 | 172 | ||
186 | checkErrors(req, res, () => { | 173 | if (areValidationErrors(req, res)) return |
187 | checkVideoExists(req.params.id, res, () => { | 174 | if (!await isVideoExist(req.params.id, res)) return |
188 | // Check if the user who did the request is able to delete the video | 175 | |
189 | checkUserCanDeleteVideo(res.locals.oauth.token.User, res, () => { | 176 | // Check if the user who did the request is able to delete the video |
190 | next() | 177 | if (!checkUserCanDeleteVideo(res.locals.oauth.token.User, res.locals.video, res)) return |
191 | }) | 178 | |
192 | }) | 179 | return next() |
193 | }) | ||
194 | } | 180 | } |
195 | ] | 181 | ] |
196 | 182 | ||
@@ -201,7 +187,9 @@ const videosSearchValidator = [ | |||
201 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 187 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
202 | logger.debug('Checking videosSearch parameters', { parameters: req.params }) | 188 | logger.debug('Checking videosSearch parameters', { parameters: req.params }) |
203 | 189 | ||
204 | checkErrors(req, res, next) | 190 | if (areValidationErrors(req, res)) return |
191 | |||
192 | return next() | ||
205 | } | 193 | } |
206 | ] | 194 | ] |
207 | 195 | ||
@@ -209,12 +197,13 @@ const videoAbuseReportValidator = [ | |||
209 | param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), | 197 | param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), |
210 | body('reason').custom(isVideoAbuseReasonValid).withMessage('Should have a valid reason'), | 198 | body('reason').custom(isVideoAbuseReasonValid).withMessage('Should have a valid reason'), |
211 | 199 | ||
212 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 200 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
213 | logger.debug('Checking videoAbuseReport parameters', { parameters: req.body }) | 201 | logger.debug('Checking videoAbuseReport parameters', { parameters: req.body }) |
214 | 202 | ||
215 | checkErrors(req, res, () => { | 203 | if (areValidationErrors(req, res)) return |
216 | checkVideoExists(req.params.id, res, next) | 204 | if (!await isVideoExist(req.params.id, res)) return |
217 | }) | 205 | |
206 | return next() | ||
218 | } | 207 | } |
219 | ] | 208 | ] |
220 | 209 | ||
@@ -222,12 +211,13 @@ const videoRateValidator = [ | |||
222 | param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), | 211 | param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), |
223 | body('rating').custom(isVideoRatingTypeValid).withMessage('Should have a valid rate type'), | 212 | body('rating').custom(isVideoRatingTypeValid).withMessage('Should have a valid rate type'), |
224 | 213 | ||
225 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 214 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
226 | logger.debug('Checking videoRate parameters', { parameters: req.body }) | 215 | logger.debug('Checking videoRate parameters', { parameters: req.body }) |
227 | 216 | ||
228 | checkErrors(req, res, () => { | 217 | if (areValidationErrors(req, res)) return |
229 | checkVideoExists(req.params.id, res, next) | 218 | if (!await isVideoExist(req.params.id, res)) return |
230 | }) | 219 | |
220 | return next() | ||
231 | } | 221 | } |
232 | ] | 222 | ] |
233 | 223 | ||
@@ -239,7 +229,7 @@ const videosShareValidator = [ | |||
239 | logger.debug('Checking videoShare parameters', { parameters: req.params }) | 229 | logger.debug('Checking videoShare parameters', { parameters: req.params }) |
240 | 230 | ||
241 | if (areValidationErrors(req, res)) return | 231 | if (areValidationErrors(req, res)) return |
242 | if (!await isVideoExistsPromise(req.params.id, res)) return | 232 | if (!await isVideoExist(req.params.id, res)) return |
243 | 233 | ||
244 | const share = await db.VideoShare.load(req.params.accountId, res.locals.video.id) | 234 | const share = await db.VideoShare.load(req.params.accountId, res.locals.video.id) |
245 | if (!share) { | 235 | if (!share) { |
@@ -248,7 +238,6 @@ const videosShareValidator = [ | |||
248 | } | 238 | } |
249 | 239 | ||
250 | res.locals.videoShare = share | 240 | res.locals.videoShare = share |
251 | |||
252 | return next() | 241 | return next() |
253 | } | 242 | } |
254 | ] | 243 | ] |
@@ -270,24 +259,25 @@ export { | |||
270 | 259 | ||
271 | // --------------------------------------------------------------------------- | 260 | // --------------------------------------------------------------------------- |
272 | 261 | ||
273 | function checkUserCanDeleteVideo (user: UserInstance, res: express.Response, callback: () => void) { | 262 | function checkUserCanDeleteVideo (user: UserInstance, video: VideoInstance, res: express.Response) { |
274 | // Retrieve the user who did the request | 263 | // Retrieve the user who did the request |
275 | if (res.locals.video.isOwned() === false) { | 264 | if (video.isOwned() === false) { |
276 | return res.status(403) | 265 | res.status(403) |
277 | .json({ error: 'Cannot remove video of another server, blacklist it' }) | 266 | .json({ error: 'Cannot remove video of another server, blacklist it' }) |
278 | .end() | 267 | .end() |
268 | return false | ||
279 | } | 269 | } |
280 | 270 | ||
281 | // Check if the user can delete the video | 271 | // Check if the user can delete the video |
282 | // The user can delete it if s/he is an admin | 272 | // The user can delete it if s/he is an admin |
283 | // Or if s/he is the video's account | 273 | // Or if s/he is the video's account |
284 | const account = res.locals.video.VideoChannel.Account | 274 | const account = video.VideoChannel.Account |
285 | if (user.hasRight(UserRight.REMOVE_ANY_VIDEO) === false && account.userId !== user.id) { | 275 | if (user.hasRight(UserRight.REMOVE_ANY_VIDEO) === false && account.userId !== user.id) { |
286 | return res.status(403) | 276 | res.status(403) |
287 | .json({ error: 'Cannot remove video of another user' }) | 277 | .json({ error: 'Cannot remove video of another user' }) |
288 | .end() | 278 | .end() |
279 | return false | ||
289 | } | 280 | } |
290 | 281 | ||
291 | // If we reach this comment, we can delete the video | 282 | return true |
292 | callback() | ||
293 | } | 283 | } |
diff --git a/server/middlewares/validators/webfinger.ts b/server/middlewares/validators/webfinger.ts index 7852c1c2b..34e62c66d 100644 --- a/server/middlewares/validators/webfinger.ts +++ b/server/middlewares/validators/webfinger.ts | |||
@@ -1,37 +1,31 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { query } from 'express-validator/check' | 2 | import { query } from 'express-validator/check' |
3 | import { isWebfingerResourceValid } from '../../helpers/custom-validators/webfinger' | 3 | import { isWebfingerResourceValid } from '../../helpers/custom-validators/webfinger' |
4 | import { database as db } from '../../initializers' | ||
5 | import { checkErrors } from './utils' | ||
6 | import { logger } from '../../helpers/logger' | 4 | import { logger } from '../../helpers/logger' |
5 | import { database as db } from '../../initializers' | ||
6 | import { areValidationErrors } from './utils' | ||
7 | 7 | ||
8 | const webfingerValidator = [ | 8 | const webfingerValidator = [ |
9 | query('resource').custom(isWebfingerResourceValid).withMessage('Should have a valid webfinger resource'), | 9 | query('resource').custom(isWebfingerResourceValid).withMessage('Should have a valid webfinger resource'), |
10 | 10 | ||
11 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 11 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
12 | logger.debug('Checking webfinger parameters', { parameters: req.query }) | 12 | logger.debug('Checking webfinger parameters', { parameters: req.query }) |
13 | 13 | ||
14 | checkErrors(req, res, () => { | 14 | if (areValidationErrors(req, res)) return |
15 | // Remove 'acct:' from the beginning of the string | 15 | |
16 | const nameWithHost = req.query.resource.substr(5) | 16 | // Remove 'acct:' from the beginning of the string |
17 | const [ name ] = nameWithHost.split('@') | 17 | const nameWithHost = req.query.resource.substr(5) |
18 | 18 | const [ name ] = nameWithHost.split('@') | |
19 | db.Account.loadLocalByName(name) | 19 | |
20 | .then(account => { | 20 | const account = await db.Account.loadLocalByName(name) |
21 | if (!account) { | 21 | if (!account) { |
22 | return res.status(404) | 22 | return res.status(404) |
23 | .send({ error: 'Account not found' }) | 23 | .send({ error: 'Account not found' }) |
24 | .end() | 24 | .end() |
25 | } | 25 | } |
26 | 26 | ||
27 | res.locals.account = account | 27 | res.locals.account = account |
28 | return next() | 28 | return next() |
29 | }) | ||
30 | .catch(err => { | ||
31 | logger.error('Error in webfinger validator.', err) | ||
32 | return res.sendStatus(500) | ||
33 | }) | ||
34 | }) | ||
35 | } | 29 | } |
36 | ] | 30 | ] |
37 | 31 | ||
diff --git a/server/models/account/account.ts b/server/models/account/account.ts index fff3ce087..c721656cb 100644 --- a/server/models/account/account.ts +++ b/server/models/account/account.ts | |||
@@ -2,17 +2,12 @@ import * as Sequelize from 'sequelize' | |||
2 | import { | 2 | import { |
3 | activityPubContextify, | 3 | activityPubContextify, |
4 | isAccountFollowersCountValid, | 4 | isAccountFollowersCountValid, |
5 | isAccountFollowersValid, | ||
6 | isAccountFollowingCountValid, | 5 | isAccountFollowingCountValid, |
7 | isAccountFollowingValid, | ||
8 | isAccountInboxValid, | ||
9 | isAccountOutboxValid, | ||
10 | isAccountPrivateKeyValid, | 6 | isAccountPrivateKeyValid, |
11 | isAccountPublicKeyValid, | 7 | isAccountPublicKeyValid, |
12 | isAccountSharedInboxValid, | ||
13 | isAccountUrlValid, | ||
14 | isUserUsernameValid | 8 | isUserUsernameValid |
15 | } from '../../helpers' | 9 | } from '../../helpers' |
10 | import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' | ||
16 | import { CONFIG, CONSTRAINTS_FIELDS } from '../../initializers/constants' | 11 | import { CONFIG, CONSTRAINTS_FIELDS } from '../../initializers/constants' |
17 | import { sendDeleteAccount } from '../../lib/activitypub/send/send-delete' | 12 | import { sendDeleteAccount } from '../../lib/activitypub/send/send-delete' |
18 | 13 | ||
@@ -61,7 +56,7 @@ export default function defineAccount (sequelize: Sequelize.Sequelize, DataTypes | |||
61 | allowNull: false, | 56 | allowNull: false, |
62 | validate: { | 57 | validate: { |
63 | urlValid: value => { | 58 | urlValid: value => { |
64 | const res = isAccountUrlValid(value) | 59 | const res = isActivityPubUrlValid(value) |
65 | if (res === false) throw new Error('URL is not valid.') | 60 | if (res === false) throw new Error('URL is not valid.') |
66 | } | 61 | } |
67 | } | 62 | } |
@@ -111,7 +106,7 @@ export default function defineAccount (sequelize: Sequelize.Sequelize, DataTypes | |||
111 | allowNull: false, | 106 | allowNull: false, |
112 | validate: { | 107 | validate: { |
113 | inboxUrlValid: value => { | 108 | inboxUrlValid: value => { |
114 | const res = isAccountInboxValid(value) | 109 | const res = isActivityPubUrlValid(value) |
115 | if (res === false) throw new Error('Inbox URL is not valid.') | 110 | if (res === false) throw new Error('Inbox URL is not valid.') |
116 | } | 111 | } |
117 | } | 112 | } |
@@ -121,7 +116,7 @@ export default function defineAccount (sequelize: Sequelize.Sequelize, DataTypes | |||
121 | allowNull: false, | 116 | allowNull: false, |
122 | validate: { | 117 | validate: { |
123 | outboxUrlValid: value => { | 118 | outboxUrlValid: value => { |
124 | const res = isAccountOutboxValid(value) | 119 | const res = isActivityPubUrlValid(value) |
125 | if (res === false) throw new Error('Outbox URL is not valid.') | 120 | if (res === false) throw new Error('Outbox URL is not valid.') |
126 | } | 121 | } |
127 | } | 122 | } |
@@ -131,7 +126,7 @@ export default function defineAccount (sequelize: Sequelize.Sequelize, DataTypes | |||
131 | allowNull: false, | 126 | allowNull: false, |
132 | validate: { | 127 | validate: { |
133 | sharedInboxUrlValid: value => { | 128 | sharedInboxUrlValid: value => { |
134 | const res = isAccountSharedInboxValid(value) | 129 | const res = isActivityPubUrlValid(value) |
135 | if (res === false) throw new Error('Shared inbox URL is not valid.') | 130 | if (res === false) throw new Error('Shared inbox URL is not valid.') |
136 | } | 131 | } |
137 | } | 132 | } |
@@ -141,7 +136,7 @@ export default function defineAccount (sequelize: Sequelize.Sequelize, DataTypes | |||
141 | allowNull: false, | 136 | allowNull: false, |
142 | validate: { | 137 | validate: { |
143 | followersUrlValid: value => { | 138 | followersUrlValid: value => { |
144 | const res = isAccountFollowersValid(value) | 139 | const res = isActivityPubUrlValid(value) |
145 | if (res === false) throw new Error('Followers URL is not valid.') | 140 | if (res === false) throw new Error('Followers URL is not valid.') |
146 | } | 141 | } |
147 | } | 142 | } |
@@ -151,7 +146,7 @@ export default function defineAccount (sequelize: Sequelize.Sequelize, DataTypes | |||
151 | allowNull: false, | 146 | allowNull: false, |
152 | validate: { | 147 | validate: { |
153 | followingUrlValid: value => { | 148 | followingUrlValid: value => { |
154 | const res = isAccountFollowingValid(value) | 149 | const res = isActivityPubUrlValid(value) |
155 | if (res === false) throw new Error('Following URL is not valid.') | 150 | if (res === false) throw new Error('Following URL is not valid.') |
156 | } | 151 | } |
157 | } | 152 | } |
diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts index e11268b2c..54f12dce3 100644 --- a/server/models/video/video-channel.ts +++ b/server/models/video/video-channel.ts | |||
@@ -1,6 +1,5 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../../helpers' | 2 | import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../../helpers' |
3 | import { isVideoChannelUrlValid } from '../../helpers/custom-validators/video-channels' | ||
4 | import { CONSTRAINTS_FIELDS } from '../../initializers/constants' | 3 | import { CONSTRAINTS_FIELDS } from '../../initializers/constants' |
5 | import { sendDeleteVideoChannel } from '../../lib/activitypub/send/send-delete' | 4 | import { sendDeleteVideoChannel } from '../../lib/activitypub/send/send-delete' |
6 | 5 | ||
@@ -8,6 +7,7 @@ import { addMethodsToModel, getSort } from '../utils' | |||
8 | import { VideoChannelAttributes, VideoChannelInstance, VideoChannelMethods } from './video-channel-interface' | 7 | import { VideoChannelAttributes, VideoChannelInstance, VideoChannelMethods } from './video-channel-interface' |
9 | import { getAnnounceActivityPubUrl } from '../../lib/activitypub/url' | 8 | import { getAnnounceActivityPubUrl } from '../../lib/activitypub/url' |
10 | import { activityPubCollection } from '../../helpers/activitypub' | 9 | import { activityPubCollection } from '../../helpers/activitypub' |
10 | import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' | ||
11 | 11 | ||
12 | let VideoChannel: Sequelize.Model<VideoChannelInstance, VideoChannelAttributes> | 12 | let VideoChannel: Sequelize.Model<VideoChannelInstance, VideoChannelAttributes> |
13 | let toFormattedJSON: VideoChannelMethods.ToFormattedJSON | 13 | let toFormattedJSON: VideoChannelMethods.ToFormattedJSON |
@@ -66,7 +66,7 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da | |||
66 | allowNull: false, | 66 | allowNull: false, |
67 | validate: { | 67 | validate: { |
68 | urlValid: value => { | 68 | urlValid: value => { |
69 | const res = isVideoChannelUrlValid(value) | 69 | const res = isActivityPubUrlValid(value) |
70 | if (res === false) throw new Error('Video channel URL is not valid.') | 70 | if (res === false) throw new Error('Video channel URL is not valid.') |
71 | } | 71 | } |
72 | } | 72 | } |
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index 4956b57ee..3f416d04c 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -7,7 +7,18 @@ import * as Sequelize from 'sequelize' | |||
7 | import { VideoPrivacy, VideoResolution } from '../../../shared' | 7 | import { VideoPrivacy, VideoResolution } from '../../../shared' |
8 | import { VideoTorrentObject } from '../../../shared/models/activitypub/objects/video-torrent-object' | 8 | import { VideoTorrentObject } from '../../../shared/models/activitypub/objects/video-torrent-object' |
9 | import { activityPubCollection } from '../../helpers/activitypub' | 9 | import { activityPubCollection } from '../../helpers/activitypub' |
10 | import { isVideoCategoryValid, isVideoLanguageValid, isVideoPrivacyValid, isVideoUrlValid } from '../../helpers/custom-validators/videos' | 10 | import { createTorrentPromise, renamePromise, statPromise, unlinkPromise, writeFilePromise } from '../../helpers/core-utils' |
11 | import { isVideoCategoryValid, isVideoLanguageValid, isVideoPrivacyValid } from '../../helpers/custom-validators/videos' | ||
12 | import { generateImageFromVideoFile, getVideoFileHeight, transcode } from '../../helpers/ffmpeg-utils' | ||
13 | import { | ||
14 | isActivityPubUrlValid, | ||
15 | isVideoDescriptionValid, | ||
16 | isVideoDurationValid, | ||
17 | isVideoLicenceValid, | ||
18 | isVideoNameValid, | ||
19 | isVideoNSFWValid | ||
20 | } from '../../helpers/index' | ||
21 | import { logger } from '../../helpers/logger' | ||
11 | import { | 22 | import { |
12 | API_VERSION, | 23 | API_VERSION, |
13 | CONFIG, | 24 | CONFIG, |
@@ -21,18 +32,12 @@ import { | |||
21 | VIDEO_LICENCES, | 32 | VIDEO_LICENCES, |
22 | VIDEO_PRIVACIES | 33 | VIDEO_PRIVACIES |
23 | } from '../../initializers/constants' | 34 | } from '../../initializers/constants' |
35 | import { getAnnounceActivityPubUrl } from '../../lib/activitypub/url' | ||
24 | import { sendDeleteVideo } from '../../lib/index' | 36 | import { sendDeleteVideo } from '../../lib/index' |
25 | |||
26 | import { addMethodsToModel, getSort } from '../utils' | 37 | import { addMethodsToModel, getSort } from '../utils' |
27 | |||
28 | import { TagInstance } from './tag-interface' | 38 | import { TagInstance } from './tag-interface' |
29 | import { VideoFileInstance, VideoFileModel } from './video-file-interface' | 39 | import { VideoFileInstance, VideoFileModel } from './video-file-interface' |
30 | import { VideoAttributes, VideoInstance, VideoMethods } from './video-interface' | 40 | import { VideoAttributes, VideoInstance, VideoMethods } from './video-interface' |
31 | import { isVideoNameValid, isVideoLicenceValid, isVideoNSFWValid, isVideoDescriptionValid, isVideoDurationValid } from '../../helpers/index' | ||
32 | import { logger } from '../../helpers/logger' | ||
33 | import { generateImageFromVideoFile, transcode, getVideoFileHeight } from '../../helpers/ffmpeg-utils' | ||
34 | import { createTorrentPromise, writeFilePromise, unlinkPromise, renamePromise, statPromise } from '../../helpers/core-utils' | ||
35 | import { getAnnounceActivityPubUrl } from '../../lib/activitypub/url' | ||
36 | 41 | ||
37 | let Video: Sequelize.Model<VideoInstance, VideoAttributes> | 42 | let Video: Sequelize.Model<VideoInstance, VideoAttributes> |
38 | let getOriginalFile: VideoMethods.GetOriginalFile | 43 | let getOriginalFile: VideoMethods.GetOriginalFile |
@@ -205,7 +210,7 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da | |||
205 | allowNull: false, | 210 | allowNull: false, |
206 | validate: { | 211 | validate: { |
207 | urlValid: value => { | 212 | urlValid: value => { |
208 | const res = isVideoUrlValid(value) | 213 | const res = isActivityPubUrlValid(value) |
209 | if (res === false) throw new Error('Video URL is not valid.') | 214 | if (res === false) throw new Error('Video URL is not valid.') |
210 | } | 215 | } |
211 | } | 216 | } |
diff --git a/support/doc/server/code.md b/support/doc/server/code.md index f0ed62acc..7233eaf5b 100644 --- a/support/doc/server/code.md +++ b/support/doc/server/code.md | |||
@@ -55,10 +55,10 @@ If you want to test the decentralization feature, you can easily run 3 instances | |||
55 | 55 | ||
56 | The server is composed by: | 56 | The server is composed by: |
57 | 57 | ||
58 | * a REST API (throught Express framework) | 58 | * a REST API (Express framework) |
59 | * a WebTorrent Tracker | 59 | * a WebTorrent Tracker |
60 | 60 | ||
61 | A video is seeded by the server throught the [WebSeed](http://www.bittorrent.org/beps/bep_0019.html) protocol (HTTP). | 61 | A video is seeded by the server with the [WebSeed](http://www.bittorrent.org/beps/bep_0019.html) protocol (HTTP). |
62 | 62 | ||
63 | ![Architecture scheme](https://github.com/Chocobozzz/PeerTube/blob/master/support/doc/server/upload-video.png) | 63 | ![Architecture scheme](https://github.com/Chocobozzz/PeerTube/blob/master/support/doc/server/upload-video.png) |
64 | 64 | ||