aboutsummaryrefslogtreecommitdiffhomepage
path: root/shared
diff options
context:
space:
mode:
Diffstat (limited to 'shared')
-rw-r--r--shared/core-utils/renderer/html.ts18
-rw-r--r--shared/extra-utils/index.ts2
-rw-r--r--shared/extra-utils/miscs/sql.ts28
-rw-r--r--shared/extra-utils/mock-servers/joinpeertube-versions.ts33
-rw-r--r--shared/extra-utils/mock-servers/mock-instances-index.ts (renamed from shared/extra-utils/instances-index/mock-instances-index.ts)6
-rw-r--r--shared/extra-utils/requests/activitypub.ts9
-rw-r--r--shared/extra-utils/requests/requests.ts7
-rw-r--r--shared/extra-utils/server/servers.ts1
-rw-r--r--shared/extra-utils/users/user-notifications.ts72
-rw-r--r--shared/extra-utils/users/users.ts4
-rw-r--r--shared/extra-utils/videos/live.ts2
-rw-r--r--shared/extra-utils/videos/video-channels.ts29
-rw-r--r--shared/models/activitypub/activitypub-actor.ts3
-rw-r--r--shared/models/activitypub/objects/common-objects.ts2
-rw-r--r--shared/models/actors/account.model.ts4
-rw-r--r--shared/models/actors/actor-image.model.ts (renamed from shared/models/avatars/avatar.model.ts)2
-rw-r--r--shared/models/actors/actor-image.type.ts4
-rw-r--r--shared/models/actors/actor.model.ts4
-rw-r--r--shared/models/actors/index.ts2
-rw-r--r--shared/models/avatars/index.ts1
-rw-r--r--shared/models/index.ts2
-rw-r--r--shared/models/joinpeertube/index.ts1
-rw-r--r--shared/models/joinpeertube/versions.model.ts5
-rw-r--r--shared/models/plugins/client-hook.model.ts21
-rw-r--r--shared/models/plugins/index.ts2
-rw-r--r--shared/models/plugins/plugin-element-placeholder.type.ts1
-rw-r--r--shared/models/plugins/register-client-form-field.model.ts14
-rw-r--r--shared/models/plugins/register-client-settings-script.model.ts8
-rw-r--r--shared/models/plugins/register-server-setting.model.ts2
-rw-r--r--shared/models/plugins/server-hook.model.ts20
-rw-r--r--shared/models/server/emailer.model.ts53
-rw-r--r--shared/models/server/job.model.ts2
-rw-r--r--shared/models/server/server-config.model.ts9
-rw-r--r--shared/models/server/server-stats.model.ts7
-rw-r--r--shared/models/users/user-notification-setting.model.ts3
-rw-r--r--shared/models/users/user-notification.model.ts18
-rw-r--r--shared/models/users/user.model.ts2
-rw-r--r--shared/models/videos/channel/video-channel.model.ts7
-rw-r--r--shared/models/videos/video-transcoding.model.ts7
39 files changed, 355 insertions, 62 deletions
diff --git a/shared/core-utils/renderer/html.ts b/shared/core-utils/renderer/html.ts
index 1220848a0..de4ad47ac 100644
--- a/shared/core-utils/renderer/html.ts
+++ b/shared/core-utils/renderer/html.ts
@@ -19,3 +19,21 @@ export const SANITIZE_OPTIONS = {
19 } 19 }
20 } 20 }
21} 21}
22
23// Thanks: https://stackoverflow.com/a/12034334
24export function escapeHTML (stringParam: string) {
25 if (!stringParam) return ''
26
27 const entityMap = {
28 '&': '&',
29 '<': '&lt;',
30 '>': '&gt;',
31 '"': '&quot;',
32 '\'': '&#39;',
33 '/': '&#x2F;',
34 '`': '&#x60;',
35 '=': '&#x3D;'
36 }
37
38 return String(stringParam).replace(/[&<>"'`=/]/g, s => entityMap[s])
39}
diff --git a/shared/extra-utils/index.ts b/shared/extra-utils/index.ts
index 5c95a1b3e..898a92d43 100644
--- a/shared/extra-utils/index.ts
+++ b/shared/extra-utils/index.ts
@@ -1,7 +1,7 @@
1export * from './bulk/bulk' 1export * from './bulk/bulk'
2export * from './cli/cli' 2export * from './cli/cli'
3export * from './feeds/feeds' 3export * from './feeds/feeds'
4export * from './instances-index/mock-instances-index' 4export * from './mock-servers/mock-instances-index'
5export * from './miscs/miscs' 5export * from './miscs/miscs'
6export * from './miscs/sql' 6export * from './miscs/sql'
7export * from './miscs/stubs' 7export * from './miscs/stubs'
diff --git a/shared/extra-utils/miscs/sql.ts b/shared/extra-utils/miscs/sql.ts
index 740f0c2d6..65a0aa5fe 100644
--- a/shared/extra-utils/miscs/sql.ts
+++ b/shared/extra-utils/miscs/sql.ts
@@ -82,6 +82,11 @@ async function countVideoViewsOf (internalServerNumber: number, uuid: string) {
82 return parseInt(total + '', 10) 82 return parseInt(total + '', 10)
83} 83}
84 84
85function getActorImage (internalServerNumber: number, filename: string) {
86 return selectQuery(internalServerNumber, `SELECT * FROM "actorImage" WHERE filename = '${filename}'`)
87 .then(rows => rows[0])
88}
89
85function selectQuery (internalServerNumber: number, query: string) { 90function selectQuery (internalServerNumber: number, query: string) {
86 const seq = getSequelize(internalServerNumber) 91 const seq = getSequelize(internalServerNumber)
87 const options = { type: QueryTypes.SELECT as QueryTypes.SELECT } 92 const options = { type: QueryTypes.SELECT as QueryTypes.SELECT }
@@ -106,12 +111,20 @@ async function closeAllSequelize (servers: ServerInfo[]) {
106 } 111 }
107} 112}
108 113
109function setPluginVersion (internalServerNumber: number, pluginName: string, newVersion: string) { 114function setPluginField (internalServerNumber: number, pluginName: string, field: string, value: string) {
110 const seq = getSequelize(internalServerNumber) 115 const seq = getSequelize(internalServerNumber)
111 116
112 const options = { type: QueryTypes.UPDATE } 117 const options = { type: QueryTypes.UPDATE }
113 118
114 return seq.query(`UPDATE "plugin" SET "version" = '${newVersion}' WHERE "name" = '${pluginName}'`, options) 119 return seq.query(`UPDATE "plugin" SET "${field}" = '${value}' WHERE "name" = '${pluginName}'`, options)
120}
121
122function setPluginVersion (internalServerNumber: number, pluginName: string, newVersion: string) {
123 return setPluginField(internalServerNumber, pluginName, 'version', newVersion)
124}
125
126function setPluginLatestVersion (internalServerNumber: number, pluginName: string, newVersion: string) {
127 return setPluginField(internalServerNumber, pluginName, 'latestVersion', newVersion)
115} 128}
116 129
117function setActorFollowScores (internalServerNumber: number, newScore: number) { 130function setActorFollowScores (internalServerNumber: number, newScore: number) {
@@ -122,14 +135,25 @@ function setActorFollowScores (internalServerNumber: number, newScore: number) {
122 return seq.query(`UPDATE "actorFollow" SET "score" = ${newScore}`, options) 135 return seq.query(`UPDATE "actorFollow" SET "score" = ${newScore}`, options)
123} 136}
124 137
138function setTokenField (internalServerNumber: number, accessToken: string, field: string, value: string) {
139 const seq = getSequelize(internalServerNumber)
140
141 const options = { type: QueryTypes.UPDATE }
142
143 return seq.query(`UPDATE "oAuthToken" SET "${field}" = '${value}' WHERE "accessToken" = '${accessToken}'`, options)
144}
145
125export { 146export {
126 setVideoField, 147 setVideoField,
127 setPlaylistField, 148 setPlaylistField,
128 setActorField, 149 setActorField,
129 countVideoViewsOf, 150 countVideoViewsOf,
130 setPluginVersion, 151 setPluginVersion,
152 setPluginLatestVersion,
131 selectQuery, 153 selectQuery,
154 getActorImage,
132 deleteAll, 155 deleteAll,
156 setTokenField,
133 updateQuery, 157 updateQuery,
134 setActorFollowScores, 158 setActorFollowScores,
135 closeAllSequelize, 159 closeAllSequelize,
diff --git a/shared/extra-utils/mock-servers/joinpeertube-versions.ts b/shared/extra-utils/mock-servers/joinpeertube-versions.ts
new file mode 100644
index 000000000..5ea432ecf
--- /dev/null
+++ b/shared/extra-utils/mock-servers/joinpeertube-versions.ts
@@ -0,0 +1,33 @@
1import * as express from 'express'
2import { randomInt } from '@shared/core-utils'
3
4export class MockJoinPeerTubeVersions {
5 private latestVersion: string
6
7 initialize () {
8 return new Promise<number>(res => {
9 const app = express()
10
11 app.use('/', (req: express.Request, res: express.Response, next: express.NextFunction) => {
12 if (process.env.DEBUG) console.log('Receiving request on mocked server %s.', req.url)
13
14 return next()
15 })
16
17 app.get('/versions.json', (req: express.Request, res: express.Response) => {
18 return res.json({
19 peertube: {
20 latestVersion: this.latestVersion
21 }
22 })
23 })
24
25 const port = 42201 + randomInt(1, 100)
26 app.listen(port, () => res(port))
27 })
28 }
29
30 setLatestVersion (latestVersion: string) {
31 this.latestVersion = latestVersion
32 }
33}
diff --git a/shared/extra-utils/instances-index/mock-instances-index.ts b/shared/extra-utils/mock-servers/mock-instances-index.ts
index 2604eda03..c9e33087d 100644
--- a/shared/extra-utils/instances-index/mock-instances-index.ts
+++ b/shared/extra-utils/mock-servers/mock-instances-index.ts
@@ -1,10 +1,11 @@
1import * as express from 'express' 1import * as express from 'express'
2import { randomInt } from '@shared/core-utils'
2 3
3export class MockInstancesIndex { 4export class MockInstancesIndex {
4 private readonly indexInstances: { host: string, createdAt: string }[] = [] 5 private readonly indexInstances: { host: string, createdAt: string }[] = []
5 6
6 initialize () { 7 initialize () {
7 return new Promise<void>(res => { 8 return new Promise<number>(res => {
8 const app = express() 9 const app = express()
9 10
10 app.use('/', (req: express.Request, res: express.Response, next: express.NextFunction) => { 11 app.use('/', (req: express.Request, res: express.Response, next: express.NextFunction) => {
@@ -28,7 +29,8 @@ export class MockInstancesIndex {
28 }) 29 })
29 }) 30 })
30 31
31 app.listen(42101, () => res()) 32 const port = 42101 + randomInt(1, 100)
33 app.listen(port, () => res(port))
32 }) 34 })
33 } 35 }
34 36
diff --git a/shared/extra-utils/requests/activitypub.ts b/shared/extra-utils/requests/activitypub.ts
index 4762a8665..ecd8ce823 100644
--- a/shared/extra-utils/requests/activitypub.ts
+++ b/shared/extra-utils/requests/activitypub.ts
@@ -5,20 +5,19 @@ import { activityPubContextify } from '../../../server/helpers/activitypub'
5 5
6function makePOSTAPRequest (url: string, body: any, httpSignature: any, headers: any) { 6function makePOSTAPRequest (url: string, body: any, httpSignature: any, headers: any) {
7 const options = { 7 const options = {
8 method: 'POST', 8 method: 'POST' as 'POST',
9 uri: url,
10 json: body, 9 json: body,
11 httpSignature, 10 httpSignature,
12 headers 11 headers
13 } 12 }
14 13
15 return doRequest(options) 14 return doRequest(url, options)
16} 15}
17 16
18async function makeFollowRequest (to: { url: string }, by: { url: string, privateKey }) { 17async function makeFollowRequest (to: { url: string }, by: { url: string, privateKey }) {
19 const follow = { 18 const follow = {
20 type: 'Follow', 19 type: 'Follow',
21 id: by.url + '/toto', 20 id: by.url + '/' + new Date().getTime(),
22 actor: by.url, 21 actor: by.url,
23 object: to.url 22 object: to.url
24 } 23 }
@@ -34,7 +33,7 @@ async function makeFollowRequest (to: { url: string }, by: { url: string, privat
34 } 33 }
35 const headers = buildGlobalHeaders(body) 34 const headers = buildGlobalHeaders(body)
36 35
37 return makePOSTAPRequest(to.url, body, httpSignature, headers) 36 return makePOSTAPRequest(to.url + '/inbox', body, httpSignature, headers)
38} 37}
39 38
40export { 39export {
diff --git a/shared/extra-utils/requests/requests.ts b/shared/extra-utils/requests/requests.ts
index 3e773ee03..8b5cddf4a 100644
--- a/shared/extra-utils/requests/requests.ts
+++ b/shared/extra-utils/requests/requests.ts
@@ -152,11 +152,12 @@ function makeHTMLRequest (url: string, path: string) {
152 .expect(HttpStatusCode.OK_200) 152 .expect(HttpStatusCode.OK_200)
153} 153}
154 154
155function updateAvatarRequest (options: { 155function updateImageRequest (options: {
156 url: string 156 url: string
157 path: string 157 path: string
158 accessToken: string 158 accessToken: string
159 fixture: string 159 fixture: string
160 fieldname: string
160}) { 161}) {
161 let filePath = '' 162 let filePath = ''
162 if (isAbsolute(options.fixture)) { 163 if (isAbsolute(options.fixture)) {
@@ -170,7 +171,7 @@ function updateAvatarRequest (options: {
170 path: options.path, 171 path: options.path,
171 token: options.accessToken, 172 token: options.accessToken,
172 fields: {}, 173 fields: {},
173 attaches: { avatarfile: filePath }, 174 attaches: { [options.fieldname]: filePath },
174 statusCodeExpected: HttpStatusCode.OK_200 175 statusCodeExpected: HttpStatusCode.OK_200
175 }) 176 })
176} 177}
@@ -191,5 +192,5 @@ export {
191 makePutBodyRequest, 192 makePutBodyRequest,
192 makeDeleteRequest, 193 makeDeleteRequest,
193 makeRawRequest, 194 makeRawRequest,
194 updateAvatarRequest 195 updateImageRequest
195} 196}
diff --git a/shared/extra-utils/server/servers.ts b/shared/extra-utils/server/servers.ts
index 08d05ef36..779a3cc36 100644
--- a/shared/extra-utils/server/servers.ts
+++ b/shared/extra-utils/server/servers.ts
@@ -37,6 +37,7 @@ interface ServerInfo {
37 customConfigFile?: string 37 customConfigFile?: string
38 38
39 accessToken?: string 39 accessToken?: string
40 refreshToken?: string
40 videoChannel?: VideoChannel 41 videoChannel?: VideoChannel
41 42
42 video?: { 43 video?: {
diff --git a/shared/extra-utils/users/user-notifications.ts b/shared/extra-utils/users/user-notifications.ts
index 467a3d959..249e82925 100644
--- a/shared/extra-utils/users/user-notifications.ts
+++ b/shared/extra-utils/users/user-notifications.ts
@@ -2,7 +2,8 @@
2 2
3import { expect } from 'chai' 3import { expect } from 'chai'
4import { inspect } from 'util' 4import { inspect } from 'util'
5import { AbuseState } from '@shared/models' 5import { AbuseState, PluginType } from '@shared/models'
6import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
6import { UserNotification, UserNotificationSetting, UserNotificationSettingValue, UserNotificationType } from '../../models/users' 7import { UserNotification, UserNotificationSetting, UserNotificationSettingValue, UserNotificationType } from '../../models/users'
7import { MockSmtpServer } from '../miscs/email' 8import { MockSmtpServer } from '../miscs/email'
8import { makeGetRequest, makePostBodyRequest, makePutBodyRequest } from '../requests/requests' 9import { makeGetRequest, makePostBodyRequest, makePutBodyRequest } from '../requests/requests'
@@ -11,7 +12,6 @@ import { flushAndRunMultipleServers, ServerInfo } from '../server/servers'
11import { getUserNotificationSocket } from '../socket/socket-io' 12import { getUserNotificationSocket } from '../socket/socket-io'
12import { setAccessTokensToServers, userLogin } from './login' 13import { setAccessTokensToServers, userLogin } from './login'
13import { createUser, getMyUserInformation } from './users' 14import { createUser, getMyUserInformation } from './users'
14import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
15 15
16function updateMyNotificationSettings ( 16function updateMyNotificationSettings (
17 url: string, 17 url: string,
@@ -629,7 +629,59 @@ async function checkNewBlacklistOnMyVideo (
629 await checkNotification(base, notificationChecker, emailNotificationFinder, 'presence') 629 await checkNotification(base, notificationChecker, emailNotificationFinder, 'presence')
630} 630}
631 631
632function getAllNotificationsSettings () { 632async function checkNewPeerTubeVersion (base: CheckerBaseParams, latestVersion: string, type: CheckerType) {
633 const notificationType = UserNotificationType.NEW_PEERTUBE_VERSION
634
635 function notificationChecker (notification: UserNotification, type: CheckerType) {
636 if (type === 'presence') {
637 expect(notification).to.not.be.undefined
638 expect(notification.type).to.equal(notificationType)
639
640 expect(notification.peertube).to.exist
641 expect(notification.peertube.latestVersion).to.equal(latestVersion)
642 } else {
643 expect(notification).to.satisfy((n: UserNotification) => {
644 return n === undefined || n.peertube === undefined || n.peertube.latestVersion !== latestVersion
645 })
646 }
647 }
648
649 function emailNotificationFinder (email: object) {
650 const text = email['text']
651
652 return text.includes(latestVersion)
653 }
654
655 await checkNotification(base, notificationChecker, emailNotificationFinder, type)
656}
657
658async function checkNewPluginVersion (base: CheckerBaseParams, pluginType: PluginType, pluginName: string, type: CheckerType) {
659 const notificationType = UserNotificationType.NEW_PLUGIN_VERSION
660
661 function notificationChecker (notification: UserNotification, type: CheckerType) {
662 if (type === 'presence') {
663 expect(notification).to.not.be.undefined
664 expect(notification.type).to.equal(notificationType)
665
666 expect(notification.plugin.name).to.equal(pluginName)
667 expect(notification.plugin.type).to.equal(pluginType)
668 } else {
669 expect(notification).to.satisfy((n: UserNotification) => {
670 return n === undefined || n.plugin === undefined || n.plugin.name !== pluginName
671 })
672 }
673 }
674
675 function emailNotificationFinder (email: object) {
676 const text = email['text']
677
678 return text.includes(pluginName)
679 }
680
681 await checkNotification(base, notificationChecker, emailNotificationFinder, type)
682}
683
684function getAllNotificationsSettings (): UserNotificationSetting {
633 return { 685 return {
634 newVideoFromSubscription: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, 686 newVideoFromSubscription: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
635 newCommentOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, 687 newCommentOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
@@ -644,11 +696,13 @@ function getAllNotificationsSettings () {
644 newInstanceFollower: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, 696 newInstanceFollower: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
645 abuseNewMessage: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, 697 abuseNewMessage: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
646 abuseStateChange: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL, 698 abuseStateChange: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
647 autoInstanceFollowing: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL 699 autoInstanceFollowing: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
648 } as UserNotificationSetting 700 newPeerTubeVersion: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
701 newPluginVersion: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL
702 }
649} 703}
650 704
651async function prepareNotificationsTest (serversCount = 3) { 705async function prepareNotificationsTest (serversCount = 3, overrideConfigArg: any = {}) {
652 const userNotifications: UserNotification[] = [] 706 const userNotifications: UserNotification[] = []
653 const adminNotifications: UserNotification[] = [] 707 const adminNotifications: UserNotification[] = []
654 const adminNotificationsServer2: UserNotification[] = [] 708 const adminNotificationsServer2: UserNotification[] = []
@@ -665,7 +719,7 @@ async function prepareNotificationsTest (serversCount = 3) {
665 limit: 20 719 limit: 20
666 } 720 }
667 } 721 }
668 const servers = await flushAndRunMultipleServers(serversCount, overrideConfig) 722 const servers = await flushAndRunMultipleServers(serversCount, Object.assign(overrideConfig, overrideConfigArg))
669 723
670 await setAccessTokensToServers(servers) 724 await setAccessTokensToServers(servers)
671 725
@@ -749,5 +803,7 @@ export {
749 checkNewInstanceFollower, 803 checkNewInstanceFollower,
750 prepareNotificationsTest, 804 prepareNotificationsTest,
751 checkNewCommentAbuseForModerators, 805 checkNewCommentAbuseForModerators,
752 checkNewAccountAbuseForModerators 806 checkNewAccountAbuseForModerators,
807 checkNewPeerTubeVersion,
808 checkNewPluginVersion
753} 809}
diff --git a/shared/extra-utils/users/users.ts b/shared/extra-utils/users/users.ts
index db532dbb0..6040dd9c0 100644
--- a/shared/extra-utils/users/users.ts
+++ b/shared/extra-utils/users/users.ts
@@ -4,7 +4,7 @@ import { UserUpdateMe } from '../../models/users'
4import { UserAdminFlag } from '../../models/users/user-flag.model' 4import { UserAdminFlag } from '../../models/users/user-flag.model'
5import { UserRegister } from '../../models/users/user-register.model' 5import { UserRegister } from '../../models/users/user-register.model'
6import { UserRole } from '../../models/users/user-role' 6import { UserRole } from '../../models/users/user-role'
7import { makeGetRequest, makePostBodyRequest, makePutBodyRequest, updateAvatarRequest } from '../requests/requests' 7import { makeGetRequest, makePostBodyRequest, makePutBodyRequest, updateImageRequest } from '../requests/requests'
8import { ServerInfo } from '../server/servers' 8import { ServerInfo } from '../server/servers'
9import { userLogin } from './login' 9import { userLogin } from './login'
10import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' 10import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
@@ -275,7 +275,7 @@ function updateMyAvatar (options: {
275}) { 275}) {
276 const path = '/api/v1/users/me/avatar/pick' 276 const path = '/api/v1/users/me/avatar/pick'
277 277
278 return updateAvatarRequest(Object.assign(options, { path })) 278 return updateImageRequest({ ...options, path, fieldname: 'avatarfile' })
279} 279}
280 280
281function updateUser (options: { 281function updateUser (options: {
diff --git a/shared/extra-utils/videos/live.ts b/shared/extra-utils/videos/live.ts
index df7370008..d3cd974de 100644
--- a/shared/extra-utils/videos/live.ts
+++ b/shared/extra-utils/videos/live.ts
@@ -119,7 +119,7 @@ async function testFfmpegStreamError (command: ffmpeg.FfmpegCommand, shouldHaveE
119 let error: Error 119 let error: Error
120 120
121 try { 121 try {
122 await waitFfmpegUntilError(command, 25000) 122 await waitFfmpegUntilError(command, 35000)
123 } catch (err) { 123 } catch (err) {
124 error = err 124 error = err
125 } 125 }
diff --git a/shared/extra-utils/videos/video-channels.ts b/shared/extra-utils/videos/video-channels.ts
index 3ff445c2a..d0dfb5856 100644
--- a/shared/extra-utils/videos/video-channels.ts
+++ b/shared/extra-utils/videos/video-channels.ts
@@ -3,7 +3,7 @@
3import * as request from 'supertest' 3import * as request from 'supertest'
4import { VideoChannelUpdate } from '../../models/videos/channel/video-channel-update.model' 4import { VideoChannelUpdate } from '../../models/videos/channel/video-channel-update.model'
5import { VideoChannelCreate } from '../../models/videos/channel/video-channel-create.model' 5import { VideoChannelCreate } from '../../models/videos/channel/video-channel-create.model'
6import { makeGetRequest, updateAvatarRequest } from '../requests/requests' 6import { makeDeleteRequest, makeGetRequest, updateImageRequest } from '../requests/requests'
7import { ServerInfo } from '../server/servers' 7import { ServerInfo } from '../server/servers'
8import { User } from '../../models/users/user.model' 8import { User } from '../../models/users/user.model'
9import { getMyUserInformation } from '../users/users' 9import { getMyUserInformation } from '../users/users'
@@ -129,16 +129,32 @@ function getVideoChannel (url: string, channelName: string) {
129 .expect('Content-Type', /json/) 129 .expect('Content-Type', /json/)
130} 130}
131 131
132function updateVideoChannelAvatar (options: { 132function updateVideoChannelImage (options: {
133 url: string 133 url: string
134 accessToken: string 134 accessToken: string
135 fixture: string 135 fixture: string
136 videoChannelName: string | number 136 videoChannelName: string | number
137 type: 'avatar' | 'banner'
137}) { 138}) {
139 const path = `/api/v1/video-channels/${options.videoChannelName}/${options.type}/pick`
138 140
139 const path = '/api/v1/video-channels/' + options.videoChannelName + '/avatar/pick' 141 return updateImageRequest({ ...options, path, fieldname: options.type + 'file' })
142}
143
144function deleteVideoChannelImage (options: {
145 url: string
146 accessToken: string
147 videoChannelName: string | number
148 type: 'avatar' | 'banner'
149}) {
150 const path = `/api/v1/video-channels/${options.videoChannelName}/${options.type}`
140 151
141 return updateAvatarRequest(Object.assign(options, { path })) 152 return makeDeleteRequest({
153 url: options.url,
154 token: options.accessToken,
155 path,
156 statusCodeExpected: 204
157 })
142} 158}
143 159
144function setDefaultVideoChannel (servers: ServerInfo[]) { 160function setDefaultVideoChannel (servers: ServerInfo[]) {
@@ -157,12 +173,13 @@ function setDefaultVideoChannel (servers: ServerInfo[]) {
157// --------------------------------------------------------------------------- 173// ---------------------------------------------------------------------------
158 174
159export { 175export {
160 updateVideoChannelAvatar, 176 updateVideoChannelImage,
161 getVideoChannelsList, 177 getVideoChannelsList,
162 getAccountVideoChannelsList, 178 getAccountVideoChannelsList,
163 addVideoChannel, 179 addVideoChannel,
164 updateVideoChannel, 180 updateVideoChannel,
165 deleteVideoChannel, 181 deleteVideoChannel,
166 getVideoChannel, 182 getVideoChannel,
167 setDefaultVideoChannel 183 setDefaultVideoChannel,
184 deleteVideoChannelImage
168} 185}
diff --git a/shared/models/activitypub/activitypub-actor.ts b/shared/models/activitypub/activitypub-actor.ts
index f022f3d02..c59be3f3b 100644
--- a/shared/models/activitypub/activitypub-actor.ts
+++ b/shared/models/activitypub/activitypub-actor.ts
@@ -27,5 +27,6 @@ export interface ActivityPubActor {
27 publicKeyPem: string 27 publicKeyPem: string
28 } 28 }
29 29
30 icon: ActivityIconObject 30 icon?: ActivityIconObject
31 image?: ActivityIconObject
31} 32}
diff --git a/shared/models/activitypub/objects/common-objects.ts b/shared/models/activitypub/objects/common-objects.ts
index 76f0e3bcf..43d7f7f74 100644
--- a/shared/models/activitypub/objects/common-objects.ts
+++ b/shared/models/activitypub/objects/common-objects.ts
@@ -9,7 +9,7 @@ export interface ActivityIdentifierObject {
9export interface ActivityIconObject { 9export interface ActivityIconObject {
10 type: 'Image' 10 type: 'Image'
11 url: string 11 url: string
12 mediaType: 'image/jpeg' | 'image/png' 12 mediaType: string
13 width?: number 13 width?: number
14 height?: number 14 height?: number
15} 15}
diff --git a/shared/models/actors/account.model.ts b/shared/models/actors/account.model.ts
index 2ff4b9f5e..120dec271 100644
--- a/shared/models/actors/account.model.ts
+++ b/shared/models/actors/account.model.ts
@@ -1,5 +1,5 @@
1import { ActorImage } from './actor-image.model'
1import { Actor } from './actor.model' 2import { Actor } from './actor.model'
2import { Avatar } from '../avatars'
3 3
4export interface Account extends Actor { 4export interface Account extends Actor {
5 displayName: string 5 displayName: string
@@ -14,5 +14,5 @@ export interface AccountSummary {
14 displayName: string 14 displayName: string
15 url: string 15 url: string
16 host: string 16 host: string
17 avatar?: Avatar 17 avatar?: ActorImage
18} 18}
diff --git a/shared/models/avatars/avatar.model.ts b/shared/models/actors/actor-image.model.ts
index f7fa16f49..ad5eab627 100644
--- a/shared/models/avatars/avatar.model.ts
+++ b/shared/models/actors/actor-image.model.ts
@@ -1,4 +1,4 @@
1export interface Avatar { 1export interface ActorImage {
2 path: string 2 path: string
3 3
4 url?: string 4 url?: string
diff --git a/shared/models/actors/actor-image.type.ts b/shared/models/actors/actor-image.type.ts
new file mode 100644
index 000000000..ac8eb6bf2
--- /dev/null
+++ b/shared/models/actors/actor-image.type.ts
@@ -0,0 +1,4 @@
1export const enum ActorImageType {
2 AVATAR = 1,
3 BANNER = 2
4}
diff --git a/shared/models/actors/actor.model.ts b/shared/models/actors/actor.model.ts
index 1dbf5f638..7d9f35b10 100644
--- a/shared/models/actors/actor.model.ts
+++ b/shared/models/actors/actor.model.ts
@@ -1,4 +1,4 @@
1import { Avatar } from '../avatars/avatar.model' 1import { ActorImage } from './actor-image.model'
2 2
3export interface Actor { 3export interface Actor {
4 id: number 4 id: number
@@ -9,5 +9,5 @@ export interface Actor {
9 followersCount: number 9 followersCount: number
10 createdAt: Date | string 10 createdAt: Date | string
11 updatedAt: Date | string 11 updatedAt: Date | string
12 avatar?: Avatar 12 avatar?: ActorImage
13} 13}
diff --git a/shared/models/actors/index.ts b/shared/models/actors/index.ts
index c7a92399d..156f83248 100644
--- a/shared/models/actors/index.ts
+++ b/shared/models/actors/index.ts
@@ -1,3 +1,5 @@
1export * from './account.model' 1export * from './account.model'
2export * from './actor-image.model'
3export * from './actor-image.type'
2export * from './actor.model' 4export * from './actor.model'
3export * from './follow.model' 5export * from './follow.model'
diff --git a/shared/models/avatars/index.ts b/shared/models/avatars/index.ts
deleted file mode 100644
index 65e8e0882..000000000
--- a/shared/models/avatars/index.ts
+++ /dev/null
@@ -1 +0,0 @@
1export * from './avatar.model'
diff --git a/shared/models/index.ts b/shared/models/index.ts
index 2214f7ca3..dff5fdf0e 100644
--- a/shared/models/index.ts
+++ b/shared/models/index.ts
@@ -1,12 +1,12 @@
1export * from './activitypub' 1export * from './activitypub'
2export * from './actors' 2export * from './actors'
3export * from './avatars'
4export * from './moderation' 3export * from './moderation'
5export * from './bulk' 4export * from './bulk'
6export * from './redundancy' 5export * from './redundancy'
7export * from './users' 6export * from './users'
8export * from './videos' 7export * from './videos'
9export * from './feeds' 8export * from './feeds'
9export * from './joinpeertube'
10export * from './overviews' 10export * from './overviews'
11export * from './plugins' 11export * from './plugins'
12export * from './search' 12export * from './search'
diff --git a/shared/models/joinpeertube/index.ts b/shared/models/joinpeertube/index.ts
new file mode 100644
index 000000000..9681c35ad
--- /dev/null
+++ b/shared/models/joinpeertube/index.ts
@@ -0,0 +1 @@
export * from './versions.model'
diff --git a/shared/models/joinpeertube/versions.model.ts b/shared/models/joinpeertube/versions.model.ts
new file mode 100644
index 000000000..60a769150
--- /dev/null
+++ b/shared/models/joinpeertube/versions.model.ts
@@ -0,0 +1,5 @@
1export interface JoinPeerTubeVersions {
2 peertube: {
3 latestVersion: string
4 }
5}
diff --git a/shared/models/plugins/client-hook.model.ts b/shared/models/plugins/client-hook.model.ts
index 7b7144676..f8ca32771 100644
--- a/shared/models/plugins/client-hook.model.ts
+++ b/shared/models/plugins/client-hook.model.ts
@@ -85,8 +85,27 @@ export const clientActionHookObject = {
85 // Fired when the registration page is being initialized 85 // Fired when the registration page is being initialized
86 'action:signup.register.init': true, 86 'action:signup.register.init': true,
87 87
88 // Fired when the video upload page is being initalized
89 'action:video-upload.init': true,
90 // Fired when the video import by URL page is being initalized
91 'action:video-url-import.init': true,
92 // Fired when the video import by torrent/magnet URI page is being initalized
93 'action:video-torrent-import.init': true,
94 // Fired when the "Go Live" page is being initalized
95 'action:go-live.init': true,
96
97 // Fired when the user explicitely logged in/logged out
98 'action:auth-user.logged-in': true,
99 'action:auth-user.logged-out': true,
100 // Fired when the application loaded user information (using tokens from the local storage or after a successful login)
101 'action:auth-user.information-loaded': true,
102
103 // Fired when the modal to download a video/caption is shown
104 'action:modal.video-download.shown': true,
105
88 // ####### Embed hooks ####### 106 // ####### Embed hooks #######
89 // In embed scope, peertube helpers are not available 107 // /!\ In embed scope, peertube helpers are not available
108 // ###########################
90 109
91 // Fired when the embed loaded the player 110 // Fired when the embed loaded the player
92 'action:embed.player.loaded': true 111 'action:embed.player.loaded': true
diff --git a/shared/models/plugins/index.ts b/shared/models/plugins/index.ts
index 96621460a..03b27f907 100644
--- a/shared/models/plugins/index.ts
+++ b/shared/models/plugins/index.ts
@@ -7,6 +7,7 @@ export * from './peertube-plugin-index.model'
7export * from './peertube-plugin-latest-version.model' 7export * from './peertube-plugin-latest-version.model'
8export * from './peertube-plugin.model' 8export * from './peertube-plugin.model'
9export * from './plugin-client-scope.type' 9export * from './plugin-client-scope.type'
10export * from './plugin-element-placeholder.type'
10export * from './plugin-package-json.model' 11export * from './plugin-package-json.model'
11export * from './plugin-playlist-privacy-manager.model' 12export * from './plugin-playlist-privacy-manager.model'
12export * from './plugin-settings-manager.model' 13export * from './plugin-settings-manager.model'
@@ -20,6 +21,7 @@ export * from './plugin-video-privacy-manager.model'
20export * from './plugin.type' 21export * from './plugin.type'
21export * from './public-server.setting' 22export * from './public-server.setting'
22export * from './register-client-hook.model' 23export * from './register-client-hook.model'
24export * from './register-client-settings-script.model'
23export * from './register-client-form-field.model' 25export * from './register-client-form-field.model'
24export * from './register-server-hook.model' 26export * from './register-server-hook.model'
25export * from './register-server-setting.model' 27export * from './register-server-setting.model'
diff --git a/shared/models/plugins/plugin-element-placeholder.type.ts b/shared/models/plugins/plugin-element-placeholder.type.ts
new file mode 100644
index 000000000..129099c62
--- /dev/null
+++ b/shared/models/plugins/plugin-element-placeholder.type.ts
@@ -0,0 +1 @@
export type PluginElementPlaceholder = 'player-next'
diff --git a/shared/models/plugins/register-client-form-field.model.ts b/shared/models/plugins/register-client-form-field.model.ts
index 641d7490c..cdcdaa181 100644
--- a/shared/models/plugins/register-client-form-field.model.ts
+++ b/shared/models/plugins/register-client-form-field.model.ts
@@ -1,7 +1,13 @@
1export interface RegisterClientFormFieldOptions { 1export type RegisterClientFormFieldOptions = {
2 name: string 2 name?: string
3 label: string 3 label?: string
4 type: 'input' | 'input-checkbox' | 'input-password' | 'input-textarea' | 'markdown-text' | 'markdown-enhanced' 4 type: 'input' | 'input-checkbox' | 'input-password' | 'input-textarea' | 'markdown-text' | 'markdown-enhanced' | 'select' | 'html'
5
6 // For select type
7 options?: { value: string, label: string }[]
8
9 // For html type
10 html?: string
5 11
6 descriptionHTML?: string 12 descriptionHTML?: string
7 13
diff --git a/shared/models/plugins/register-client-settings-script.model.ts b/shared/models/plugins/register-client-settings-script.model.ts
new file mode 100644
index 000000000..ac16af366
--- /dev/null
+++ b/shared/models/plugins/register-client-settings-script.model.ts
@@ -0,0 +1,8 @@
1import { RegisterServerSettingOptions } from "./register-server-setting.model"
2
3export interface RegisterClientSettingsScript {
4 isSettingHidden (options: {
5 setting: RegisterServerSettingOptions
6 formValues: { [name: string]: any }
7 }): boolean
8}
diff --git a/shared/models/plugins/register-server-setting.model.ts b/shared/models/plugins/register-server-setting.model.ts
index 6872dc53e..9f45c3c37 100644
--- a/shared/models/plugins/register-server-setting.model.ts
+++ b/shared/models/plugins/register-server-setting.model.ts
@@ -1,6 +1,6 @@
1import { RegisterClientFormFieldOptions } from './register-client-form-field.model' 1import { RegisterClientFormFieldOptions } from './register-client-form-field.model'
2 2
3export interface RegisterServerSettingOptions extends RegisterClientFormFieldOptions { 3export type RegisterServerSettingOptions = RegisterClientFormFieldOptions & {
4 // If the setting is not private, anyone can view its value (client code included) 4 // If the setting is not private, anyone can view its value (client code included)
5 // If the setting is private, only server-side hooks can access it 5 // If the setting is private, only server-side hooks can access it
6 // Mainly used by the PeerTube client to get admin config 6 // Mainly used by the PeerTube client to get admin config
diff --git a/shared/models/plugins/server-hook.model.ts b/shared/models/plugins/server-hook.model.ts
index 082b4b591..88277af5a 100644
--- a/shared/models/plugins/server-hook.model.ts
+++ b/shared/models/plugins/server-hook.model.ts
@@ -18,6 +18,16 @@ export const serverFilterHookObject = {
18 'filter:api.user.me.videos.list.params': true, 18 'filter:api.user.me.videos.list.params': true,
19 'filter:api.user.me.videos.list.result': true, 19 'filter:api.user.me.videos.list.result': true,
20 20
21 // Filter params/results to search videos/channels in the DB or on the remote index
22 'filter:api.search.videos.local.list.params': true,
23 'filter:api.search.videos.local.list.result': true,
24 'filter:api.search.videos.index.list.params': true,
25 'filter:api.search.videos.index.list.result': true,
26 'filter:api.search.video-channels.local.list.params': true,
27 'filter:api.search.video-channels.local.list.result': true,
28 'filter:api.search.video-channels.index.list.params': true,
29 'filter:api.search.video-channels.index.list.result': true,
30
21 // Filter the result of the get function 31 // Filter the result of the get function
22 // Used to get detailed video information (video watch page for example) 32 // Used to get detailed video information (video watch page for example)
23 'filter:api.video.get.result': true, 33 'filter:api.video.get.result': true,
@@ -50,7 +60,15 @@ export const serverFilterHookObject = {
50 'filter:video.auto-blacklist.result': true, 60 'filter:video.auto-blacklist.result': true,
51 61
52 // Filter result used to check if a user can register on the instance 62 // Filter result used to check if a user can register on the instance
53 'filter:api.user.signup.allowed.result': true 63 'filter:api.user.signup.allowed.result': true,
64
65 // Filter result used to check if video/torrent download is allowed
66 'filter:api.download.video.allowed.result': true,
67 'filter:api.download.torrent.allowed.result': true,
68
69 // Filter result to check if the embed is allowed for a particular request
70 'filter:html.embed.video.allowed.result': true,
71 'filter:html.embed.video-playlist.allowed.result': true
54} 72}
55 73
56export type ServerFilterHookName = keyof typeof serverFilterHookObject 74export type ServerFilterHookName = keyof typeof serverFilterHookObject
diff --git a/shared/models/server/emailer.model.ts b/shared/models/server/emailer.model.ts
index 069ef0bab..39512d306 100644
--- a/shared/models/server/emailer.model.ts
+++ b/shared/models/server/emailer.model.ts
@@ -1,12 +1,49 @@
1export type SendEmailOptions = { 1type From = string | { name?: string, address: string }
2 to: string[]
3 2
4 template?: string 3interface Base extends Partial<SendEmailDefaultMessageOptions> {
4 to: string[] | string
5}
6
7interface MailTemplate extends Base {
8 template: string
5 locals?: { [key: string]: any } 9 locals?: { [key: string]: any }
10 text?: undefined
11}
12
13interface MailText extends Base {
14 text: string
6 15
7 // override defaults 16 locals?: Partial<SendEmailDefaultLocalsOptions> & {
8 subject?: string 17 title?: string
9 text?: string 18 action?: {
10 from?: string | { name?: string, address: string } 19 url: string
11 replyTo?: string 20 text: string
21 }
22 }
12} 23}
24
25interface SendEmailDefaultLocalsOptions {
26 instanceName: string
27 text: string
28 subject: string
29}
30
31interface SendEmailDefaultMessageOptions {
32 to: string[] | string
33 from: From
34 subject: string
35 replyTo: string
36}
37
38export type SendEmailDefaultOptions = {
39 template: 'common'
40
41 message: SendEmailDefaultMessageOptions
42
43 locals: SendEmailDefaultLocalsOptions & {
44 WEBSERVER: any
45 EMAIL: any
46 }
47}
48
49export type SendEmailOptions = MailTemplate | MailText
diff --git a/shared/models/server/job.model.ts b/shared/models/server/job.model.ts
index 83ef84457..e4acfee8d 100644
--- a/shared/models/server/job.model.ts
+++ b/shared/models/server/job.model.ts
@@ -59,7 +59,7 @@ export type ActivitypubHttpFetcherPayload = {
59export type ActivitypubHttpUnicastPayload = { 59export type ActivitypubHttpUnicastPayload = {
60 uri: string 60 uri: string
61 signatureActorId?: number 61 signatureActorId?: number
62 body: any 62 body: object
63 contextType?: ContextType 63 contextType?: ContextType
64} 64}
65 65
diff --git a/shared/models/server/server-config.model.ts b/shared/models/server/server-config.model.ts
index efde4ad9d..85d84af44 100644
--- a/shared/models/server/server-config.model.ts
+++ b/shared/models/server/server-config.model.ts
@@ -151,6 +151,15 @@ export interface ServerConfig {
151 } 151 }
152 } 152 }
153 153
154 banner: {
155 file: {
156 size: {
157 max: number
158 }
159 extensions: string[]
160 }
161 }
162
154 video: { 163 video: {
155 image: { 164 image: {
156 size: { 165 size: {
diff --git a/shared/models/server/server-stats.model.ts b/shared/models/server/server-stats.model.ts
index 0f8cfc6cf..b1dcf2065 100644
--- a/shared/models/server/server-stats.model.ts
+++ b/shared/models/server/server-stats.model.ts
@@ -13,6 +13,13 @@ export interface ServerStats {
13 totalVideos: number 13 totalVideos: number
14 totalVideoComments: number 14 totalVideoComments: number
15 15
16 totalLocalVideoChannels: number
17 totalLocalDailyActiveVideoChannels: number
18 totalLocalWeeklyActiveVideoChannels: number
19 totalLocalMonthlyActiveVideoChannels: number
20
21 totalLocalPlaylists: number
22
16 totalInstanceFollowers: number 23 totalInstanceFollowers: number
17 totalInstanceFollowing: number 24 totalInstanceFollowing: number
18 25
diff --git a/shared/models/users/user-notification-setting.model.ts b/shared/models/users/user-notification-setting.model.ts
index 473148062..977e6b985 100644
--- a/shared/models/users/user-notification-setting.model.ts
+++ b/shared/models/users/user-notification-setting.model.ts
@@ -24,4 +24,7 @@ export interface UserNotificationSetting {
24 24
25 abuseStateChange: UserNotificationSettingValue 25 abuseStateChange: UserNotificationSettingValue
26 abuseNewMessage: UserNotificationSettingValue 26 abuseNewMessage: UserNotificationSettingValue
27
28 newPeerTubeVersion: UserNotificationSettingValue
29 newPluginVersion: UserNotificationSettingValue
27} 30}
diff --git a/shared/models/users/user-notification.model.ts b/shared/models/users/user-notification.model.ts
index e2f2234e4..8b33e3fbd 100644
--- a/shared/models/users/user-notification.model.ts
+++ b/shared/models/users/user-notification.model.ts
@@ -1,7 +1,8 @@
1import { FollowState } from '../actors' 1import { FollowState } from '../actors'
2import { AbuseState } from '../moderation' 2import { AbuseState } from '../moderation'
3import { PluginType } from '../plugins'
3 4
4export enum UserNotificationType { 5export const enum UserNotificationType {
5 NEW_VIDEO_FROM_SUBSCRIPTION = 1, 6 NEW_VIDEO_FROM_SUBSCRIPTION = 1,
6 NEW_COMMENT_ON_MY_VIDEO = 2, 7 NEW_COMMENT_ON_MY_VIDEO = 2,
7 NEW_ABUSE_FOR_MODERATORS = 3, 8 NEW_ABUSE_FOR_MODERATORS = 3,
@@ -26,7 +27,10 @@ export enum UserNotificationType {
26 27
27 ABUSE_STATE_CHANGE = 15, 28 ABUSE_STATE_CHANGE = 15,
28 29
29 ABUSE_NEW_MESSAGE = 16 30 ABUSE_NEW_MESSAGE = 16,
31
32 NEW_PLUGIN_VERSION = 17,
33 NEW_PEERTUBE_VERSION = 18
30} 34}
31 35
32export interface VideoInfo { 36export interface VideoInfo {
@@ -108,6 +112,16 @@ export interface UserNotification {
108 } 112 }
109 } 113 }
110 114
115 plugin?: {
116 name: string
117 type: PluginType
118 latestVersion: string
119 }
120
121 peertube?: {
122 latestVersion: string
123 }
124
111 createdAt: string 125 createdAt: string
112 updatedAt: string 126 updatedAt: string
113} 127}
diff --git a/shared/models/users/user.model.ts b/shared/models/users/user.model.ts
index 2c24d81be..7a982c2e5 100644
--- a/shared/models/users/user.model.ts
+++ b/shared/models/users/user.model.ts
@@ -38,7 +38,7 @@ export interface User {
38 abusesAcceptedCount?: number 38 abusesAcceptedCount?: number
39 abusesCreatedCount?: number 39 abusesCreatedCount?: number
40 40
41 videoCommentsCount? : number 41 videoCommentsCount?: number
42 42
43 theme: string 43 theme: string
44 44
diff --git a/shared/models/videos/channel/video-channel.model.ts b/shared/models/videos/channel/video-channel.model.ts
index 32829e92a..56517972d 100644
--- a/shared/models/videos/channel/video-channel.model.ts
+++ b/shared/models/videos/channel/video-channel.model.ts
@@ -1,6 +1,5 @@
1import { Actor } from '../../actors/actor.model' 1import { Actor } from '../../actors/actor.model'
2import { Account } from '../../actors/index' 2import { Account, ActorImage } from '../../actors'
3import { Avatar } from '../../avatars'
4 3
5export type ViewsPerDate = { 4export type ViewsPerDate = {
6 date: Date 5 date: Date
@@ -16,6 +15,8 @@ export interface VideoChannel extends Actor {
16 15
17 videosCount?: number 16 videosCount?: number
18 viewsPerDay?: ViewsPerDate[] // chronologically ordered 17 viewsPerDay?: ViewsPerDate[] // chronologically ordered
18
19 banner?: ActorImage
19} 20}
20 21
21export interface VideoChannelSummary { 22export interface VideoChannelSummary {
@@ -24,5 +25,5 @@ export interface VideoChannelSummary {
24 displayName: string 25 displayName: string
25 url: string 26 url: string
26 host: string 27 host: string
27 avatar?: Avatar 28 avatar?: ActorImage
28} 29}
diff --git a/shared/models/videos/video-transcoding.model.ts b/shared/models/videos/video-transcoding.model.ts
index 06b555c16..3f2382ce8 100644
--- a/shared/models/videos/video-transcoding.model.ts
+++ b/shared/models/videos/video-transcoding.model.ts
@@ -12,7 +12,12 @@ export type EncoderOptionsBuilder = (params: {
12export interface EncoderOptions { 12export interface EncoderOptions {
13 copy?: boolean // Copy stream? Default to false 13 copy?: boolean // Copy stream? Default to false
14 14
15 outputOptions: string[] 15 scaleFilter?: {
16 name: string
17 }
18
19 inputOptions?: string[]
20 outputOptions?: string[]
16} 21}
17 22
18// All our encoders 23// All our encoders