diff options
Diffstat (limited to 'shared')
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 | ||
24 | export function escapeHTML (stringParam: string) { | ||
25 | if (!stringParam) return '' | ||
26 | |||
27 | const entityMap = { | ||
28 | '&': '&', | ||
29 | '<': '<', | ||
30 | '>': '>', | ||
31 | '"': '"', | ||
32 | '\'': ''', | ||
33 | '/': '/', | ||
34 | '`': '`', | ||
35 | '=': '=' | ||
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 @@ | |||
1 | export * from './bulk/bulk' | 1 | export * from './bulk/bulk' |
2 | export * from './cli/cli' | 2 | export * from './cli/cli' |
3 | export * from './feeds/feeds' | 3 | export * from './feeds/feeds' |
4 | export * from './instances-index/mock-instances-index' | 4 | export * from './mock-servers/mock-instances-index' |
5 | export * from './miscs/miscs' | 5 | export * from './miscs/miscs' |
6 | export * from './miscs/sql' | 6 | export * from './miscs/sql' |
7 | export * from './miscs/stubs' | 7 | export * 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 | ||
85 | function getActorImage (internalServerNumber: number, filename: string) { | ||
86 | return selectQuery(internalServerNumber, `SELECT * FROM "actorImage" WHERE filename = '${filename}'`) | ||
87 | .then(rows => rows[0]) | ||
88 | } | ||
89 | |||
85 | function selectQuery (internalServerNumber: number, query: string) { | 90 | function 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 | ||
109 | function setPluginVersion (internalServerNumber: number, pluginName: string, newVersion: string) { | 114 | function 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 | |||
122 | function setPluginVersion (internalServerNumber: number, pluginName: string, newVersion: string) { | ||
123 | return setPluginField(internalServerNumber, pluginName, 'version', newVersion) | ||
124 | } | ||
125 | |||
126 | function setPluginLatestVersion (internalServerNumber: number, pluginName: string, newVersion: string) { | ||
127 | return setPluginField(internalServerNumber, pluginName, 'latestVersion', newVersion) | ||
115 | } | 128 | } |
116 | 129 | ||
117 | function setActorFollowScores (internalServerNumber: number, newScore: number) { | 130 | function 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 | ||
138 | function 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 | |||
125 | export { | 146 | export { |
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 @@ | |||
1 | import * as express from 'express' | ||
2 | import { randomInt } from '@shared/core-utils' | ||
3 | |||
4 | export 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 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { randomInt } from '@shared/core-utils' | ||
2 | 3 | ||
3 | export class MockInstancesIndex { | 4 | export 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 | ||
6 | function makePOSTAPRequest (url: string, body: any, httpSignature: any, headers: any) { | 6 | function 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 | ||
18 | async function makeFollowRequest (to: { url: string }, by: { url: string, privateKey }) { | 17 | async 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 | ||
40 | export { | 39 | export { |
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 | ||
155 | function updateAvatarRequest (options: { | 155 | function 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 | ||
3 | import { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { inspect } from 'util' | 4 | import { inspect } from 'util' |
5 | import { AbuseState } from '@shared/models' | 5 | import { AbuseState, PluginType } from '@shared/models' |
6 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
6 | import { UserNotification, UserNotificationSetting, UserNotificationSettingValue, UserNotificationType } from '../../models/users' | 7 | import { UserNotification, UserNotificationSetting, UserNotificationSettingValue, UserNotificationType } from '../../models/users' |
7 | import { MockSmtpServer } from '../miscs/email' | 8 | import { MockSmtpServer } from '../miscs/email' |
8 | import { makeGetRequest, makePostBodyRequest, makePutBodyRequest } from '../requests/requests' | 9 | import { makeGetRequest, makePostBodyRequest, makePutBodyRequest } from '../requests/requests' |
@@ -11,7 +12,6 @@ import { flushAndRunMultipleServers, ServerInfo } from '../server/servers' | |||
11 | import { getUserNotificationSocket } from '../socket/socket-io' | 12 | import { getUserNotificationSocket } from '../socket/socket-io' |
12 | import { setAccessTokensToServers, userLogin } from './login' | 13 | import { setAccessTokensToServers, userLogin } from './login' |
13 | import { createUser, getMyUserInformation } from './users' | 14 | import { createUser, getMyUserInformation } from './users' |
14 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
15 | 15 | ||
16 | function updateMyNotificationSettings ( | 16 | function 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 | ||
632 | function getAllNotificationsSettings () { | 632 | async 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 | |||
658 | async 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 | |||
684 | function 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 | ||
651 | async function prepareNotificationsTest (serversCount = 3) { | 705 | async 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' | |||
4 | import { UserAdminFlag } from '../../models/users/user-flag.model' | 4 | import { UserAdminFlag } from '../../models/users/user-flag.model' |
5 | import { UserRegister } from '../../models/users/user-register.model' | 5 | import { UserRegister } from '../../models/users/user-register.model' |
6 | import { UserRole } from '../../models/users/user-role' | 6 | import { UserRole } from '../../models/users/user-role' |
7 | import { makeGetRequest, makePostBodyRequest, makePutBodyRequest, updateAvatarRequest } from '../requests/requests' | 7 | import { makeGetRequest, makePostBodyRequest, makePutBodyRequest, updateImageRequest } from '../requests/requests' |
8 | import { ServerInfo } from '../server/servers' | 8 | import { ServerInfo } from '../server/servers' |
9 | import { userLogin } from './login' | 9 | import { userLogin } from './login' |
10 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | 10 | import { 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 | ||
281 | function updateUser (options: { | 281 | function 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 @@ | |||
3 | import * as request from 'supertest' | 3 | import * as request from 'supertest' |
4 | import { VideoChannelUpdate } from '../../models/videos/channel/video-channel-update.model' | 4 | import { VideoChannelUpdate } from '../../models/videos/channel/video-channel-update.model' |
5 | import { VideoChannelCreate } from '../../models/videos/channel/video-channel-create.model' | 5 | import { VideoChannelCreate } from '../../models/videos/channel/video-channel-create.model' |
6 | import { makeGetRequest, updateAvatarRequest } from '../requests/requests' | 6 | import { makeDeleteRequest, makeGetRequest, updateImageRequest } from '../requests/requests' |
7 | import { ServerInfo } from '../server/servers' | 7 | import { ServerInfo } from '../server/servers' |
8 | import { User } from '../../models/users/user.model' | 8 | import { User } from '../../models/users/user.model' |
9 | import { getMyUserInformation } from '../users/users' | 9 | import { 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 | ||
132 | function updateVideoChannelAvatar (options: { | 132 | function 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 | |||
144 | function 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 | ||
144 | function setDefaultVideoChannel (servers: ServerInfo[]) { | 160 | function setDefaultVideoChannel (servers: ServerInfo[]) { |
@@ -157,12 +173,13 @@ function setDefaultVideoChannel (servers: ServerInfo[]) { | |||
157 | // --------------------------------------------------------------------------- | 173 | // --------------------------------------------------------------------------- |
158 | 174 | ||
159 | export { | 175 | export { |
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 { | |||
9 | export interface ActivityIconObject { | 9 | export 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 @@ | |||
1 | import { ActorImage } from './actor-image.model' | ||
1 | import { Actor } from './actor.model' | 2 | import { Actor } from './actor.model' |
2 | import { Avatar } from '../avatars' | ||
3 | 3 | ||
4 | export interface Account extends Actor { | 4 | export 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 @@ | |||
1 | export interface Avatar { | 1 | export 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 @@ | |||
1 | export 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 @@ | |||
1 | import { Avatar } from '../avatars/avatar.model' | 1 | import { ActorImage } from './actor-image.model' |
2 | 2 | ||
3 | export interface Actor { | 3 | export 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 @@ | |||
1 | export * from './account.model' | 1 | export * from './account.model' |
2 | export * from './actor-image.model' | ||
3 | export * from './actor-image.type' | ||
2 | export * from './actor.model' | 4 | export * from './actor.model' |
3 | export * from './follow.model' | 5 | export * 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 @@ | |||
1 | export * 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 @@ | |||
1 | export * from './activitypub' | 1 | export * from './activitypub' |
2 | export * from './actors' | 2 | export * from './actors' |
3 | export * from './avatars' | ||
4 | export * from './moderation' | 3 | export * from './moderation' |
5 | export * from './bulk' | 4 | export * from './bulk' |
6 | export * from './redundancy' | 5 | export * from './redundancy' |
7 | export * from './users' | 6 | export * from './users' |
8 | export * from './videos' | 7 | export * from './videos' |
9 | export * from './feeds' | 8 | export * from './feeds' |
9 | export * from './joinpeertube' | ||
10 | export * from './overviews' | 10 | export * from './overviews' |
11 | export * from './plugins' | 11 | export * from './plugins' |
12 | export * from './search' | 12 | export * 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 @@ | |||
1 | export 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' | |||
7 | export * from './peertube-plugin-latest-version.model' | 7 | export * from './peertube-plugin-latest-version.model' |
8 | export * from './peertube-plugin.model' | 8 | export * from './peertube-plugin.model' |
9 | export * from './plugin-client-scope.type' | 9 | export * from './plugin-client-scope.type' |
10 | export * from './plugin-element-placeholder.type' | ||
10 | export * from './plugin-package-json.model' | 11 | export * from './plugin-package-json.model' |
11 | export * from './plugin-playlist-privacy-manager.model' | 12 | export * from './plugin-playlist-privacy-manager.model' |
12 | export * from './plugin-settings-manager.model' | 13 | export * from './plugin-settings-manager.model' |
@@ -20,6 +21,7 @@ export * from './plugin-video-privacy-manager.model' | |||
20 | export * from './plugin.type' | 21 | export * from './plugin.type' |
21 | export * from './public-server.setting' | 22 | export * from './public-server.setting' |
22 | export * from './register-client-hook.model' | 23 | export * from './register-client-hook.model' |
24 | export * from './register-client-settings-script.model' | ||
23 | export * from './register-client-form-field.model' | 25 | export * from './register-client-form-field.model' |
24 | export * from './register-server-hook.model' | 26 | export * from './register-server-hook.model' |
25 | export * from './register-server-setting.model' | 27 | export * 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 @@ | |||
1 | export interface RegisterClientFormFieldOptions { | 1 | export 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 @@ | |||
1 | import { RegisterServerSettingOptions } from "./register-server-setting.model" | ||
2 | |||
3 | export 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 @@ | |||
1 | import { RegisterClientFormFieldOptions } from './register-client-form-field.model' | 1 | import { RegisterClientFormFieldOptions } from './register-client-form-field.model' |
2 | 2 | ||
3 | export interface RegisterServerSettingOptions extends RegisterClientFormFieldOptions { | 3 | export 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 | ||
56 | export type ServerFilterHookName = keyof typeof serverFilterHookObject | 74 | export 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 @@ | |||
1 | export type SendEmailOptions = { | 1 | type From = string | { name?: string, address: string } |
2 | to: string[] | ||
3 | 2 | ||
4 | template?: string | 3 | interface Base extends Partial<SendEmailDefaultMessageOptions> { |
4 | to: string[] | string | ||
5 | } | ||
6 | |||
7 | interface MailTemplate extends Base { | ||
8 | template: string | ||
5 | locals?: { [key: string]: any } | 9 | locals?: { [key: string]: any } |
10 | text?: undefined | ||
11 | } | ||
12 | |||
13 | interface 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 | |||
25 | interface SendEmailDefaultLocalsOptions { | ||
26 | instanceName: string | ||
27 | text: string | ||
28 | subject: string | ||
29 | } | ||
30 | |||
31 | interface SendEmailDefaultMessageOptions { | ||
32 | to: string[] | string | ||
33 | from: From | ||
34 | subject: string | ||
35 | replyTo: string | ||
36 | } | ||
37 | |||
38 | export type SendEmailDefaultOptions = { | ||
39 | template: 'common' | ||
40 | |||
41 | message: SendEmailDefaultMessageOptions | ||
42 | |||
43 | locals: SendEmailDefaultLocalsOptions & { | ||
44 | WEBSERVER: any | ||
45 | EMAIL: any | ||
46 | } | ||
47 | } | ||
48 | |||
49 | export 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 = { | |||
59 | export type ActivitypubHttpUnicastPayload = { | 59 | export 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 @@ | |||
1 | import { FollowState } from '../actors' | 1 | import { FollowState } from '../actors' |
2 | import { AbuseState } from '../moderation' | 2 | import { AbuseState } from '../moderation' |
3 | import { PluginType } from '../plugins' | ||
3 | 4 | ||
4 | export enum UserNotificationType { | 5 | export 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 | ||
32 | export interface VideoInfo { | 36 | export 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 @@ | |||
1 | import { Actor } from '../../actors/actor.model' | 1 | import { Actor } from '../../actors/actor.model' |
2 | import { Account } from '../../actors/index' | 2 | import { Account, ActorImage } from '../../actors' |
3 | import { Avatar } from '../../avatars' | ||
4 | 3 | ||
5 | export type ViewsPerDate = { | 4 | export 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 | ||
21 | export interface VideoChannelSummary { | 22 | export 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: { | |||
12 | export interface EncoderOptions { | 12 | export 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 |