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'
import * as pem from 'pem'
import * as rimraf from 'rimraf'
import { URL } from 'url'
+import { truncate } from 'lodash'
function sanitizeUrl (url: string) {
const urlObject = new URL(url)
@@ -78,6 +79,22 @@ function buildPath (path: string) {
return join(root(), path)
}
+// Consistent with .length, lodash truncate function is not
+function peertubeTruncate (str: string, maxLength: number) {
+ const options = {
+ length: maxLength
+ }
+ const truncatedStr = truncate(str, options)
+
+ // The truncated string is okay, we can return it
+ if (truncatedStr.length <= maxLength) return truncatedStr
+
+ // Lodash takes into account all UTF characters, whereas String.prototype.length does not: some characters have a length of 2
+ // We always use the .length so we need to truncate more if needed
+ options.length -= truncatedStr.length - maxLength
+ return truncate(str, options)
+}
+
function promisify0 (func: (cb: (err: any, result: A) => void) => void): () => Promise {
return function promisified (): Promise {
return new Promise((resolve: (arg: A) => void, reject: (err: any) => void) => {
@@ -145,6 +162,7 @@ export {
sanitizeUrl,
sanitizeHost,
buildPath,
+ peertubeTruncate,
promisify0,
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 @@
import * as validator from 'validator'
-import { ACTIVITY_PUB } from '../../../initializers'
+import { ACTIVITY_PUB, CONSTRAINTS_FIELDS } from '../../../initializers'
+import { peertubeTruncate } from '../../core-utils'
import { exists, isBooleanValid, isDateValid, isUUIDValid } from '../misc'
import {
isVideoAbuseReasonValid,
@@ -56,6 +57,7 @@ function isVideoTorrentObjectValid (video: any) {
isBooleanValid(video.commentsEnabled) &&
isDateValid(video.published) &&
isDateValid(video.updated) &&
+ setTruncatedContent(video) &&
(!video.content || isRemoteVideoContentValid(video.mediaType, video.content)) &&
isRemoteVideoIconValid(video.icon) &&
setValidRemoteVideoUrls(video) &&
@@ -111,6 +113,14 @@ function setValidRemoteVideoUrls (video: any) {
return true
}
+function setTruncatedContent (video: any) {
+ if (video.content) {
+ video.content = peertubeTruncate(video.content, CONSTRAINTS_FIELDS.VIDEOS.TRUNCATED_DESCRIPTION.max)
+ }
+
+ return true
+}
+
function isRemoteVideoUrlValid (url: any) {
return url.type === 'Link' &&
(
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
try {
await activityProcessor(activity, inboxActor)
} catch (err) {
- logger.warn('Cannot process activity %s.', activity.type, { error: err.stack })
+ logger.warn('Cannot process activity %s.', activity.type, { err })
}
}
}
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 @@
import * as Bluebird from 'bluebird'
-import { map, maxBy, truncate } from 'lodash'
+import { map, maxBy } from 'lodash'
import * as magnetUtil from 'magnet-uri'
import * as parseTorrent from 'parse-torrent'
import { join } from 'path'
@@ -31,7 +31,10 @@ import { VideoTorrentObject } from '../../../shared/models/activitypub/objects'
import { Video, VideoDetails } from '../../../shared/models/videos'
import { VideoFilter } from '../../../shared/models/videos/video-query.type'
import { activityPubCollection } from '../../helpers/activitypub'
-import { createTorrentPromise, renamePromise, statPromise, unlinkPromise, writeFilePromise } from '../../helpers/core-utils'
+import {
+ createTorrentPromise, peertubeTruncate, renamePromise, statPromise, unlinkPromise,
+ writeFilePromise
+} from '../../helpers/core-utils'
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
import { isBooleanValid } from '../../helpers/custom-validators/misc'
import {
@@ -1191,19 +1194,7 @@ export class VideoModel extends Model {
if (!this.description) return null
const maxLength = CONSTRAINTS_FIELDS.VIDEOS.TRUNCATED_DESCRIPTION.max
-
- const options = {
- length: maxLength
- }
- const truncatedDescription = truncate(this.description, options)
-
- // The truncated string is okay, we can return it
- if (truncatedDescription.length <= maxLength) return truncatedDescription
-
- // Lodash takes into account all UTF characters, whereas String.prototype.length does not: some characters have a length of 2
- // We always use the .length so we need to truncate more if needed
- options.length -= maxLength - truncatedDescription.length
- return truncate(this.description, options)
+ return peertubeTruncate(this.description, maxLength)
}
optimizeOriginalVideofile = async function () {