aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/helpers
diff options
context:
space:
mode:
Diffstat (limited to 'server/helpers')
-rw-r--r--server/helpers/activitypub.ts4
-rw-r--r--server/helpers/captions-utils.ts4
-rw-r--r--server/helpers/core-utils.ts20
-rw-r--r--server/helpers/custom-validators/activitypub/activity.ts99
-rw-r--r--server/helpers/custom-validators/activitypub/actor.ts29
-rw-r--r--server/helpers/custom-validators/activitypub/announce.ts13
-rw-r--r--server/helpers/custom-validators/activitypub/cache-file.ts16
-rw-r--r--server/helpers/custom-validators/activitypub/flag.ts14
-rw-r--r--server/helpers/custom-validators/activitypub/misc.ts24
-rw-r--r--server/helpers/custom-validators/activitypub/rate.ts15
-rw-r--r--server/helpers/custom-validators/activitypub/undo.ts20
-rw-r--r--server/helpers/custom-validators/activitypub/video-comments.ts11
-rw-r--r--server/helpers/custom-validators/activitypub/videos.ts19
-rw-r--r--server/helpers/custom-validators/activitypub/view.ts10
-rw-r--r--server/helpers/custom-validators/misc.ts5
-rw-r--r--server/helpers/custom-validators/servers.ts11
-rw-r--r--server/helpers/custom-validators/user-notifications.ts23
-rw-r--r--server/helpers/custom-validators/users.ts5
-rw-r--r--server/helpers/custom-validators/video-captions.ts4
-rw-r--r--server/helpers/custom-validators/video-imports.ts4
-rw-r--r--server/helpers/custom-validators/videos.ts13
-rw-r--r--server/helpers/express-utils.ts4
-rw-r--r--server/helpers/ffmpeg-utils.ts10
-rw-r--r--server/helpers/image-utils.ts14
-rw-r--r--server/helpers/regexp.ts23
-rw-r--r--server/helpers/requests.ts9
-rw-r--r--server/helpers/utils.ts12
-rw-r--r--server/helpers/webtorrent.ts6
-rw-r--r--server/helpers/youtube-dl.ts4
29 files changed, 240 insertions, 205 deletions
diff --git a/server/helpers/activitypub.ts b/server/helpers/activitypub.ts
index 79b76fa0b..f1430055f 100644
--- a/server/helpers/activitypub.ts
+++ b/server/helpers/activitypub.ts
@@ -106,7 +106,7 @@ function buildSignedActivity (byActor: ActorModel, data: Object) {
106 return signJsonLDObject(byActor, activity) as Promise<Activity> 106 return signJsonLDObject(byActor, activity) as Promise<Activity>
107} 107}
108 108
109function getAPUrl (activity: string | { id: string }) { 109function getAPId (activity: string | { id: string }) {
110 if (typeof activity === 'string') return activity 110 if (typeof activity === 'string') return activity
111 111
112 return activity.id 112 return activity.id
@@ -123,7 +123,7 @@ function checkUrlsSameHost (url1: string, url2: string) {
123 123
124export { 124export {
125 checkUrlsSameHost, 125 checkUrlsSameHost,
126 getAPUrl, 126 getAPId,
127 activityPubContextify, 127 activityPubContextify,
128 activityPubCollectionPagination, 128 activityPubCollectionPagination,
129 buildSignedActivity 129 buildSignedActivity
diff --git a/server/helpers/captions-utils.ts b/server/helpers/captions-utils.ts
index 660dce65c..0fb11a125 100644
--- a/server/helpers/captions-utils.ts
+++ b/server/helpers/captions-utils.ts
@@ -2,7 +2,7 @@ import { join } from 'path'
2import { CONFIG } from '../initializers' 2import { CONFIG } from '../initializers'
3import { VideoCaptionModel } from '../models/video/video-caption' 3import { VideoCaptionModel } from '../models/video/video-caption'
4import * as srt2vtt from 'srt-to-vtt' 4import * as srt2vtt from 'srt-to-vtt'
5import { createReadStream, createWriteStream, remove, rename } from 'fs-extra' 5import { createReadStream, createWriteStream, remove, move } from 'fs-extra'
6 6
7async function moveAndProcessCaptionFile (physicalFile: { filename: string, path: string }, videoCaption: VideoCaptionModel) { 7async function moveAndProcessCaptionFile (physicalFile: { filename: string, path: string }, videoCaption: VideoCaptionModel) {
8 const videoCaptionsDir = CONFIG.STORAGE.CAPTIONS_DIR 8 const videoCaptionsDir = CONFIG.STORAGE.CAPTIONS_DIR
@@ -13,7 +13,7 @@ async function moveAndProcessCaptionFile (physicalFile: { filename: string, path
13 await convertSrtToVtt(physicalFile.path, destination) 13 await convertSrtToVtt(physicalFile.path, destination)
14 await remove(physicalFile.path) 14 await remove(physicalFile.path)
15 } else { // Just move the vtt file 15 } else { // Just move the vtt file
16 await rename(physicalFile.path, destination) 16 await move(physicalFile.path, destination, { overwrite: true })
17 } 17 }
18 18
19 // This is important in case if there is another attempt in the retry process 19 // This is important in case if there is another attempt in the retry process
diff --git a/server/helpers/core-utils.ts b/server/helpers/core-utils.ts
index 84e33c0e9..3fb824e36 100644
--- a/server/helpers/core-utils.ts
+++ b/server/helpers/core-utils.ts
@@ -11,6 +11,25 @@ import * as pem from 'pem'
11import { URL } from 'url' 11import { URL } from 'url'
12import { truncate } from 'lodash' 12import { truncate } from 'lodash'
13import { exec } from 'child_process' 13import { exec } from 'child_process'
14import { isArray } from './custom-validators/misc'
15
16const objectConverter = (oldObject: any, keyConverter: (e: string) => string, valueConverter: (e: any) => any) => {
17 if (!oldObject || typeof oldObject !== 'object') {
18 return valueConverter(oldObject)
19 }
20
21 if (isArray(oldObject)) {
22 return oldObject.map(e => objectConverter(e, keyConverter, valueConverter))
23 }
24
25 const newObject = {}
26 Object.keys(oldObject).forEach(oldKey => {
27 const newKey = keyConverter(oldKey)
28 newObject[ newKey ] = objectConverter(oldObject[ oldKey ], keyConverter, valueConverter)
29 })
30
31 return newObject
32}
14 33
15const timeTable = { 34const timeTable = {
16 ms: 1, 35 ms: 1,
@@ -235,6 +254,7 @@ export {
235 isTestInstance, 254 isTestInstance,
236 isProdInstance, 255 isProdInstance,
237 256
257 objectConverter,
238 root, 258 root,
239 escapeHTML, 259 escapeHTML,
240 pageToStartAndCount, 260 pageToStartAndCount,
diff --git a/server/helpers/custom-validators/activitypub/activity.ts b/server/helpers/custom-validators/activitypub/activity.ts
index 2562ead9b..b24590d9d 100644
--- a/server/helpers/custom-validators/activitypub/activity.ts
+++ b/server/helpers/custom-validators/activitypub/activity.ts
@@ -1,26 +1,14 @@
1import * as validator from 'validator' 1import * as validator from 'validator'
2import { Activity, ActivityType } from '../../../../shared/models/activitypub' 2import { Activity, ActivityType } from '../../../../shared/models/activitypub'
3import { 3import { sanitizeAndCheckActorObject } from './actor'
4 isActorAcceptActivityValid, 4import { isActivityPubUrlValid, isBaseActivityValid, isObjectValid } from './misc'
5 isActorDeleteActivityValid, 5import { isDislikeActivityValid } from './rate'
6 isActorFollowActivityValid, 6import { sanitizeAndCheckVideoCommentObject } from './video-comments'
7 isActorRejectActivityValid, 7import { sanitizeAndCheckVideoTorrentObject } from './videos'
8 isActorUpdateActivityValid
9} from './actor'
10import { isAnnounceActivityValid } from './announce'
11import { isActivityPubUrlValid } from './misc'
12import { isDislikeActivityValid, isLikeActivityValid } from './rate'
13import { isUndoActivityValid } from './undo'
14import { isVideoCommentCreateActivityValid, isVideoCommentDeleteActivityValid } from './video-comments'
15import {
16 isVideoFlagValid,
17 isVideoTorrentDeleteActivityValid,
18 sanitizeAndCheckVideoTorrentCreateActivity,
19 sanitizeAndCheckVideoTorrentUpdateActivity
20} from './videos'
21import { isViewActivityValid } from './view' 8import { isViewActivityValid } from './view'
22import { exists } from '../misc' 9import { exists } from '../misc'
23import { isCacheFileCreateActivityValid, isCacheFileUpdateActivityValid } from './cache-file' 10import { isCacheFileObjectValid } from './cache-file'
11import { isFlagActivityValid } from './flag'
24 12
25function isRootActivityValid (activity: any) { 13function isRootActivityValid (activity: any) {
26 return Array.isArray(activity['@context']) && ( 14 return Array.isArray(activity['@context']) && (
@@ -46,7 +34,10 @@ const activityCheckers: { [ P in ActivityType ]: (activity: Activity) => boolean
46 Reject: checkRejectActivity, 34 Reject: checkRejectActivity,
47 Announce: checkAnnounceActivity, 35 Announce: checkAnnounceActivity,
48 Undo: checkUndoActivity, 36 Undo: checkUndoActivity,
49 Like: checkLikeActivity 37 Like: checkLikeActivity,
38 View: checkViewActivity,
39 Flag: checkFlagActivity,
40 Dislike: checkDislikeActivity
50} 41}
51 42
52function isActivityValid (activity: any) { 43function isActivityValid (activity: any) {
@@ -66,47 +57,79 @@ export {
66 57
67// --------------------------------------------------------------------------- 58// ---------------------------------------------------------------------------
68 59
60function checkViewActivity (activity: any) {
61 return isBaseActivityValid(activity, 'View') &&
62 isViewActivityValid(activity)
63}
64
65function checkFlagActivity (activity: any) {
66 return isBaseActivityValid(activity, 'Flag') &&
67 isFlagActivityValid(activity)
68}
69
70function checkDislikeActivity (activity: any) {
71 return isBaseActivityValid(activity, 'Dislike') &&
72 isDislikeActivityValid(activity)
73}
74
69function checkCreateActivity (activity: any) { 75function checkCreateActivity (activity: any) {
70 return isViewActivityValid(activity) || 76 return isBaseActivityValid(activity, 'Create') &&
71 isDislikeActivityValid(activity) || 77 (
72 sanitizeAndCheckVideoTorrentCreateActivity(activity) || 78 isViewActivityValid(activity.object) ||
73 isVideoFlagValid(activity) || 79 isDislikeActivityValid(activity.object) ||
74 isVideoCommentCreateActivityValid(activity) || 80 isFlagActivityValid(activity.object) ||
75 isCacheFileCreateActivityValid(activity) 81
82 isCacheFileObjectValid(activity.object) ||
83 sanitizeAndCheckVideoCommentObject(activity.object) ||
84 sanitizeAndCheckVideoTorrentObject(activity.object)
85 )
76} 86}
77 87
78function checkUpdateActivity (activity: any) { 88function checkUpdateActivity (activity: any) {
79 return isCacheFileUpdateActivityValid(activity) || 89 return isBaseActivityValid(activity, 'Update') &&
80 sanitizeAndCheckVideoTorrentUpdateActivity(activity) || 90 (
81 isActorUpdateActivityValid(activity) 91 isCacheFileObjectValid(activity.object) ||
92 sanitizeAndCheckVideoTorrentObject(activity.object) ||
93 sanitizeAndCheckActorObject(activity.object)
94 )
82} 95}
83 96
84function checkDeleteActivity (activity: any) { 97function checkDeleteActivity (activity: any) {
85 return isVideoTorrentDeleteActivityValid(activity) || 98 // We don't really check objects
86 isActorDeleteActivityValid(activity) || 99 return isBaseActivityValid(activity, 'Delete') &&
87 isVideoCommentDeleteActivityValid(activity) 100 isObjectValid(activity.object)
88} 101}
89 102
90function checkFollowActivity (activity: any) { 103function checkFollowActivity (activity: any) {
91 return isActorFollowActivityValid(activity) 104 return isBaseActivityValid(activity, 'Follow') &&
105 isObjectValid(activity.object)
92} 106}
93 107
94function checkAcceptActivity (activity: any) { 108function checkAcceptActivity (activity: any) {
95 return isActorAcceptActivityValid(activity) 109 return isBaseActivityValid(activity, 'Accept')
96} 110}
97 111
98function checkRejectActivity (activity: any) { 112function checkRejectActivity (activity: any) {
99 return isActorRejectActivityValid(activity) 113 return isBaseActivityValid(activity, 'Reject')
100} 114}
101 115
102function checkAnnounceActivity (activity: any) { 116function checkAnnounceActivity (activity: any) {
103 return isAnnounceActivityValid(activity) 117 return isBaseActivityValid(activity, 'Announce') &&
118 isObjectValid(activity.object)
104} 119}
105 120
106function checkUndoActivity (activity: any) { 121function checkUndoActivity (activity: any) {
107 return isUndoActivityValid(activity) 122 return isBaseActivityValid(activity, 'Undo') &&
123 (
124 checkFollowActivity(activity.object) ||
125 checkLikeActivity(activity.object) ||
126 checkDislikeActivity(activity.object) ||
127 checkAnnounceActivity(activity.object) ||
128 checkCreateActivity(activity.object)
129 )
108} 130}
109 131
110function checkLikeActivity (activity: any) { 132function checkLikeActivity (activity: any) {
111 return isLikeActivityValid(activity) 133 return isBaseActivityValid(activity, 'Like') &&
134 isObjectValid(activity.object)
112} 135}
diff --git a/server/helpers/custom-validators/activitypub/actor.ts b/server/helpers/custom-validators/activitypub/actor.ts
index 77c003cdf..c05f60f14 100644
--- a/server/helpers/custom-validators/activitypub/actor.ts
+++ b/server/helpers/custom-validators/activitypub/actor.ts
@@ -27,7 +27,8 @@ function isActorPublicKeyValid (publicKey: string) {
27 validator.isLength(publicKey, CONSTRAINTS_FIELDS.ACTORS.PUBLIC_KEY) 27 validator.isLength(publicKey, CONSTRAINTS_FIELDS.ACTORS.PUBLIC_KEY)
28} 28}
29 29
30const actorNameRegExp = new RegExp('^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\\-_\.]+$') 30const actorNameAlphabet = '[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\\-_.]'
31const actorNameRegExp = new RegExp(`^${actorNameAlphabet}+$`)
31function isActorPreferredUsernameValid (preferredUsername: string) { 32function isActorPreferredUsernameValid (preferredUsername: string) {
32 return exists(preferredUsername) && validator.matches(preferredUsername, actorNameRegExp) 33 return exists(preferredUsername) && validator.matches(preferredUsername, actorNameRegExp)
33} 34}
@@ -72,24 +73,10 @@ function isActorDeleteActivityValid (activity: any) {
72 return isBaseActivityValid(activity, 'Delete') 73 return isBaseActivityValid(activity, 'Delete')
73} 74}
74 75
75function isActorFollowActivityValid (activity: any) { 76function sanitizeAndCheckActorObject (object: any) {
76 return isBaseActivityValid(activity, 'Follow') && 77 normalizeActor(object)
77 isActivityPubUrlValid(activity.object)
78}
79
80function isActorAcceptActivityValid (activity: any) {
81 return isBaseActivityValid(activity, 'Accept')
82}
83
84function isActorRejectActivityValid (activity: any) {
85 return isBaseActivityValid(activity, 'Reject')
86}
87
88function isActorUpdateActivityValid (activity: any) {
89 normalizeActor(activity.object)
90 78
91 return isBaseActivityValid(activity, 'Update') && 79 return isActorObjectValid(object)
92 isActorObjectValid(activity.object)
93} 80}
94 81
95function normalizeActor (actor: any) { 82function normalizeActor (actor: any) {
@@ -127,6 +114,7 @@ function areValidActorHandles (handles: string[]) {
127 114
128export { 115export {
129 normalizeActor, 116 normalizeActor,
117 actorNameAlphabet,
130 areValidActorHandles, 118 areValidActorHandles,
131 isActorEndpointsObjectValid, 119 isActorEndpointsObjectValid,
132 isActorPublicKeyObjectValid, 120 isActorPublicKeyObjectValid,
@@ -137,10 +125,7 @@ export {
137 isActorObjectValid, 125 isActorObjectValid,
138 isActorFollowingCountValid, 126 isActorFollowingCountValid,
139 isActorFollowersCountValid, 127 isActorFollowersCountValid,
140 isActorFollowActivityValid,
141 isActorAcceptActivityValid,
142 isActorRejectActivityValid,
143 isActorDeleteActivityValid, 128 isActorDeleteActivityValid,
144 isActorUpdateActivityValid, 129 sanitizeAndCheckActorObject,
145 isValidActorHandle 130 isValidActorHandle
146} 131}
diff --git a/server/helpers/custom-validators/activitypub/announce.ts b/server/helpers/custom-validators/activitypub/announce.ts
deleted file mode 100644
index 0519c6026..000000000
--- a/server/helpers/custom-validators/activitypub/announce.ts
+++ /dev/null
@@ -1,13 +0,0 @@
1import { isActivityPubUrlValid, isBaseActivityValid } from './misc'
2
3function isAnnounceActivityValid (activity: any) {
4 return isBaseActivityValid(activity, 'Announce') &&
5 (
6 isActivityPubUrlValid(activity.object) ||
7 (activity.object && isActivityPubUrlValid(activity.object.id))
8 )
9}
10
11export {
12 isAnnounceActivityValid
13}
diff --git a/server/helpers/custom-validators/activitypub/cache-file.ts b/server/helpers/custom-validators/activitypub/cache-file.ts
index bd70934c8..e2bd0c55e 100644
--- a/server/helpers/custom-validators/activitypub/cache-file.ts
+++ b/server/helpers/custom-validators/activitypub/cache-file.ts
@@ -1,18 +1,8 @@
1import { isActivityPubUrlValid, isBaseActivityValid } from './misc' 1import { isActivityPubUrlValid } from './misc'
2import { isRemoteVideoUrlValid } from './videos' 2import { isRemoteVideoUrlValid } from './videos'
3import { isDateValid, exists } from '../misc' 3import { exists, isDateValid } from '../misc'
4import { CacheFileObject } from '../../../../shared/models/activitypub/objects' 4import { CacheFileObject } from '../../../../shared/models/activitypub/objects'
5 5
6function isCacheFileCreateActivityValid (activity: any) {
7 return isBaseActivityValid(activity, 'Create') &&
8 isCacheFileObjectValid(activity.object)
9}
10
11function isCacheFileUpdateActivityValid (activity: any) {
12 return isBaseActivityValid(activity, 'Update') &&
13 isCacheFileObjectValid(activity.object)
14}
15
16function isCacheFileObjectValid (object: CacheFileObject) { 6function isCacheFileObjectValid (object: CacheFileObject) {
17 return exists(object) && 7 return exists(object) &&
18 object.type === 'CacheFile' && 8 object.type === 'CacheFile' &&
@@ -22,7 +12,5 @@ function isCacheFileObjectValid (object: CacheFileObject) {
22} 12}
23 13
24export { 14export {
25 isCacheFileUpdateActivityValid,
26 isCacheFileCreateActivityValid,
27 isCacheFileObjectValid 15 isCacheFileObjectValid
28} 16}
diff --git a/server/helpers/custom-validators/activitypub/flag.ts b/server/helpers/custom-validators/activitypub/flag.ts
new file mode 100644
index 000000000..6452e297c
--- /dev/null
+++ b/server/helpers/custom-validators/activitypub/flag.ts
@@ -0,0 +1,14 @@
1import { isActivityPubUrlValid } from './misc'
2import { isVideoAbuseReasonValid } from '../video-abuses'
3
4function isFlagActivityValid (activity: any) {
5 return activity.type === 'Flag' &&
6 isVideoAbuseReasonValid(activity.content) &&
7 isActivityPubUrlValid(activity.object)
8}
9
10// ---------------------------------------------------------------------------
11
12export {
13 isFlagActivityValid
14}
diff --git a/server/helpers/custom-validators/activitypub/misc.ts b/server/helpers/custom-validators/activitypub/misc.ts
index 4e2c57f04..f1762d11c 100644
--- a/server/helpers/custom-validators/activitypub/misc.ts
+++ b/server/helpers/custom-validators/activitypub/misc.ts
@@ -28,15 +28,20 @@ function isBaseActivityValid (activity: any, type: string) {
28 return (activity['@context'] === undefined || Array.isArray(activity['@context'])) && 28 return (activity['@context'] === undefined || Array.isArray(activity['@context'])) &&
29 activity.type === type && 29 activity.type === type &&
30 isActivityPubUrlValid(activity.id) && 30 isActivityPubUrlValid(activity.id) &&
31 exists(activity.actor) && 31 isObjectValid(activity.actor) &&
32 (isActivityPubUrlValid(activity.actor) || isActivityPubUrlValid(activity.actor.id)) && 32 isUrlCollectionValid(activity.to) &&
33 ( 33 isUrlCollectionValid(activity.cc)
34 activity.to === undefined || 34}
35 (Array.isArray(activity.to) && activity.to.every(t => isActivityPubUrlValid(t))) 35
36 ) && 36function isUrlCollectionValid (collection: any) {
37 return collection === undefined ||
38 (Array.isArray(collection) && collection.every(t => isActivityPubUrlValid(t)))
39}
40
41function isObjectValid (object: any) {
42 return exists(object) &&
37 ( 43 (
38 activity.cc === undefined || 44 isActivityPubUrlValid(object) || isActivityPubUrlValid(object.id)
39 (Array.isArray(activity.cc) && activity.cc.every(t => isActivityPubUrlValid(t)))
40 ) 45 )
41} 46}
42 47
@@ -57,5 +62,6 @@ export {
57 isUrlValid, 62 isUrlValid,
58 isActivityPubUrlValid, 63 isActivityPubUrlValid,
59 isBaseActivityValid, 64 isBaseActivityValid,
60 setValidAttributedTo 65 setValidAttributedTo,
66 isObjectValid
61} 67}
diff --git a/server/helpers/custom-validators/activitypub/rate.ts b/server/helpers/custom-validators/activitypub/rate.ts
index e70bd94b8..ba68e8074 100644
--- a/server/helpers/custom-validators/activitypub/rate.ts
+++ b/server/helpers/custom-validators/activitypub/rate.ts
@@ -1,20 +1,13 @@
1import { isActivityPubUrlValid, isBaseActivityValid } from './misc' 1import { isActivityPubUrlValid, isObjectValid } from './misc'
2
3function isLikeActivityValid (activity: any) {
4 return isBaseActivityValid(activity, 'Like') &&
5 isActivityPubUrlValid(activity.object)
6}
7 2
8function isDislikeActivityValid (activity: any) { 3function isDislikeActivityValid (activity: any) {
9 return isBaseActivityValid(activity, 'Create') && 4 return activity.type === 'Dislike' &&
10 activity.object.type === 'Dislike' && 5 isActivityPubUrlValid(activity.actor) &&
11 isActivityPubUrlValid(activity.object.actor) && 6 isObjectValid(activity.object)
12 isActivityPubUrlValid(activity.object.object)
13} 7}
14 8
15// --------------------------------------------------------------------------- 9// ---------------------------------------------------------------------------
16 10
17export { 11export {
18 isLikeActivityValid,
19 isDislikeActivityValid 12 isDislikeActivityValid
20} 13}
diff --git a/server/helpers/custom-validators/activitypub/undo.ts b/server/helpers/custom-validators/activitypub/undo.ts
deleted file mode 100644
index 578035893..000000000
--- a/server/helpers/custom-validators/activitypub/undo.ts
+++ /dev/null
@@ -1,20 +0,0 @@
1import { isActorFollowActivityValid } from './actor'
2import { isBaseActivityValid } from './misc'
3import { isDislikeActivityValid, isLikeActivityValid } from './rate'
4import { isAnnounceActivityValid } from './announce'
5import { isCacheFileCreateActivityValid } from './cache-file'
6
7function isUndoActivityValid (activity: any) {
8 return isBaseActivityValid(activity, 'Undo') &&
9 (
10 isActorFollowActivityValid(activity.object) ||
11 isLikeActivityValid(activity.object) ||
12 isDislikeActivityValid(activity.object) ||
13 isAnnounceActivityValid(activity.object) ||
14 isCacheFileCreateActivityValid(activity.object)
15 )
16}
17
18export {
19 isUndoActivityValid
20}
diff --git a/server/helpers/custom-validators/activitypub/video-comments.ts b/server/helpers/custom-validators/activitypub/video-comments.ts
index 051c4565a..0415db21c 100644
--- a/server/helpers/custom-validators/activitypub/video-comments.ts
+++ b/server/helpers/custom-validators/activitypub/video-comments.ts
@@ -3,11 +3,6 @@ import { ACTIVITY_PUB, CONSTRAINTS_FIELDS } from '../../../initializers'
3import { exists, isArray, isDateValid } from '../misc' 3import { exists, isArray, isDateValid } from '../misc'
4import { isActivityPubUrlValid, isBaseActivityValid } from './misc' 4import { isActivityPubUrlValid, isBaseActivityValid } from './misc'
5 5
6function isVideoCommentCreateActivityValid (activity: any) {
7 return isBaseActivityValid(activity, 'Create') &&
8 sanitizeAndCheckVideoCommentObject(activity.object)
9}
10
11function sanitizeAndCheckVideoCommentObject (comment: any) { 6function sanitizeAndCheckVideoCommentObject (comment: any) {
12 if (!comment || comment.type !== 'Note') return false 7 if (!comment || comment.type !== 'Note') return false
13 8
@@ -25,15 +20,9 @@ function sanitizeAndCheckVideoCommentObject (comment: any) {
25 ) // Only accept public comments 20 ) // Only accept public comments
26} 21}
27 22
28function isVideoCommentDeleteActivityValid (activity: any) {
29 return isBaseActivityValid(activity, 'Delete')
30}
31
32// --------------------------------------------------------------------------- 23// ---------------------------------------------------------------------------
33 24
34export { 25export {
35 isVideoCommentCreateActivityValid,
36 isVideoCommentDeleteActivityValid,
37 sanitizeAndCheckVideoCommentObject 26 sanitizeAndCheckVideoCommentObject
38} 27}
39 28
diff --git a/server/helpers/custom-validators/activitypub/videos.ts b/server/helpers/custom-validators/activitypub/videos.ts
index 95fe824b9..0f34aab21 100644
--- a/server/helpers/custom-validators/activitypub/videos.ts
+++ b/server/helpers/custom-validators/activitypub/videos.ts
@@ -14,27 +14,11 @@ import { isActivityPubUrlValid, isBaseActivityValid, setValidAttributedTo } from
14import { VideoState } from '../../../../shared/models/videos' 14import { VideoState } from '../../../../shared/models/videos'
15import { isVideoAbuseReasonValid } from '../video-abuses' 15import { isVideoAbuseReasonValid } from '../video-abuses'
16 16
17function sanitizeAndCheckVideoTorrentCreateActivity (activity: any) {
18 return isBaseActivityValid(activity, 'Create') &&
19 sanitizeAndCheckVideoTorrentObject(activity.object)
20}
21
22function sanitizeAndCheckVideoTorrentUpdateActivity (activity: any) { 17function sanitizeAndCheckVideoTorrentUpdateActivity (activity: any) {
23 return isBaseActivityValid(activity, 'Update') && 18 return isBaseActivityValid(activity, 'Update') &&
24 sanitizeAndCheckVideoTorrentObject(activity.object) 19 sanitizeAndCheckVideoTorrentObject(activity.object)
25} 20}
26 21
27function isVideoTorrentDeleteActivityValid (activity: any) {
28 return isBaseActivityValid(activity, 'Delete')
29}
30
31function isVideoFlagValid (activity: any) {
32 return isBaseActivityValid(activity, 'Create') &&
33 activity.object.type === 'Flag' &&
34 isVideoAbuseReasonValid(activity.object.content) &&
35 isActivityPubUrlValid(activity.object.object)
36}
37
38function isActivityPubVideoDurationValid (value: string) { 22function isActivityPubVideoDurationValid (value: string) {
39 // https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration 23 // https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration
40 return exists(value) && 24 return exists(value) &&
@@ -103,11 +87,8 @@ function isRemoteVideoUrlValid (url: any) {
103// --------------------------------------------------------------------------- 87// ---------------------------------------------------------------------------
104 88
105export { 89export {
106 sanitizeAndCheckVideoTorrentCreateActivity,
107 sanitizeAndCheckVideoTorrentUpdateActivity, 90 sanitizeAndCheckVideoTorrentUpdateActivity,
108 isVideoTorrentDeleteActivityValid,
109 isRemoteStringIdentifierValid, 91 isRemoteStringIdentifierValid,
110 isVideoFlagValid,
111 sanitizeAndCheckVideoTorrentObject, 92 sanitizeAndCheckVideoTorrentObject,
112 isRemoteVideoUrlValid 93 isRemoteVideoUrlValid
113} 94}
diff --git a/server/helpers/custom-validators/activitypub/view.ts b/server/helpers/custom-validators/activitypub/view.ts
index 7a3aca6f5..41d16469f 100644
--- a/server/helpers/custom-validators/activitypub/view.ts
+++ b/server/helpers/custom-validators/activitypub/view.ts
@@ -1,11 +1,11 @@
1import { isActivityPubUrlValid, isBaseActivityValid } from './misc' 1import { isActivityPubUrlValid } from './misc'
2 2
3function isViewActivityValid (activity: any) { 3function isViewActivityValid (activity: any) {
4 return isBaseActivityValid(activity, 'Create') && 4 return activity.type === 'View' &&
5 activity.object.type === 'View' && 5 isActivityPubUrlValid(activity.actor) &&
6 isActivityPubUrlValid(activity.object.actor) && 6 isActivityPubUrlValid(activity.object)
7 isActivityPubUrlValid(activity.object.object)
8} 7}
8
9// --------------------------------------------------------------------------- 9// ---------------------------------------------------------------------------
10 10
11export { 11export {
diff --git a/server/helpers/custom-validators/misc.ts b/server/helpers/custom-validators/misc.ts
index 6d10a65a8..b6f0ebe6f 100644
--- a/server/helpers/custom-validators/misc.ts
+++ b/server/helpers/custom-validators/misc.ts
@@ -9,6 +9,10 @@ function isArray (value: any) {
9 return Array.isArray(value) 9 return Array.isArray(value)
10} 10}
11 11
12function isNotEmptyIntArray (value: any) {
13 return Array.isArray(value) && value.every(v => validator.isInt('' + v)) && value.length !== 0
14}
15
12function isDateValid (value: string) { 16function isDateValid (value: string) {
13 return exists(value) && validator.isISO8601(value) 17 return exists(value) && validator.isISO8601(value)
14} 18}
@@ -78,6 +82,7 @@ function isFileValid (
78 82
79export { 83export {
80 exists, 84 exists,
85 isNotEmptyIntArray,
81 isArray, 86 isArray,
82 isIdValid, 87 isIdValid,
83 isUUIDValid, 88 isUUIDValid,
diff --git a/server/helpers/custom-validators/servers.ts b/server/helpers/custom-validators/servers.ts
index d5021bf38..18c80ec8f 100644
--- a/server/helpers/custom-validators/servers.ts
+++ b/server/helpers/custom-validators/servers.ts
@@ -3,6 +3,7 @@ import 'express-validator'
3 3
4import { isArray, exists } from './misc' 4import { isArray, exists } from './misc'
5import { isTestInstance } from '../core-utils' 5import { isTestInstance } from '../core-utils'
6import { CONSTRAINTS_FIELDS } from '../../initializers'
6 7
7function isHostValid (host: string) { 8function isHostValid (host: string) {
8 const isURLOptions = { 9 const isURLOptions = {
@@ -26,9 +27,19 @@ function isEachUniqueHostValid (hosts: string[]) {
26 }) 27 })
27} 28}
28 29
30function isValidContactBody (value: any) {
31 return exists(value) && validator.isLength(value, CONSTRAINTS_FIELDS.CONTACT_FORM.BODY)
32}
33
34function isValidContactFromName (value: any) {
35 return exists(value) && validator.isLength(value, CONSTRAINTS_FIELDS.CONTACT_FORM.FROM_NAME)
36}
37
29// --------------------------------------------------------------------------- 38// ---------------------------------------------------------------------------
30 39
31export { 40export {
41 isValidContactBody,
42 isValidContactFromName,
32 isEachUniqueHostValid, 43 isEachUniqueHostValid,
33 isHostValid 44 isHostValid
34} 45}
diff --git a/server/helpers/custom-validators/user-notifications.ts b/server/helpers/custom-validators/user-notifications.ts
new file mode 100644
index 000000000..02ea3bbc2
--- /dev/null
+++ b/server/helpers/custom-validators/user-notifications.ts
@@ -0,0 +1,23 @@
1import { exists } from './misc'
2import * as validator from 'validator'
3import { UserNotificationType } from '../../../shared/models/users'
4import { UserNotificationSettingValue } from '../../../shared/models/users/user-notification-setting.model'
5
6function isUserNotificationTypeValid (value: any) {
7 return exists(value) && validator.isInt('' + value) && UserNotificationType[value] !== undefined
8}
9
10function isUserNotificationSettingValid (value: any) {
11 return exists(value) &&
12 validator.isInt('' + value) && (
13 value === UserNotificationSettingValue.NONE ||
14 value === UserNotificationSettingValue.WEB ||
15 value === UserNotificationSettingValue.EMAIL ||
16 value === (UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL)
17 )
18}
19
20export {
21 isUserNotificationSettingValid,
22 isUserNotificationTypeValid
23}
diff --git a/server/helpers/custom-validators/users.ts b/server/helpers/custom-validators/users.ts
index 1cb5e5b0f..80652b479 100644
--- a/server/helpers/custom-validators/users.ts
+++ b/server/helpers/custom-validators/users.ts
@@ -46,6 +46,10 @@ function isUserWebTorrentEnabledValid (value: any) {
46 return isBooleanValid(value) 46 return isBooleanValid(value)
47} 47}
48 48
49function isUserVideosHistoryEnabledValid (value: any) {
50 return isBooleanValid(value)
51}
52
49function isUserAutoPlayVideoValid (value: any) { 53function isUserAutoPlayVideoValid (value: any) {
50 return isBooleanValid(value) 54 return isBooleanValid(value)
51} 55}
@@ -73,6 +77,7 @@ function isAvatarFile (files: { [ fieldname: string ]: Express.Multer.File[] } |
73// --------------------------------------------------------------------------- 77// ---------------------------------------------------------------------------
74 78
75export { 79export {
80 isUserVideosHistoryEnabledValid,
76 isUserBlockedValid, 81 isUserBlockedValid,
77 isUserPasswordValid, 82 isUserPasswordValid,
78 isUserBlockedReasonValid, 83 isUserBlockedReasonValid,
diff --git a/server/helpers/custom-validators/video-captions.ts b/server/helpers/custom-validators/video-captions.ts
index 177e9e86e..b33d90e18 100644
--- a/server/helpers/custom-validators/video-captions.ts
+++ b/server/helpers/custom-validators/video-captions.ts
@@ -1,4 +1,4 @@
1import { CONSTRAINTS_FIELDS, VIDEO_CAPTIONS_MIMETYPE_EXT, VIDEO_LANGUAGES } from '../../initializers' 1import { CONSTRAINTS_FIELDS, MIMETYPES, VIDEO_LANGUAGES } from '../../initializers'
2import { exists, isFileValid } from './misc' 2import { exists, isFileValid } from './misc'
3import { Response } from 'express' 3import { Response } from 'express'
4import { VideoModel } from '../../models/video/video' 4import { VideoModel } from '../../models/video/video'
@@ -8,7 +8,7 @@ function isVideoCaptionLanguageValid (value: any) {
8 return exists(value) && VIDEO_LANGUAGES[ value ] !== undefined 8 return exists(value) && VIDEO_LANGUAGES[ value ] !== undefined
9} 9}
10 10
11const videoCaptionTypes = Object.keys(VIDEO_CAPTIONS_MIMETYPE_EXT) 11const videoCaptionTypes = Object.keys(MIMETYPES.VIDEO_CAPTIONS.MIMETYPE_EXT)
12 .concat([ 'application/octet-stream' ]) // MacOS sends application/octet-stream >< 12 .concat([ 'application/octet-stream' ]) // MacOS sends application/octet-stream ><
13 .map(m => `(${m})`) 13 .map(m => `(${m})`)
14const videoCaptionTypesRegex = videoCaptionTypes.join('|') 14const videoCaptionTypesRegex = videoCaptionTypes.join('|')
diff --git a/server/helpers/custom-validators/video-imports.ts b/server/helpers/custom-validators/video-imports.ts
index 4d6ab1fa4..ce9e9193c 100644
--- a/server/helpers/custom-validators/video-imports.ts
+++ b/server/helpers/custom-validators/video-imports.ts
@@ -1,7 +1,7 @@
1import 'express-validator' 1import 'express-validator'
2import 'multer' 2import 'multer'
3import * as validator from 'validator' 3import * as validator from 'validator'
4import { CONSTRAINTS_FIELDS, TORRENT_MIMETYPE_EXT, VIDEO_IMPORT_STATES } from '../../initializers' 4import { CONSTRAINTS_FIELDS, MIMETYPES, VIDEO_IMPORT_STATES } from '../../initializers'
5import { exists, isFileValid } from './misc' 5import { exists, isFileValid } from './misc'
6import * as express from 'express' 6import * as express from 'express'
7import { VideoImportModel } from '../../models/video/video-import' 7import { VideoImportModel } from '../../models/video/video-import'
@@ -24,7 +24,7 @@ function isVideoImportStateValid (value: any) {
24 return exists(value) && VIDEO_IMPORT_STATES[ value ] !== undefined 24 return exists(value) && VIDEO_IMPORT_STATES[ value ] !== undefined
25} 25}
26 26
27const videoTorrentImportTypes = Object.keys(TORRENT_MIMETYPE_EXT).map(m => `(${m})`) 27const videoTorrentImportTypes = Object.keys(MIMETYPES.TORRENT.MIMETYPE_EXT).map(m => `(${m})`)
28const videoTorrentImportRegex = videoTorrentImportTypes.join('|') 28const videoTorrentImportRegex = videoTorrentImportTypes.join('|')
29function isVideoImportTorrentFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) { 29function isVideoImportTorrentFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
30 return isFileValid(files, videoTorrentImportRegex, 'torrentfile', CONSTRAINTS_FIELDS.VIDEO_IMPORTS.TORRENT_FILE.FILE_SIZE.max, true) 30 return isFileValid(files, videoTorrentImportRegex, 'torrentfile', CONSTRAINTS_FIELDS.VIDEO_IMPORTS.TORRENT_FILE.FILE_SIZE.max, true)
diff --git a/server/helpers/custom-validators/videos.ts b/server/helpers/custom-validators/videos.ts
index a13b09ac8..95e256b8f 100644
--- a/server/helpers/custom-validators/videos.ts
+++ b/server/helpers/custom-validators/videos.ts
@@ -5,10 +5,9 @@ import 'multer'
5import * as validator from 'validator' 5import * as validator from 'validator'
6import { UserRight, VideoFilter, VideoPrivacy, VideoRateType } from '../../../shared' 6import { UserRight, VideoFilter, VideoPrivacy, VideoRateType } from '../../../shared'
7import { 7import {
8 CONSTRAINTS_FIELDS, 8 CONSTRAINTS_FIELDS, MIMETYPES,
9 VIDEO_CATEGORIES, 9 VIDEO_CATEGORIES,
10 VIDEO_LICENCES, 10 VIDEO_LICENCES,
11 VIDEO_MIMETYPE_EXT,
12 VIDEO_PRIVACIES, 11 VIDEO_PRIVACIES,
13 VIDEO_RATE_TYPES, 12 VIDEO_RATE_TYPES,
14 VIDEO_STATES 13 VIDEO_STATES
@@ -83,10 +82,15 @@ function isVideoRatingTypeValid (value: string) {
83 return value === 'none' || values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1 82 return value === 'none' || values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
84} 83}
85 84
86const videoFileTypes = Object.keys(VIDEO_MIMETYPE_EXT).map(m => `(${m})`) 85function isVideoFileExtnameValid (value: string) {
87const videoFileTypesRegex = videoFileTypes.join('|') 86 return exists(value) && MIMETYPES.VIDEO.EXT_MIMETYPE[value] !== undefined
87}
88 88
89function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) { 89function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
90 const videoFileTypesRegex = Object.keys(MIMETYPES.VIDEO.MIMETYPE_EXT)
91 .map(m => `(${m})`)
92 .join('|')
93
90 return isFileValid(files, videoFileTypesRegex, 'videofile', null) 94 return isFileValid(files, videoFileTypesRegex, 'videofile', null)
91} 95}
92 96
@@ -221,6 +225,7 @@ export {
221 isVideoStateValid, 225 isVideoStateValid,
222 isVideoViewsValid, 226 isVideoViewsValid,
223 isVideoRatingTypeValid, 227 isVideoRatingTypeValid,
228 isVideoFileExtnameValid,
224 isVideoDurationValid, 229 isVideoDurationValid,
225 isVideoTagValid, 230 isVideoTagValid,
226 isVideoPrivacyValid, 231 isVideoPrivacyValid,
diff --git a/server/helpers/express-utils.ts b/server/helpers/express-utils.ts
index 162fe2244..9a72ee96d 100644
--- a/server/helpers/express-utils.ts
+++ b/server/helpers/express-utils.ts
@@ -7,12 +7,12 @@ import { extname } from 'path'
7import { isArray } from './custom-validators/misc' 7import { isArray } from './custom-validators/misc'
8import { UserModel } from '../models/account/user' 8import { UserModel } from '../models/account/user'
9 9
10function buildNSFWFilter (res: express.Response, paramNSFW?: string) { 10function buildNSFWFilter (res?: express.Response, paramNSFW?: string) {
11 if (paramNSFW === 'true') return true 11 if (paramNSFW === 'true') return true
12 if (paramNSFW === 'false') return false 12 if (paramNSFW === 'false') return false
13 if (paramNSFW === 'both') return undefined 13 if (paramNSFW === 'both') return undefined
14 14
15 if (res.locals.oauth) { 15 if (res && res.locals.oauth) {
16 const user: UserModel = res.locals.oauth.token.User 16 const user: UserModel = res.locals.oauth.token.User
17 17
18 // User does not want NSFW videos 18 // User does not want NSFW videos
diff --git a/server/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts
index b59e7e40e..132f4690e 100644
--- a/server/helpers/ffmpeg-utils.ts
+++ b/server/helpers/ffmpeg-utils.ts
@@ -41,7 +41,7 @@ async function getVideoFileResolution (path: string) {
41async function getVideoFileFPS (path: string) { 41async function getVideoFileFPS (path: string) {
42 const videoStream = await getVideoFileStream(path) 42 const videoStream = await getVideoFileStream(path)
43 43
44 for (const key of [ 'r_frame_rate' , 'avg_frame_rate' ]) { 44 for (const key of [ 'avg_frame_rate', 'r_frame_rate' ]) {
45 const valuesText: string = videoStream[key] 45 const valuesText: string = videoStream[key]
46 if (!valuesText) continue 46 if (!valuesText) continue
47 47
@@ -184,7 +184,7 @@ function getVideoFileStream (path: string) {
184 if (err) return rej(err) 184 if (err) return rej(err)
185 185
186 const videoStream = metadata.streams.find(s => s.codec_type === 'video') 186 const videoStream = metadata.streams.find(s => s.codec_type === 'video')
187 if (!videoStream) throw new Error('Cannot find video stream of ' + path) 187 if (!videoStream) return rej(new Error('Cannot find video stream of ' + path))
188 188
189 return res(videoStream) 189 return res(videoStream)
190 }) 190 })
@@ -328,10 +328,10 @@ async function presetH264 (command: ffmpeg.FfmpegCommand, resolution: VideoResol
328 const audioCodecName = parsedAudio.audioStream[ 'codec_name' ] 328 const audioCodecName = parsedAudio.audioStream[ 'codec_name' ]
329 let bitrate: number 329 let bitrate: number
330 if (audio.bitrate[ audioCodecName ]) { 330 if (audio.bitrate[ audioCodecName ]) {
331 bitrate = audio.bitrate[ audioCodecName ](parsedAudio.audioStream[ 'bit_rate' ]) 331 localCommand = localCommand.audioCodec('aac')
332 332
333 if (bitrate === -1) localCommand = localCommand.audioCodec('copy') 333 bitrate = audio.bitrate[ audioCodecName ](parsedAudio.audioStream[ 'bit_rate' ])
334 else if (bitrate !== undefined) localCommand = localCommand.audioBitrate(bitrate) 334 if (bitrate !== undefined && bitrate !== -1) localCommand = localCommand.audioBitrate(bitrate)
335 } 335 }
336 } 336 }
337 337
diff --git a/server/helpers/image-utils.ts b/server/helpers/image-utils.ts
index da3285b13..e43ea3f1d 100644
--- a/server/helpers/image-utils.ts
+++ b/server/helpers/image-utils.ts
@@ -1,6 +1,7 @@
1import 'multer' 1import 'multer'
2import * as sharp from 'sharp' 2import * as sharp from 'sharp'
3import { move, remove } from 'fs-extra' 3import { readFile, remove } from 'fs-extra'
4import { logger } from './logger'
4 5
5async function processImage ( 6async function processImage (
6 physicalFile: { path: string }, 7 physicalFile: { path: string },
@@ -11,14 +12,11 @@ async function processImage (
11 throw new Error('Sharp needs an input path different that the output path.') 12 throw new Error('Sharp needs an input path different that the output path.')
12 } 13 }
13 14
14 const sharpInstance = sharp(physicalFile.path) 15 logger.debug('Processing image %s to %s.', physicalFile.path, destination)
15 const metadata = await sharpInstance.metadata()
16 16
17 // No need to resize 17 // Avoid sharp cache
18 if (metadata.width === newSize.width && metadata.height === newSize.height) { 18 const buf = await readFile(physicalFile.path)
19 await move(physicalFile.path, destination, { overwrite: true }) 19 const sharpInstance = sharp(buf)
20 return
21 }
22 20
23 await remove(destination) 21 await remove(destination)
24 22
diff --git a/server/helpers/regexp.ts b/server/helpers/regexp.ts
new file mode 100644
index 000000000..2336654b0
--- /dev/null
+++ b/server/helpers/regexp.ts
@@ -0,0 +1,23 @@
1// Thanks to https://regex101.com
2function regexpCapture (str: string, regex: RegExp, maxIterations = 100) {
3 let m: RegExpExecArray
4 let i = 0
5 let result: RegExpExecArray[] = []
6
7 // tslint:disable:no-conditional-assignment
8 while ((m = regex.exec(str)) !== null && i < maxIterations) {
9 // This is necessary to avoid infinite loops with zero-width matches
10 if (m.index === regex.lastIndex) {
11 regex.lastIndex++
12 }
13
14 result.push(m)
15 i++
16 }
17
18 return result
19}
20
21export {
22 regexpCapture
23}
diff --git a/server/helpers/requests.ts b/server/helpers/requests.ts
index 805930a9f..3fc776f1a 100644
--- a/server/helpers/requests.ts
+++ b/server/helpers/requests.ts
@@ -1,8 +1,9 @@
1import * as Bluebird from 'bluebird' 1import * as Bluebird from 'bluebird'
2import { createWriteStream } from 'fs-extra' 2import { createWriteStream } from 'fs-extra'
3import * as request from 'request' 3import * as request from 'request'
4import { ACTIVITY_PUB } from '../initializers' 4import { ACTIVITY_PUB, CONFIG } from '../initializers'
5import { processImage } from './image-utils' 5import { processImage } from './image-utils'
6import { join } from 'path'
6 7
7function doRequest <T> ( 8function doRequest <T> (
8 requestOptions: request.CoreOptions & request.UriOptions & { activityPub?: boolean } 9 requestOptions: request.CoreOptions & request.UriOptions & { activityPub?: boolean }
@@ -28,11 +29,11 @@ function doRequestAndSaveToFile (requestOptions: request.CoreOptions & request.U
28 }) 29 })
29} 30}
30 31
31async function downloadImage (url: string, destPath: string, size: { width: number, height: number }) { 32async function downloadImage (url: string, destDir: string, destName: string, size: { width: number, height: number }) {
32 const tmpPath = destPath + '.tmp' 33 const tmpPath = join(CONFIG.STORAGE.TMP_DIR, 'pending-' + destName)
33
34 await doRequestAndSaveToFile({ method: 'GET', uri: url }, tmpPath) 34 await doRequestAndSaveToFile({ method: 'GET', uri: url }, tmpPath)
35 35
36 const destPath = join(destDir, destName)
36 await processImage({ path: tmpPath }, destPath, size) 37 await processImage({ path: tmpPath }, destPath, size)
37} 38}
38 39
diff --git a/server/helpers/utils.ts b/server/helpers/utils.ts
index 5c9d6fe2f..3c3406e38 100644
--- a/server/helpers/utils.ts
+++ b/server/helpers/utils.ts
@@ -7,6 +7,7 @@ import { join } from 'path'
7import { Instance as ParseTorrent } from 'parse-torrent' 7import { Instance as ParseTorrent } from 'parse-torrent'
8import { remove } from 'fs-extra' 8import { remove } from 'fs-extra'
9import * as memoizee from 'memoizee' 9import * as memoizee from 'memoizee'
10import { isArray } from './custom-validators/misc'
10 11
11function deleteFileAsync (path: string) { 12function deleteFileAsync (path: string) {
12 remove(path) 13 remove(path)
@@ -19,10 +20,7 @@ async function generateRandomString (size: number) {
19 return raw.toString('hex') 20 return raw.toString('hex')
20} 21}
21 22
22interface FormattableToJSON { 23interface FormattableToJSON { toFormattedJSON (args?: any) }
23 toFormattedJSON (args?: any)
24}
25
26function getFormattedObjects<U, T extends FormattableToJSON> (objects: T[], objectsTotal: number, formattedArg?: any) { 24function getFormattedObjects<U, T extends FormattableToJSON> (objects: T[], objectsTotal: number, formattedArg?: any) {
27 const formattedObjects: U[] = [] 25 const formattedObjects: U[] = []
28 26
@@ -46,11 +44,11 @@ const getServerActor = memoizee(async function () {
46 return actor 44 return actor
47}) 45})
48 46
49function generateVideoTmpPath (target: string | ParseTorrent) { 47function generateVideoImportTmpPath (target: string | ParseTorrent) {
50 const id = typeof target === 'string' ? target : target.infoHash 48 const id = typeof target === 'string' ? target : target.infoHash
51 49
52 const hash = sha256(id) 50 const hash = sha256(id)
53 return join(CONFIG.STORAGE.VIDEOS_DIR, hash + '-import.mp4') 51 return join(CONFIG.STORAGE.TMP_DIR, hash + '-import.mp4')
54} 52}
55 53
56function getSecureTorrentName (originalName: string) { 54function getSecureTorrentName (originalName: string) {
@@ -103,6 +101,6 @@ export {
103 getSecureTorrentName, 101 getSecureTorrentName,
104 getServerActor, 102 getServerActor,
105 getServerCommit, 103 getServerCommit,
106 generateVideoTmpPath, 104 generateVideoImportTmpPath,
107 getUUIDFromFilename 105 getUUIDFromFilename
108} 106}
diff --git a/server/helpers/webtorrent.ts b/server/helpers/webtorrent.ts
index ce35b87da..3c9a0b96a 100644
--- a/server/helpers/webtorrent.ts
+++ b/server/helpers/webtorrent.ts
@@ -1,5 +1,5 @@
1import { logger } from './logger' 1import { logger } from './logger'
2import { generateVideoTmpPath } from './utils' 2import { generateVideoImportTmpPath } from './utils'
3import * as WebTorrent from 'webtorrent' 3import * as WebTorrent from 'webtorrent'
4import { createWriteStream, ensureDir, remove } from 'fs-extra' 4import { createWriteStream, ensureDir, remove } from 'fs-extra'
5import { CONFIG } from '../initializers' 5import { CONFIG } from '../initializers'
@@ -9,10 +9,10 @@ async function downloadWebTorrentVideo (target: { magnetUri: string, torrentName
9 const id = target.magnetUri || target.torrentName 9 const id = target.magnetUri || target.torrentName
10 let timer 10 let timer
11 11
12 const path = generateVideoTmpPath(id) 12 const path = generateVideoImportTmpPath(id)
13 logger.info('Importing torrent video %s', id) 13 logger.info('Importing torrent video %s', id)
14 14
15 const directoryPath = join(CONFIG.STORAGE.VIDEOS_DIR, 'import') 15 const directoryPath = join(CONFIG.STORAGE.TMP_DIR, 'webtorrent')
16 await ensureDir(directoryPath) 16 await ensureDir(directoryPath)
17 17
18 return new Promise<string>((res, rej) => { 18 return new Promise<string>((res, rej) => {
diff --git a/server/helpers/youtube-dl.ts b/server/helpers/youtube-dl.ts
index 2a5663042..b74351b42 100644
--- a/server/helpers/youtube-dl.ts
+++ b/server/helpers/youtube-dl.ts
@@ -1,7 +1,7 @@
1import { truncate } from 'lodash' 1import { truncate } from 'lodash'
2import { CONSTRAINTS_FIELDS, VIDEO_CATEGORIES } from '../initializers' 2import { CONSTRAINTS_FIELDS, VIDEO_CATEGORIES } from '../initializers'
3import { logger } from './logger' 3import { logger } from './logger'
4import { generateVideoTmpPath } from './utils' 4import { generateVideoImportTmpPath } from './utils'
5import { join } from 'path' 5import { join } from 'path'
6import { root } from './core-utils' 6import { root } from './core-utils'
7import { ensureDir, writeFile, remove } from 'fs-extra' 7import { ensureDir, writeFile, remove } from 'fs-extra'
@@ -40,7 +40,7 @@ function getYoutubeDLInfo (url: string, opts?: string[]): Promise<YoutubeDLInfo>
40} 40}
41 41
42function downloadYoutubeDLVideo (url: string, timeout: number) { 42function downloadYoutubeDLVideo (url: string, timeout: number) {
43 const path = generateVideoTmpPath(url) 43 const path = generateVideoImportTmpPath(url)
44 let timer 44 let timer
45 45
46 logger.info('Importing youtubeDL video %s', url) 46 logger.info('Importing youtubeDL video %s', url)