aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server/helpers/core-utils.ts18
-rw-r--r--server/helpers/custom-validators/activitypub/videos.ts12
-rw-r--r--server/lib/activitypub/process/process.ts2
-rw-r--r--server/models/video/video.ts21
4 files changed, 36 insertions, 17 deletions
diff --git a/server/helpers/core-utils.ts b/server/helpers/core-utils.ts
index 65f18d644..a3dfe27b5 100644
--- a/server/helpers/core-utils.ts
+++ b/server/helpers/core-utils.ts
@@ -12,6 +12,7 @@ import { isAbsolute, join } from 'path'
12import * as pem from 'pem' 12import * as pem from 'pem'
13import * as rimraf from 'rimraf' 13import * as rimraf from 'rimraf'
14import { URL } from 'url' 14import { URL } from 'url'
15import { truncate } from 'lodash'
15 16
16function sanitizeUrl (url: string) { 17function sanitizeUrl (url: string) {
17 const urlObject = new URL(url) 18 const urlObject = new URL(url)
@@ -78,6 +79,22 @@ function buildPath (path: string) {
78 return join(root(), path) 79 return join(root(), path)
79} 80}
80 81
82// Consistent with .length, lodash truncate function is not
83function peertubeTruncate (str: string, maxLength: number) {
84 const options = {
85 length: maxLength
86 }
87 const truncatedStr = truncate(str, options)
88
89 // The truncated string is okay, we can return it
90 if (truncatedStr.length <= maxLength) return truncatedStr
91
92 // Lodash takes into account all UTF characters, whereas String.prototype.length does not: some characters have a length of 2
93 // We always use the .length so we need to truncate more if needed
94 options.length -= truncatedStr.length - maxLength
95 return truncate(str, options)
96}
97
81function promisify0<A> (func: (cb: (err: any, result: A) => void) => void): () => Promise<A> { 98function promisify0<A> (func: (cb: (err: any, result: A) => void) => void): () => Promise<A> {
82 return function promisified (): Promise<A> { 99 return function promisified (): Promise<A> {
83 return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => { 100 return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => {
@@ -145,6 +162,7 @@ export {
145 sanitizeUrl, 162 sanitizeUrl,
146 sanitizeHost, 163 sanitizeHost,
147 buildPath, 164 buildPath,
165 peertubeTruncate,
148 166
149 promisify0, 167 promisify0,
150 promisify1, 168 promisify1,
diff --git a/server/helpers/custom-validators/activitypub/videos.ts b/server/helpers/custom-validators/activitypub/videos.ts
index 10588423a..3af587a32 100644
--- a/server/helpers/custom-validators/activitypub/videos.ts
+++ b/server/helpers/custom-validators/activitypub/videos.ts
@@ -1,5 +1,6 @@
1import * as validator from 'validator' 1import * as validator from 'validator'
2import { ACTIVITY_PUB } from '../../../initializers' 2import { ACTIVITY_PUB, CONSTRAINTS_FIELDS } from '../../../initializers'
3import { peertubeTruncate } from '../../core-utils'
3import { exists, isBooleanValid, isDateValid, isUUIDValid } from '../misc' 4import { exists, isBooleanValid, isDateValid, isUUIDValid } from '../misc'
4import { 5import {
5 isVideoAbuseReasonValid, 6 isVideoAbuseReasonValid,
@@ -56,6 +57,7 @@ function isVideoTorrentObjectValid (video: any) {
56 isBooleanValid(video.commentsEnabled) && 57 isBooleanValid(video.commentsEnabled) &&
57 isDateValid(video.published) && 58 isDateValid(video.published) &&
58 isDateValid(video.updated) && 59 isDateValid(video.updated) &&
60 setTruncatedContent(video) &&
59 (!video.content || isRemoteVideoContentValid(video.mediaType, video.content)) && 61 (!video.content || isRemoteVideoContentValid(video.mediaType, video.content)) &&
60 isRemoteVideoIconValid(video.icon) && 62 isRemoteVideoIconValid(video.icon) &&
61 setValidRemoteVideoUrls(video) && 63 setValidRemoteVideoUrls(video) &&
@@ -111,6 +113,14 @@ function setValidRemoteVideoUrls (video: any) {
111 return true 113 return true
112} 114}
113 115
116function setTruncatedContent (video: any) {
117 if (video.content) {
118 video.content = peertubeTruncate(video.content, CONSTRAINTS_FIELDS.VIDEOS.TRUNCATED_DESCRIPTION.max)
119 }
120
121 return true
122}
123
114function isRemoteVideoUrlValid (url: any) { 124function isRemoteVideoUrlValid (url: any) {
115 return url.type === 'Link' && 125 return url.type === 'Link' &&
116 ( 126 (
diff --git a/server/lib/activitypub/process/process.ts b/server/lib/activitypub/process/process.ts
index 10d8ba189..da91675ce 100644
--- a/server/lib/activitypub/process/process.ts
+++ b/server/lib/activitypub/process/process.ts
@@ -43,7 +43,7 @@ async function processActivities (activities: Activity[], signatureActor?: Actor
43 try { 43 try {
44 await activityProcessor(activity, inboxActor) 44 await activityProcessor(activity, inboxActor)
45 } catch (err) { 45 } catch (err) {
46 logger.warn('Cannot process activity %s.', activity.type, { error: err.stack }) 46 logger.warn('Cannot process activity %s.', activity.type, { err })
47 } 47 }
48 } 48 }
49} 49}
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index a28b5209b..7c56c65a6 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -1,5 +1,5 @@
1import * as Bluebird from 'bluebird' 1import * as Bluebird from 'bluebird'
2import { map, maxBy, truncate } from 'lodash' 2import { map, maxBy } from 'lodash'
3import * as magnetUtil from 'magnet-uri' 3import * as magnetUtil from 'magnet-uri'
4import * as parseTorrent from 'parse-torrent' 4import * as parseTorrent from 'parse-torrent'
5import { join } from 'path' 5import { join } from 'path'
@@ -31,7 +31,10 @@ import { VideoTorrentObject } from '../../../shared/models/activitypub/objects'
31import { Video, VideoDetails } from '../../../shared/models/videos' 31import { Video, VideoDetails } from '../../../shared/models/videos'
32import { VideoFilter } from '../../../shared/models/videos/video-query.type' 32import { VideoFilter } from '../../../shared/models/videos/video-query.type'
33import { activityPubCollection } from '../../helpers/activitypub' 33import { activityPubCollection } from '../../helpers/activitypub'
34import { createTorrentPromise, renamePromise, statPromise, unlinkPromise, writeFilePromise } from '../../helpers/core-utils' 34import {
35 createTorrentPromise, peertubeTruncate, renamePromise, statPromise, unlinkPromise,
36 writeFilePromise
37} from '../../helpers/core-utils'
35import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' 38import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
36import { isBooleanValid } from '../../helpers/custom-validators/misc' 39import { isBooleanValid } from '../../helpers/custom-validators/misc'
37import { 40import {
@@ -1191,19 +1194,7 @@ export class VideoModel extends Model<VideoModel> {
1191 if (!this.description) return null 1194 if (!this.description) return null
1192 1195
1193 const maxLength = CONSTRAINTS_FIELDS.VIDEOS.TRUNCATED_DESCRIPTION.max 1196 const maxLength = CONSTRAINTS_FIELDS.VIDEOS.TRUNCATED_DESCRIPTION.max
1194 1197 return peertubeTruncate(this.description, maxLength)
1195 const options = {
1196 length: maxLength
1197 }
1198 const truncatedDescription = truncate(this.description, options)
1199
1200 // The truncated string is okay, we can return it
1201 if (truncatedDescription.length <= maxLength) return truncatedDescription
1202
1203 // Lodash takes into account all UTF characters, whereas String.prototype.length does not: some characters have a length of 2
1204 // We always use the .length so we need to truncate more if needed
1205 options.length -= maxLength - truncatedDescription.length
1206 return truncate(this.description, options)
1207 } 1198 }
1208 1199
1209 optimizeOriginalVideofile = async function () { 1200 optimizeOriginalVideofile = async function () {