diff options
Diffstat (limited to 'server/controllers/api')
-rw-r--r-- | server/controllers/api/accounts.ts | 13 | ||||
-rw-r--r-- | server/controllers/api/config.ts | 33 | ||||
-rw-r--r-- | server/controllers/api/index.ts | 4 | ||||
-rw-r--r-- | server/controllers/api/jobs.ts | 2 | ||||
-rw-r--r-- | server/controllers/api/overviews.ts | 2 | ||||
-rw-r--r-- | server/controllers/api/server/debug.ts | 6 | ||||
-rw-r--r-- | server/controllers/api/server/follows.ts | 5 | ||||
-rw-r--r-- | server/controllers/api/server/logs.ts | 10 | ||||
-rw-r--r-- | server/controllers/api/server/redundancy.ts | 84 | ||||
-rw-r--r-- | server/controllers/api/server/stats.ts | 10 | ||||
-rw-r--r-- | server/controllers/api/users/index.ts | 18 | ||||
-rw-r--r-- | server/controllers/api/users/me.ts | 4 | ||||
-rw-r--r-- | server/controllers/api/users/my-subscriptions.ts | 6 | ||||
-rw-r--r-- | server/controllers/api/video-channel.ts | 3 | ||||
-rw-r--r-- | server/controllers/api/video-playlist.ts | 1 | ||||
-rw-r--r-- | server/controllers/api/videos/captions.ts | 2 | ||||
-rw-r--r-- | server/controllers/api/videos/import.ts | 22 | ||||
-rw-r--r-- | server/controllers/api/videos/index.ts | 7 |
18 files changed, 160 insertions, 72 deletions
diff --git a/server/controllers/api/accounts.ts b/server/controllers/api/accounts.ts index 05740318e..f354ccf24 100644 --- a/server/controllers/api/accounts.ts +++ b/server/controllers/api/accounts.ts | |||
@@ -16,21 +16,17 @@ import { | |||
16 | accountNameWithHostGetValidator, | 16 | accountNameWithHostGetValidator, |
17 | accountsSortValidator, | 17 | accountsSortValidator, |
18 | ensureAuthUserOwnsAccountValidator, | 18 | ensureAuthUserOwnsAccountValidator, |
19 | videosSortValidator, | 19 | videoChannelsSortValidator, |
20 | videoChannelsSortValidator | 20 | videosSortValidator |
21 | } from '../../middlewares/validators' | 21 | } from '../../middlewares/validators' |
22 | import { AccountModel } from '../../models/account/account' | 22 | import { AccountModel } from '../../models/account/account' |
23 | import { AccountVideoRateModel } from '../../models/account/account-video-rate' | 23 | import { AccountVideoRateModel } from '../../models/account/account-video-rate' |
24 | import { VideoModel } from '../../models/video/video' | 24 | import { VideoModel } from '../../models/video/video' |
25 | import { buildNSFWFilter, isUserAbleToSearchRemoteURI, getCountVideos } from '../../helpers/express-utils' | 25 | import { buildNSFWFilter, getCountVideos, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils' |
26 | import { VideoChannelModel } from '../../models/video/video-channel' | 26 | import { VideoChannelModel } from '../../models/video/video-channel' |
27 | import { JobQueue } from '../../lib/job-queue' | 27 | import { JobQueue } from '../../lib/job-queue' |
28 | import { logger } from '../../helpers/logger' | ||
29 | import { VideoPlaylistModel } from '../../models/video/video-playlist' | 28 | import { VideoPlaylistModel } from '../../models/video/video-playlist' |
30 | import { | 29 | import { commonVideoPlaylistFiltersValidator, videoPlaylistsSearchValidator } from '../../middlewares/validators/videos/video-playlists' |
31 | commonVideoPlaylistFiltersValidator, | ||
32 | videoPlaylistsSearchValidator | ||
33 | } from '../../middlewares/validators/videos/video-playlists' | ||
34 | 30 | ||
35 | const accountsRouter = express.Router() | 31 | const accountsRouter = express.Router() |
36 | 32 | ||
@@ -104,7 +100,6 @@ function getAccount (req: express.Request, res: express.Response) { | |||
104 | 100 | ||
105 | if (account.isOutdated()) { | 101 | if (account.isOutdated()) { |
106 | JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'actor', url: account.Actor.url } }) | 102 | JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'actor', url: account.Actor.url } }) |
107 | .catch(err => logger.error('Cannot create AP refresher job for actor %s.', account.Actor.url, { err })) | ||
108 | } | 103 | } |
109 | 104 | ||
110 | return res.json(account.toFormattedJSON()) | 105 | return res.json(account.toFormattedJSON()) |
diff --git a/server/controllers/api/config.ts b/server/controllers/api/config.ts index ae4e00248..06fe30371 100644 --- a/server/controllers/api/config.ts +++ b/server/controllers/api/config.ts | |||
@@ -11,10 +11,9 @@ import { ClientHtml } from '../../lib/client-html' | |||
11 | import { auditLoggerFactory, CustomConfigAuditView, getAuditIdFromRes } from '../../helpers/audit-logger' | 11 | import { auditLoggerFactory, CustomConfigAuditView, getAuditIdFromRes } from '../../helpers/audit-logger' |
12 | import { remove, writeJSON } from 'fs-extra' | 12 | import { remove, writeJSON } from 'fs-extra' |
13 | import { getServerCommit } from '../../helpers/utils' | 13 | import { getServerCommit } from '../../helpers/utils' |
14 | import { Emailer } from '../../lib/emailer' | ||
15 | import validator from 'validator' | 14 | import validator from 'validator' |
16 | import { objectConverter } from '../../helpers/core-utils' | 15 | import { objectConverter } from '../../helpers/core-utils' |
17 | import { CONFIG, reloadConfig } from '../../initializers/config' | 16 | import { CONFIG, isEmailEnabled, reloadConfig } from '../../initializers/config' |
18 | import { PluginManager } from '../../lib/plugins/plugin-manager' | 17 | import { PluginManager } from '../../lib/plugins/plugin-manager' |
19 | import { getThemeOrDefault } from '../../lib/plugins/theme-utils' | 18 | import { getThemeOrDefault } from '../../lib/plugins/theme-utils' |
20 | import { Hooks } from '@server/lib/plugins/hooks' | 19 | import { Hooks } from '@server/lib/plugins/hooks' |
@@ -31,12 +30,12 @@ configRouter.get('/', | |||
31 | configRouter.get('/custom', | 30 | configRouter.get('/custom', |
32 | authenticate, | 31 | authenticate, |
33 | ensureUserHasRight(UserRight.MANAGE_CONFIGURATION), | 32 | ensureUserHasRight(UserRight.MANAGE_CONFIGURATION), |
34 | asyncMiddleware(getCustomConfig) | 33 | getCustomConfig |
35 | ) | 34 | ) |
36 | configRouter.put('/custom', | 35 | configRouter.put('/custom', |
37 | authenticate, | 36 | authenticate, |
38 | ensureUserHasRight(UserRight.MANAGE_CONFIGURATION), | 37 | ensureUserHasRight(UserRight.MANAGE_CONFIGURATION), |
39 | asyncMiddleware(customConfigUpdateValidator), | 38 | customConfigUpdateValidator, |
40 | asyncMiddleware(updateCustomConfig) | 39 | asyncMiddleware(updateCustomConfig) |
41 | ) | 40 | ) |
42 | configRouter.delete('/custom', | 41 | configRouter.delete('/custom', |
@@ -73,6 +72,12 @@ async function getConfig (req: express.Request, res: express.Response) { | |||
73 | css: CONFIG.INSTANCE.CUSTOMIZATIONS.CSS | 72 | css: CONFIG.INSTANCE.CUSTOMIZATIONS.CSS |
74 | } | 73 | } |
75 | }, | 74 | }, |
75 | search: { | ||
76 | remoteUri: { | ||
77 | users: CONFIG.SEARCH.REMOTE_URI.USERS, | ||
78 | anonymous: CONFIG.SEARCH.REMOTE_URI.ANONYMOUS | ||
79 | } | ||
80 | }, | ||
76 | plugin: { | 81 | plugin: { |
77 | registered: getRegisteredPlugins() | 82 | registered: getRegisteredPlugins() |
78 | }, | 83 | }, |
@@ -81,7 +86,7 @@ async function getConfig (req: express.Request, res: express.Response) { | |||
81 | default: defaultTheme | 86 | default: defaultTheme |
82 | }, | 87 | }, |
83 | email: { | 88 | email: { |
84 | enabled: Emailer.isEnabled() | 89 | enabled: isEmailEnabled() |
85 | }, | 90 | }, |
86 | contactForm: { | 91 | contactForm: { |
87 | enabled: CONFIG.CONTACT_FORM.ENABLED | 92 | enabled: CONFIG.CONTACT_FORM.ENABLED |
@@ -196,7 +201,7 @@ function getAbout (req: express.Request, res: express.Response) { | |||
196 | return res.json(about).end() | 201 | return res.json(about).end() |
197 | } | 202 | } |
198 | 203 | ||
199 | async function getCustomConfig (req: express.Request, res: express.Response) { | 204 | function getCustomConfig (req: express.Request, res: express.Response) { |
200 | const data = customConfig() | 205 | const data = customConfig() |
201 | 206 | ||
202 | return res.json(data).end() | 207 | return res.json(data).end() |
@@ -250,7 +255,7 @@ function getRegisteredThemes () { | |||
250 | 255 | ||
251 | function getEnabledResolutions () { | 256 | function getEnabledResolutions () { |
252 | return Object.keys(CONFIG.TRANSCODING.RESOLUTIONS) | 257 | return Object.keys(CONFIG.TRANSCODING.RESOLUTIONS) |
253 | .filter(key => CONFIG.TRANSCODING.ENABLED && CONFIG.TRANSCODING.RESOLUTIONS[ key ] === true) | 258 | .filter(key => CONFIG.TRANSCODING.ENABLED && CONFIG.TRANSCODING.RESOLUTIONS[key] === true) |
254 | .map(r => parseInt(r, 10)) | 259 | .map(r => parseInt(r, 10)) |
255 | } | 260 | } |
256 | 261 | ||
@@ -340,13 +345,13 @@ function customConfig (): CustomConfig { | |||
340 | allowAudioFiles: CONFIG.TRANSCODING.ALLOW_AUDIO_FILES, | 345 | allowAudioFiles: CONFIG.TRANSCODING.ALLOW_AUDIO_FILES, |
341 | threads: CONFIG.TRANSCODING.THREADS, | 346 | threads: CONFIG.TRANSCODING.THREADS, |
342 | resolutions: { | 347 | resolutions: { |
343 | '0p': CONFIG.TRANSCODING.RESOLUTIONS[ '0p' ], | 348 | '0p': CONFIG.TRANSCODING.RESOLUTIONS['0p'], |
344 | '240p': CONFIG.TRANSCODING.RESOLUTIONS[ '240p' ], | 349 | '240p': CONFIG.TRANSCODING.RESOLUTIONS['240p'], |
345 | '360p': CONFIG.TRANSCODING.RESOLUTIONS[ '360p' ], | 350 | '360p': CONFIG.TRANSCODING.RESOLUTIONS['360p'], |
346 | '480p': CONFIG.TRANSCODING.RESOLUTIONS[ '480p' ], | 351 | '480p': CONFIG.TRANSCODING.RESOLUTIONS['480p'], |
347 | '720p': CONFIG.TRANSCODING.RESOLUTIONS[ '720p' ], | 352 | '720p': CONFIG.TRANSCODING.RESOLUTIONS['720p'], |
348 | '1080p': CONFIG.TRANSCODING.RESOLUTIONS[ '1080p' ], | 353 | '1080p': CONFIG.TRANSCODING.RESOLUTIONS['1080p'], |
349 | '2160p': CONFIG.TRANSCODING.RESOLUTIONS[ '2160p' ] | 354 | '2160p': CONFIG.TRANSCODING.RESOLUTIONS['2160p'] |
350 | }, | 355 | }, |
351 | webtorrent: { | 356 | webtorrent: { |
352 | enabled: CONFIG.TRANSCODING.WEBTORRENT.ENABLED | 357 | enabled: CONFIG.TRANSCODING.WEBTORRENT.ENABLED |
diff --git a/server/controllers/api/index.ts b/server/controllers/api/index.ts index 6138a32de..7bec6c527 100644 --- a/server/controllers/api/index.ts +++ b/server/controllers/api/index.ts | |||
@@ -1,5 +1,4 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import * as RateLimit from 'express-rate-limit' | ||
3 | import { configRouter } from './config' | 2 | import { configRouter } from './config' |
4 | import { jobsRouter } from './jobs' | 3 | import { jobsRouter } from './jobs' |
5 | import { oauthClientsRouter } from './oauth-clients' | 4 | import { oauthClientsRouter } from './oauth-clients' |
@@ -15,6 +14,7 @@ import { overviewsRouter } from './overviews' | |||
15 | import { videoPlaylistRouter } from './video-playlist' | 14 | import { videoPlaylistRouter } from './video-playlist' |
16 | import { CONFIG } from '../../initializers/config' | 15 | import { CONFIG } from '../../initializers/config' |
17 | import { pluginRouter } from './plugins' | 16 | import { pluginRouter } from './plugins' |
17 | import * as RateLimit from 'express-rate-limit' | ||
18 | 18 | ||
19 | const apiRouter = express.Router() | 19 | const apiRouter = express.Router() |
20 | 20 | ||
@@ -24,8 +24,6 @@ apiRouter.use(cors({ | |||
24 | credentials: true | 24 | credentials: true |
25 | })) | 25 | })) |
26 | 26 | ||
27 | // FIXME: https://github.com/nfriedly/express-rate-limit/issues/138 | ||
28 | // @ts-ignore | ||
29 | const apiRateLimiter = RateLimit({ | 27 | const apiRateLimiter = RateLimit({ |
30 | windowMs: CONFIG.RATES_LIMIT.API.WINDOW_MS, | 28 | windowMs: CONFIG.RATES_LIMIT.API.WINDOW_MS, |
31 | max: CONFIG.RATES_LIMIT.API.MAX | 29 | max: CONFIG.RATES_LIMIT.API.MAX |
diff --git a/server/controllers/api/jobs.ts b/server/controllers/api/jobs.ts index 05320311e..13fc04d18 100644 --- a/server/controllers/api/jobs.ts +++ b/server/controllers/api/jobs.ts | |||
@@ -50,7 +50,7 @@ async function listJobs (req: express.Request, res: express.Response) { | |||
50 | }) | 50 | }) |
51 | const total = await JobQueue.Instance.count(state) | 51 | const total = await JobQueue.Instance.count(state) |
52 | 52 | ||
53 | const result: ResultList<any> = { | 53 | const result: ResultList<Job> = { |
54 | total, | 54 | total, |
55 | data: jobs.map(j => formatJob(j, state)) | 55 | data: jobs.map(j => formatJob(j, state)) |
56 | } | 56 | } |
diff --git a/server/controllers/api/overviews.ts b/server/controllers/api/overviews.ts index 46e76ac6b..75f3baedb 100644 --- a/server/controllers/api/overviews.ts +++ b/server/controllers/api/overviews.ts | |||
@@ -24,7 +24,7 @@ export { overviewsRouter } | |||
24 | const buildSamples = memoizee(async function () { | 24 | const buildSamples = memoizee(async function () { |
25 | const [ categories, channels, tags ] = await Promise.all([ | 25 | const [ categories, channels, tags ] = await Promise.all([ |
26 | VideoModel.getRandomFieldSamples('category', OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD, OVERVIEWS.VIDEOS.SAMPLES_COUNT), | 26 | VideoModel.getRandomFieldSamples('category', OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD, OVERVIEWS.VIDEOS.SAMPLES_COUNT), |
27 | VideoModel.getRandomFieldSamples('channelId', OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD ,OVERVIEWS.VIDEOS.SAMPLES_COUNT), | 27 | VideoModel.getRandomFieldSamples('channelId', OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD, OVERVIEWS.VIDEOS.SAMPLES_COUNT), |
28 | TagModel.getRandomSamples(OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD, OVERVIEWS.VIDEOS.SAMPLES_COUNT) | 28 | TagModel.getRandomSamples(OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD, OVERVIEWS.VIDEOS.SAMPLES_COUNT) |
29 | ]) | 29 | ]) |
30 | 30 | ||
diff --git a/server/controllers/api/server/debug.ts b/server/controllers/api/server/debug.ts index 4450038f6..e12fc1dd4 100644 --- a/server/controllers/api/server/debug.ts +++ b/server/controllers/api/server/debug.ts | |||
@@ -1,13 +1,13 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { UserRight } from '../../../../shared/models/users' | 2 | import { UserRight } from '../../../../shared/models/users' |
3 | import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../../middlewares' | 3 | import { authenticate, ensureUserHasRight } from '../../../middlewares' |
4 | 4 | ||
5 | const debugRouter = express.Router() | 5 | const debugRouter = express.Router() |
6 | 6 | ||
7 | debugRouter.get('/debug', | 7 | debugRouter.get('/debug', |
8 | authenticate, | 8 | authenticate, |
9 | ensureUserHasRight(UserRight.MANAGE_DEBUG), | 9 | ensureUserHasRight(UserRight.MANAGE_DEBUG), |
10 | asyncMiddleware(getDebug) | 10 | getDebug |
11 | ) | 11 | ) |
12 | 12 | ||
13 | // --------------------------------------------------------------------------- | 13 | // --------------------------------------------------------------------------- |
@@ -18,7 +18,7 @@ export { | |||
18 | 18 | ||
19 | // --------------------------------------------------------------------------- | 19 | // --------------------------------------------------------------------------- |
20 | 20 | ||
21 | async function getDebug (req: express.Request, res: express.Response) { | 21 | function getDebug (req: express.Request, res: express.Response) { |
22 | return res.json({ | 22 | return res.json({ |
23 | ip: req.ip | 23 | ip: req.ip |
24 | }).end() | 24 | }).end() |
diff --git a/server/controllers/api/server/follows.ts b/server/controllers/api/server/follows.ts index 29a403a43..0bc20bd60 100644 --- a/server/controllers/api/server/follows.ts +++ b/server/controllers/api/server/follows.ts | |||
@@ -24,7 +24,7 @@ import { | |||
24 | } from '../../../middlewares/validators' | 24 | } from '../../../middlewares/validators' |
25 | import { ActorFollowModel } from '../../../models/activitypub/actor-follow' | 25 | import { ActorFollowModel } from '../../../models/activitypub/actor-follow' |
26 | import { JobQueue } from '../../../lib/job-queue' | 26 | import { JobQueue } from '../../../lib/job-queue' |
27 | import { removeRedundancyOf } from '../../../lib/redundancy' | 27 | import { removeRedundanciesOfServer } from '../../../lib/redundancy' |
28 | import { sequelizeTypescript } from '../../../initializers/database' | 28 | import { sequelizeTypescript } from '../../../initializers/database' |
29 | import { autoFollowBackIfNeeded } from '../../../lib/activitypub/follow' | 29 | import { autoFollowBackIfNeeded } from '../../../lib/activitypub/follow' |
30 | 30 | ||
@@ -135,7 +135,6 @@ async function followInstance (req: express.Request, res: express.Response) { | |||
135 | } | 135 | } |
136 | 136 | ||
137 | JobQueue.Instance.createJob({ type: 'activitypub-follow', payload }) | 137 | JobQueue.Instance.createJob({ type: 'activitypub-follow', payload }) |
138 | .catch(err => logger.error('Cannot create follow job for %s.', host, err)) | ||
139 | } | 138 | } |
140 | 139 | ||
141 | return res.status(204).end() | 140 | return res.status(204).end() |
@@ -153,7 +152,7 @@ async function removeFollowing (req: express.Request, res: express.Response) { | |||
153 | await server.save({ transaction: t }) | 152 | await server.save({ transaction: t }) |
154 | 153 | ||
155 | // Async, could be long | 154 | // Async, could be long |
156 | removeRedundancyOf(server.id) | 155 | removeRedundanciesOfServer(server.id) |
157 | .catch(err => logger.error('Cannot remove redundancy of %s.', server.host, err)) | 156 | .catch(err => logger.error('Cannot remove redundancy of %s.', server.host, err)) |
158 | 157 | ||
159 | await follow.destroy({ transaction: t }) | 158 | await follow.destroy({ transaction: t }) |
diff --git a/server/controllers/api/server/logs.ts b/server/controllers/api/server/logs.ts index cd1e0f5bf..4b543d686 100644 --- a/server/controllers/api/server/logs.ts +++ b/server/controllers/api/server/logs.ts | |||
@@ -59,9 +59,9 @@ async function getLogs (req: express.Request, res: express.Response) { | |||
59 | } | 59 | } |
60 | 60 | ||
61 | async function generateOutput (options: { | 61 | async function generateOutput (options: { |
62 | startDateQuery: string, | 62 | startDateQuery: string |
63 | endDateQuery?: string, | 63 | endDateQuery?: string |
64 | level: LogLevel, | 64 | level: LogLevel |
65 | nameFilter: RegExp | 65 | nameFilter: RegExp |
66 | }) { | 66 | }) { |
67 | const { startDateQuery, level, nameFilter } = options | 67 | const { startDateQuery, level, nameFilter } = options |
@@ -111,7 +111,7 @@ async function getOutputFromFile (path: string, startDate: Date, endDate: Date, | |||
111 | const output: any[] = [] | 111 | const output: any[] = [] |
112 | 112 | ||
113 | for (let i = lines.length - 1; i >= 0; i--) { | 113 | for (let i = lines.length - 1; i >= 0; i--) { |
114 | const line = lines[ i ] | 114 | const line = lines[i] |
115 | let log: any | 115 | let log: any |
116 | 116 | ||
117 | try { | 117 | try { |
@@ -122,7 +122,7 @@ async function getOutputFromFile (path: string, startDate: Date, endDate: Date, | |||
122 | } | 122 | } |
123 | 123 | ||
124 | logTime = new Date(log.timestamp).getTime() | 124 | logTime = new Date(log.timestamp).getTime() |
125 | if (logTime >= startTime && logTime <= endTime && logsLevel[ log.level ] >= logsLevel[ level ]) { | 125 | if (logTime >= startTime && logTime <= endTime && logsLevel[log.level] >= logsLevel[level]) { |
126 | output.push(log) | 126 | output.push(log) |
127 | 127 | ||
128 | currentSize += line.length | 128 | currentSize += line.length |
diff --git a/server/controllers/api/server/redundancy.ts b/server/controllers/api/server/redundancy.ts index 4ea6164a3..1ced0759e 100644 --- a/server/controllers/api/server/redundancy.ts +++ b/server/controllers/api/server/redundancy.ts | |||
@@ -1,9 +1,24 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { UserRight } from '../../../../shared/models/users' | 2 | import { UserRight } from '../../../../shared/models/users' |
3 | import { asyncMiddleware, authenticate, ensureUserHasRight } from '../../../middlewares' | 3 | import { |
4 | import { updateServerRedundancyValidator } from '../../../middlewares/validators/redundancy' | 4 | asyncMiddleware, |
5 | import { removeRedundancyOf } from '../../../lib/redundancy' | 5 | authenticate, |
6 | ensureUserHasRight, | ||
7 | paginationValidator, | ||
8 | setDefaultPagination, | ||
9 | setDefaultVideoRedundanciesSort, | ||
10 | videoRedundanciesSortValidator | ||
11 | } from '../../../middlewares' | ||
12 | import { | ||
13 | listVideoRedundanciesValidator, | ||
14 | updateServerRedundancyValidator, | ||
15 | addVideoRedundancyValidator, | ||
16 | removeVideoRedundancyValidator | ||
17 | } from '../../../middlewares/validators/redundancy' | ||
18 | import { removeRedundanciesOfServer, removeVideoRedundancy } from '../../../lib/redundancy' | ||
6 | import { logger } from '../../../helpers/logger' | 19 | import { logger } from '../../../helpers/logger' |
20 | import { VideoRedundancyModel } from '@server/models/redundancy/video-redundancy' | ||
21 | import { JobQueue } from '@server/lib/job-queue' | ||
7 | 22 | ||
8 | const serverRedundancyRouter = express.Router() | 23 | const serverRedundancyRouter = express.Router() |
9 | 24 | ||
@@ -14,6 +29,31 @@ serverRedundancyRouter.put('/redundancy/:host', | |||
14 | asyncMiddleware(updateRedundancy) | 29 | asyncMiddleware(updateRedundancy) |
15 | ) | 30 | ) |
16 | 31 | ||
32 | serverRedundancyRouter.get('/redundancy/videos', | ||
33 | authenticate, | ||
34 | ensureUserHasRight(UserRight.MANAGE_VIDEOS_REDUNDANCIES), | ||
35 | listVideoRedundanciesValidator, | ||
36 | paginationValidator, | ||
37 | videoRedundanciesSortValidator, | ||
38 | setDefaultVideoRedundanciesSort, | ||
39 | setDefaultPagination, | ||
40 | asyncMiddleware(listVideoRedundancies) | ||
41 | ) | ||
42 | |||
43 | serverRedundancyRouter.post('/redundancy/videos', | ||
44 | authenticate, | ||
45 | ensureUserHasRight(UserRight.MANAGE_VIDEOS_REDUNDANCIES), | ||
46 | addVideoRedundancyValidator, | ||
47 | asyncMiddleware(addVideoRedundancy) | ||
48 | ) | ||
49 | |||
50 | serverRedundancyRouter.delete('/redundancy/videos/:redundancyId', | ||
51 | authenticate, | ||
52 | ensureUserHasRight(UserRight.MANAGE_VIDEOS_REDUNDANCIES), | ||
53 | removeVideoRedundancyValidator, | ||
54 | asyncMiddleware(removeVideoRedundancyController) | ||
55 | ) | ||
56 | |||
17 | // --------------------------------------------------------------------------- | 57 | // --------------------------------------------------------------------------- |
18 | 58 | ||
19 | export { | 59 | export { |
@@ -22,6 +62,42 @@ export { | |||
22 | 62 | ||
23 | // --------------------------------------------------------------------------- | 63 | // --------------------------------------------------------------------------- |
24 | 64 | ||
65 | async function listVideoRedundancies (req: express.Request, res: express.Response) { | ||
66 | const resultList = await VideoRedundancyModel.listForApi({ | ||
67 | start: req.query.start, | ||
68 | count: req.query.count, | ||
69 | sort: req.query.sort, | ||
70 | target: req.query.target, | ||
71 | strategy: req.query.strategy | ||
72 | }) | ||
73 | |||
74 | const result = { | ||
75 | total: resultList.total, | ||
76 | data: resultList.data.map(r => VideoRedundancyModel.toFormattedJSONStatic(r)) | ||
77 | } | ||
78 | |||
79 | return res.json(result) | ||
80 | } | ||
81 | |||
82 | async function addVideoRedundancy (req: express.Request, res: express.Response) { | ||
83 | const payload = { | ||
84 | videoId: res.locals.onlyVideo.id | ||
85 | } | ||
86 | |||
87 | await JobQueue.Instance.createJobWithPromise({ | ||
88 | type: 'video-redundancy', | ||
89 | payload | ||
90 | }) | ||
91 | |||
92 | return res.sendStatus(204) | ||
93 | } | ||
94 | |||
95 | async function removeVideoRedundancyController (req: express.Request, res: express.Response) { | ||
96 | await removeVideoRedundancy(res.locals.videoRedundancy) | ||
97 | |||
98 | return res.sendStatus(204) | ||
99 | } | ||
100 | |||
25 | async function updateRedundancy (req: express.Request, res: express.Response) { | 101 | async function updateRedundancy (req: express.Request, res: express.Response) { |
26 | const server = res.locals.server | 102 | const server = res.locals.server |
27 | 103 | ||
@@ -30,7 +106,7 @@ async function updateRedundancy (req: express.Request, res: express.Response) { | |||
30 | await server.save() | 106 | await server.save() |
31 | 107 | ||
32 | // Async, could be long | 108 | // Async, could be long |
33 | removeRedundancyOf(server.id) | 109 | removeRedundanciesOfServer(server.id) |
34 | .catch(err => logger.error('Cannot remove redundancy of %s.', server.host, { err })) | 110 | .catch(err => logger.error('Cannot remove redundancy of %s.', server.host, { err })) |
35 | 111 | ||
36 | return res.sendStatus(204) | 112 | return res.sendStatus(204) |
diff --git a/server/controllers/api/server/stats.ts b/server/controllers/api/server/stats.ts index 3616c074d..6d508a481 100644 --- a/server/controllers/api/server/stats.ts +++ b/server/controllers/api/server/stats.ts | |||
@@ -10,6 +10,7 @@ import { ROUTE_CACHE_LIFETIME } from '../../../initializers/constants' | |||
10 | import { cacheRoute } from '../../../middlewares/cache' | 10 | import { cacheRoute } from '../../../middlewares/cache' |
11 | import { VideoFileModel } from '../../../models/video/video-file' | 11 | import { VideoFileModel } from '../../../models/video/video-file' |
12 | import { CONFIG } from '../../../initializers/config' | 12 | import { CONFIG } from '../../../initializers/config' |
13 | import { VideoRedundancyStrategyWithManual } from '@shared/models' | ||
13 | 14 | ||
14 | const statsRouter = express.Router() | 15 | const statsRouter = express.Router() |
15 | 16 | ||
@@ -25,8 +26,15 @@ async function getStats (req: express.Request, res: express.Response) { | |||
25 | const { totalInstanceFollowers, totalInstanceFollowing } = await ActorFollowModel.getStats() | 26 | const { totalInstanceFollowers, totalInstanceFollowing } = await ActorFollowModel.getStats() |
26 | const { totalLocalVideoFilesSize } = await VideoFileModel.getStats() | 27 | const { totalLocalVideoFilesSize } = await VideoFileModel.getStats() |
27 | 28 | ||
29 | const strategies: { strategy: VideoRedundancyStrategyWithManual, size: number }[] = CONFIG.REDUNDANCY.VIDEOS.STRATEGIES | ||
30 | .map(r => ({ | ||
31 | strategy: r.strategy, | ||
32 | size: r.size | ||
33 | })) | ||
34 | strategies.push({ strategy: 'manual', size: null }) | ||
35 | |||
28 | const videosRedundancyStats = await Promise.all( | 36 | const videosRedundancyStats = await Promise.all( |
29 | CONFIG.REDUNDANCY.VIDEOS.STRATEGIES.map(r => { | 37 | strategies.map(r => { |
30 | return VideoRedundancyModel.getStats(r.strategy) | 38 | return VideoRedundancyModel.getStats(r.strategy) |
31 | .then(stats => Object.assign(stats, { strategy: r.strategy, totalSize: r.size })) | 39 | .then(stats => Object.assign(stats, { strategy: r.strategy, totalSize: r.size })) |
32 | }) | 40 | }) |
diff --git a/server/controllers/api/users/index.ts b/server/controllers/api/users/index.ts index b960e80c1..98eb2beed 100644 --- a/server/controllers/api/users/index.ts +++ b/server/controllers/api/users/index.ts | |||
@@ -2,7 +2,7 @@ import * as express from 'express' | |||
2 | import * as RateLimit from 'express-rate-limit' | 2 | import * as RateLimit from 'express-rate-limit' |
3 | import { UserCreate, UserRight, UserRole, UserUpdate } from '../../../../shared' | 3 | import { UserCreate, UserRight, UserRole, UserUpdate } from '../../../../shared' |
4 | import { logger } from '../../../helpers/logger' | 4 | import { logger } from '../../../helpers/logger' |
5 | import { getFormattedObjects } from '../../../helpers/utils' | 5 | import { generateRandomString, getFormattedObjects } from '../../../helpers/utils' |
6 | import { WEBSERVER } from '../../../initializers/constants' | 6 | import { WEBSERVER } from '../../../initializers/constants' |
7 | import { Emailer } from '../../../lib/emailer' | 7 | import { Emailer } from '../../../lib/emailer' |
8 | import { Redis } from '../../../lib/redis' | 8 | import { Redis } from '../../../lib/redis' |
@@ -53,8 +53,6 @@ import { Hooks } from '@server/lib/plugins/hooks' | |||
53 | 53 | ||
54 | const auditLogger = auditLoggerFactory('users') | 54 | const auditLogger = auditLoggerFactory('users') |
55 | 55 | ||
56 | // FIXME: https://github.com/nfriedly/express-rate-limit/issues/138 | ||
57 | // @ts-ignore | ||
58 | const loginRateLimiter = RateLimit({ | 56 | const loginRateLimiter = RateLimit({ |
59 | windowMs: CONFIG.RATES_LIMIT.LOGIN.WINDOW_MS, | 57 | windowMs: CONFIG.RATES_LIMIT.LOGIN.WINDOW_MS, |
60 | max: CONFIG.RATES_LIMIT.LOGIN.MAX | 58 | max: CONFIG.RATES_LIMIT.LOGIN.MAX |
@@ -199,11 +197,25 @@ async function createUser (req: express.Request, res: express.Response) { | |||
199 | adminFlags: body.adminFlags || UserAdminFlag.NONE | 197 | adminFlags: body.adminFlags || UserAdminFlag.NONE |
200 | }) as MUser | 198 | }) as MUser |
201 | 199 | ||
200 | // NB: due to the validator usersAddValidator, password==='' can only be true if we can send the mail. | ||
201 | const createPassword = userToCreate.password === '' | ||
202 | if (createPassword) { | ||
203 | userToCreate.password = await generateRandomString(20) | ||
204 | } | ||
205 | |||
202 | const { user, account, videoChannel } = await createUserAccountAndChannelAndPlaylist({ userToCreate: userToCreate }) | 206 | const { user, account, videoChannel } = await createUserAccountAndChannelAndPlaylist({ userToCreate: userToCreate }) |
203 | 207 | ||
204 | auditLogger.create(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON())) | 208 | auditLogger.create(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON())) |
205 | logger.info('User %s with its channel and account created.', body.username) | 209 | logger.info('User %s with its channel and account created.', body.username) |
206 | 210 | ||
211 | if (createPassword) { | ||
212 | // this will send an email for newly created users, so then can set their first password. | ||
213 | logger.info('Sending to user %s a create password email', body.username) | ||
214 | const verificationString = await Redis.Instance.setCreatePasswordVerificationString(user.id) | ||
215 | const url = WEBSERVER.URL + '/reset-password?userId=' + user.id + '&verificationString=' + verificationString | ||
216 | await Emailer.Instance.addPasswordCreateEmailJob(userToCreate.username, user.email, url) | ||
217 | } | ||
218 | |||
207 | Hooks.runAction('action:api.user.created', { body, user, account, videoChannel }) | 219 | Hooks.runAction('action:api.user.created', { body, user, account, videoChannel }) |
208 | 220 | ||
209 | return res.json({ | 221 | return res.json({ |
diff --git a/server/controllers/api/users/me.ts b/server/controllers/api/users/me.ts index ac7c62aab..23890e20c 100644 --- a/server/controllers/api/users/me.ts +++ b/server/controllers/api/users/me.ts | |||
@@ -39,7 +39,7 @@ meRouter.get('/me', | |||
39 | ) | 39 | ) |
40 | meRouter.delete('/me', | 40 | meRouter.delete('/me', |
41 | authenticate, | 41 | authenticate, |
42 | asyncMiddleware(deleteMeValidator), | 42 | deleteMeValidator, |
43 | asyncMiddleware(deleteMe) | 43 | asyncMiddleware(deleteMe) |
44 | ) | 44 | ) |
45 | 45 | ||
@@ -214,7 +214,7 @@ async function updateMe (req: express.Request, res: express.Response) { | |||
214 | } | 214 | } |
215 | 215 | ||
216 | async function updateMyAvatar (req: express.Request, res: express.Response) { | 216 | async function updateMyAvatar (req: express.Request, res: express.Response) { |
217 | const avatarPhysicalFile = req.files[ 'avatarfile' ][ 0 ] | 217 | const avatarPhysicalFile = req.files['avatarfile'][0] |
218 | const user = res.locals.oauth.token.user | 218 | const user = res.locals.oauth.token.user |
219 | 219 | ||
220 | const userAccount = await AccountModel.load(user.Account.id) | 220 | const userAccount = await AccountModel.load(user.Account.id) |
diff --git a/server/controllers/api/users/my-subscriptions.ts b/server/controllers/api/users/my-subscriptions.ts index 43c4c37d8..888392b8b 100644 --- a/server/controllers/api/users/my-subscriptions.ts +++ b/server/controllers/api/users/my-subscriptions.ts | |||
@@ -19,7 +19,6 @@ import { buildNSFWFilter, getCountVideos } from '../../../helpers/express-utils' | |||
19 | import { VideoFilter } from '../../../../shared/models/videos/video-query.type' | 19 | import { VideoFilter } from '../../../../shared/models/videos/video-query.type' |
20 | import { ActorFollowModel } from '../../../models/activitypub/actor-follow' | 20 | import { ActorFollowModel } from '../../../models/activitypub/actor-follow' |
21 | import { JobQueue } from '../../../lib/job-queue' | 21 | import { JobQueue } from '../../../lib/job-queue' |
22 | import { logger } from '../../../helpers/logger' | ||
23 | import { sequelizeTypescript } from '../../../initializers/database' | 22 | import { sequelizeTypescript } from '../../../initializers/database' |
24 | 23 | ||
25 | const mySubscriptionsRouter = express.Router() | 24 | const mySubscriptionsRouter = express.Router() |
@@ -52,7 +51,7 @@ mySubscriptionsRouter.get('/me/subscriptions', | |||
52 | mySubscriptionsRouter.post('/me/subscriptions', | 51 | mySubscriptionsRouter.post('/me/subscriptions', |
53 | authenticate, | 52 | authenticate, |
54 | userSubscriptionAddValidator, | 53 | userSubscriptionAddValidator, |
55 | asyncMiddleware(addUserSubscription) | 54 | addUserSubscription |
56 | ) | 55 | ) |
57 | 56 | ||
58 | mySubscriptionsRouter.get('/me/subscriptions/:uri', | 57 | mySubscriptionsRouter.get('/me/subscriptions/:uri', |
@@ -106,7 +105,7 @@ async function areSubscriptionsExist (req: express.Request, res: express.Respons | |||
106 | return res.json(existObject) | 105 | return res.json(existObject) |
107 | } | 106 | } |
108 | 107 | ||
109 | async function addUserSubscription (req: express.Request, res: express.Response) { | 108 | function addUserSubscription (req: express.Request, res: express.Response) { |
110 | const user = res.locals.oauth.token.User | 109 | const user = res.locals.oauth.token.User |
111 | const [ name, host ] = req.body.uri.split('@') | 110 | const [ name, host ] = req.body.uri.split('@') |
112 | 111 | ||
@@ -117,7 +116,6 @@ async function addUserSubscription (req: express.Request, res: express.Response) | |||
117 | } | 116 | } |
118 | 117 | ||
119 | JobQueue.Instance.createJob({ type: 'activitypub-follow', payload }) | 118 | JobQueue.Instance.createJob({ type: 'activitypub-follow', payload }) |
120 | .catch(err => logger.error('Cannot create follow job for subscription %s.', req.body.uri, err)) | ||
121 | 119 | ||
122 | return res.status(204).end() | 120 | return res.status(204).end() |
123 | } | 121 | } |
diff --git a/server/controllers/api/video-channel.ts b/server/controllers/api/video-channel.ts index e1f37a8fb..a808896ff 100644 --- a/server/controllers/api/video-channel.ts +++ b/server/controllers/api/video-channel.ts | |||
@@ -119,7 +119,7 @@ async function listVideoChannels (req: express.Request, res: express.Response) { | |||
119 | } | 119 | } |
120 | 120 | ||
121 | async function updateVideoChannelAvatar (req: express.Request, res: express.Response) { | 121 | async function updateVideoChannelAvatar (req: express.Request, res: express.Response) { |
122 | const avatarPhysicalFile = req.files[ 'avatarfile' ][ 0 ] | 122 | const avatarPhysicalFile = req.files['avatarfile'][0] |
123 | const videoChannel = res.locals.videoChannel | 123 | const videoChannel = res.locals.videoChannel |
124 | const oldVideoChannelAuditKeys = new VideoChannelAuditView(videoChannel.toFormattedJSON()) | 124 | const oldVideoChannelAuditKeys = new VideoChannelAuditView(videoChannel.toFormattedJSON()) |
125 | 125 | ||
@@ -232,7 +232,6 @@ async function getVideoChannel (req: express.Request, res: express.Response) { | |||
232 | 232 | ||
233 | if (videoChannelWithVideos.isOutdated()) { | 233 | if (videoChannelWithVideos.isOutdated()) { |
234 | JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'actor', url: videoChannelWithVideos.Actor.url } }) | 234 | JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'actor', url: videoChannelWithVideos.Actor.url } }) |
235 | .catch(err => logger.error('Cannot create AP refresher job for actor %s.', videoChannelWithVideos.Actor.url, { err })) | ||
236 | } | 235 | } |
237 | 236 | ||
238 | return res.json(videoChannelWithVideos.toFormattedJSON()) | 237 | return res.json(videoChannelWithVideos.toFormattedJSON()) |
diff --git a/server/controllers/api/video-playlist.ts b/server/controllers/api/video-playlist.ts index d9f0ff925..b51490bf9 100644 --- a/server/controllers/api/video-playlist.ts +++ b/server/controllers/api/video-playlist.ts | |||
@@ -144,7 +144,6 @@ function getVideoPlaylist (req: express.Request, res: express.Response) { | |||
144 | 144 | ||
145 | if (videoPlaylist.isOutdated()) { | 145 | if (videoPlaylist.isOutdated()) { |
146 | JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'video-playlist', url: videoPlaylist.url } }) | 146 | JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'video-playlist', url: videoPlaylist.url } }) |
147 | .catch(err => logger.error('Cannot create AP refresher job for playlist %s.', videoPlaylist.url, { err })) | ||
148 | } | 147 | } |
149 | 148 | ||
150 | return res.json(videoPlaylist.toFormattedJSON()) | 149 | return res.json(videoPlaylist.toFormattedJSON()) |
diff --git a/server/controllers/api/videos/captions.ts b/server/controllers/api/videos/captions.ts index 37481d12f..fd7b165fb 100644 --- a/server/controllers/api/videos/captions.ts +++ b/server/controllers/api/videos/captions.ts | |||
@@ -66,7 +66,7 @@ async function addVideoCaption (req: express.Request, res: express.Response) { | |||
66 | await moveAndProcessCaptionFile(videoCaptionPhysicalFile, videoCaption) | 66 | await moveAndProcessCaptionFile(videoCaptionPhysicalFile, videoCaption) |
67 | 67 | ||
68 | await sequelizeTypescript.transaction(async t => { | 68 | await sequelizeTypescript.transaction(async t => { |
69 | await VideoCaptionModel.insertOrReplaceLanguage(video.id, req.params.captionLanguage, t) | 69 | await VideoCaptionModel.insertOrReplaceLanguage(video.id, req.params.captionLanguage, null, t) |
70 | 70 | ||
71 | // Update video update | 71 | // Update video update |
72 | await federateVideoIfNeeded(video, false, t) | 72 | await federateVideoIfNeeded(video, false, t) |
diff --git a/server/controllers/api/videos/import.ts b/server/controllers/api/videos/import.ts index 28ced5836..ed223cbc9 100644 --- a/server/controllers/api/videos/import.ts +++ b/server/controllers/api/videos/import.ts | |||
@@ -88,12 +88,12 @@ async function addTorrentImport (req: express.Request, res: express.Response, to | |||
88 | const buf = await readFile(torrentfile.path) | 88 | const buf = await readFile(torrentfile.path) |
89 | const parsedTorrent = parseTorrent(buf) | 89 | const parsedTorrent = parseTorrent(buf) |
90 | 90 | ||
91 | videoName = isArray(parsedTorrent.name) ? parsedTorrent.name[ 0 ] : parsedTorrent.name as string | 91 | videoName = isArray(parsedTorrent.name) ? parsedTorrent.name[0] : parsedTorrent.name as string |
92 | } else { | 92 | } else { |
93 | magnetUri = body.magnetUri | 93 | magnetUri = body.magnetUri |
94 | 94 | ||
95 | const parsed = magnetUtil.decode(magnetUri) | 95 | const parsed = magnetUtil.decode(magnetUri) |
96 | videoName = isArray(parsed.name) ? parsed.name[ 0 ] : parsed.name as string | 96 | videoName = isArray(parsed.name) ? parsed.name[0] : parsed.name as string |
97 | } | 97 | } |
98 | 98 | ||
99 | const video = buildVideo(res.locals.videoChannel.id, body, { name: videoName }) | 99 | const video = buildVideo(res.locals.videoChannel.id, body, { name: videoName }) |
@@ -124,7 +124,7 @@ async function addTorrentImport (req: express.Request, res: express.Response, to | |||
124 | videoImportId: videoImport.id, | 124 | videoImportId: videoImport.id, |
125 | magnetUri | 125 | magnetUri |
126 | } | 126 | } |
127 | await JobQueue.Instance.createJob({ type: 'video-import', payload }) | 127 | await JobQueue.Instance.createJobWithPromise({ type: 'video-import', payload }) |
128 | 128 | ||
129 | auditLogger.create(getAuditIdFromRes(res), new VideoImportAuditView(videoImport.toFormattedJSON())) | 129 | auditLogger.create(getAuditIdFromRes(res), new VideoImportAuditView(videoImport.toFormattedJSON())) |
130 | 130 | ||
@@ -176,7 +176,7 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response) | |||
176 | downloadThumbnail: !thumbnailModel, | 176 | downloadThumbnail: !thumbnailModel, |
177 | downloadPreview: !previewModel | 177 | downloadPreview: !previewModel |
178 | } | 178 | } |
179 | await JobQueue.Instance.createJob({ type: 'video-import', payload }) | 179 | await JobQueue.Instance.createJobWithPromise({ type: 'video-import', payload }) |
180 | 180 | ||
181 | auditLogger.create(getAuditIdFromRes(res), new VideoImportAuditView(videoImport.toFormattedJSON())) | 181 | auditLogger.create(getAuditIdFromRes(res), new VideoImportAuditView(videoImport.toFormattedJSON())) |
182 | 182 | ||
@@ -211,7 +211,7 @@ function buildVideo (channelId: number, body: VideoImportCreate, importData: You | |||
211 | async function processThumbnail (req: express.Request, video: VideoModel) { | 211 | async function processThumbnail (req: express.Request, video: VideoModel) { |
212 | const thumbnailField = req.files ? req.files['thumbnailfile'] : undefined | 212 | const thumbnailField = req.files ? req.files['thumbnailfile'] : undefined |
213 | if (thumbnailField) { | 213 | if (thumbnailField) { |
214 | const thumbnailPhysicalFile = thumbnailField[ 0 ] | 214 | const thumbnailPhysicalFile = thumbnailField[0] |
215 | 215 | ||
216 | return createVideoMiniatureFromExisting(thumbnailPhysicalFile.path, video, ThumbnailType.MINIATURE, false) | 216 | return createVideoMiniatureFromExisting(thumbnailPhysicalFile.path, video, ThumbnailType.MINIATURE, false) |
217 | } | 217 | } |
@@ -231,12 +231,12 @@ async function processPreview (req: express.Request, video: VideoModel) { | |||
231 | } | 231 | } |
232 | 232 | ||
233 | function insertIntoDB (parameters: { | 233 | function insertIntoDB (parameters: { |
234 | video: MVideoThumbnailAccountDefault, | 234 | video: MVideoThumbnailAccountDefault |
235 | thumbnailModel: MThumbnail, | 235 | thumbnailModel: MThumbnail |
236 | previewModel: MThumbnail, | 236 | previewModel: MThumbnail |
237 | videoChannel: MChannelAccountDefault, | 237 | videoChannel: MChannelAccountDefault |
238 | tags: string[], | 238 | tags: string[] |
239 | videoImportAttributes: Partial<MVideoImport>, | 239 | videoImportAttributes: Partial<MVideoImport> |
240 | user: MUser | 240 | user: MUser |
241 | }): Bluebird<MVideoImportFormattable> { | 241 | }): Bluebird<MVideoImportFormattable> { |
242 | const { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes, user } = parameters | 242 | const { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes, user } = parameters |
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index 8d4ff07eb..eb46ea01f 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts | |||
@@ -135,7 +135,7 @@ videosRouter.get('/:id', | |||
135 | asyncMiddleware(getVideo) | 135 | asyncMiddleware(getVideo) |
136 | ) | 136 | ) |
137 | videosRouter.post('/:id/views', | 137 | videosRouter.post('/:id/views', |
138 | asyncMiddleware(videosGetValidator), | 138 | asyncMiddleware(videosCustomGetValidator('only-immutable-attributes')), |
139 | asyncMiddleware(viewVideo) | 139 | asyncMiddleware(viewVideo) |
140 | ) | 140 | ) |
141 | 141 | ||
@@ -307,7 +307,7 @@ async function addVideo (req: express.Request, res: express.Response) { | |||
307 | } | 307 | } |
308 | } | 308 | } |
309 | 309 | ||
310 | await JobQueue.Instance.createJob({ type: 'video-transcoding', payload: dataInput }) | 310 | await JobQueue.Instance.createJobWithPromise({ type: 'video-transcoding', payload: dataInput }) |
311 | } | 311 | } |
312 | 312 | ||
313 | Hooks.runAction('action:api.video.uploaded', { video: videoCreated }) | 313 | Hooks.runAction('action:api.video.uploaded', { video: videoCreated }) |
@@ -452,14 +452,13 @@ async function getVideo (req: express.Request, res: express.Response) { | |||
452 | 452 | ||
453 | if (video.isOutdated()) { | 453 | if (video.isOutdated()) { |
454 | JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'video', url: video.url } }) | 454 | JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'video', url: video.url } }) |
455 | .catch(err => logger.error('Cannot create AP refresher job for video %s.', video.url, { err })) | ||
456 | } | 455 | } |
457 | 456 | ||
458 | return res.json(video.toFormattedDetailsJSON()) | 457 | return res.json(video.toFormattedDetailsJSON()) |
459 | } | 458 | } |
460 | 459 | ||
461 | async function viewVideo (req: express.Request, res: express.Response) { | 460 | async function viewVideo (req: express.Request, res: express.Response) { |
462 | const videoInstance = res.locals.videoAll | 461 | const videoInstance = res.locals.onlyImmutableVideo |
463 | 462 | ||
464 | const ip = req.ip | 463 | const ip = req.ip |
465 | const exists = await Redis.Instance.doesVideoIPViewExist(ip, videoInstance.uuid) | 464 | const exists = await Redis.Instance.doesVideoIPViewExist(ip, videoInstance.uuid) |