diff options
-rw-r--r-- | server/controllers/api/videos/index.ts | 23 | ||||
-rw-r--r-- | server/controllers/api/videos/watching.ts | 9 | ||||
-rw-r--r-- | server/middlewares/validators/videos/video-live.ts | 10 | ||||
-rw-r--r-- | server/middlewares/validators/videos/videos.ts | 9 | ||||
-rw-r--r-- | shared/models/server/server-error-code.enum.ts | 15 | ||||
-rw-r--r-- | support/doc/api/openapi.yaml | 43 |
6 files changed, 88 insertions, 21 deletions
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index 703051ee2..8c6c44144 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts | |||
@@ -60,12 +60,25 @@ videosRouter.use('/', liveRouter) | |||
60 | videosRouter.use('/', uploadRouter) | 60 | videosRouter.use('/', uploadRouter) |
61 | videosRouter.use('/', updateRouter) | 61 | videosRouter.use('/', updateRouter) |
62 | 62 | ||
63 | videosRouter.get('/categories', listVideoCategories) | 63 | videosRouter.get('/categories', |
64 | videosRouter.get('/licences', listVideoLicences) | 64 | openapiOperationDoc({ operationId: 'getCategories' }), |
65 | videosRouter.get('/languages', listVideoLanguages) | 65 | listVideoCategories |
66 | videosRouter.get('/privacies', listVideoPrivacies) | 66 | ) |
67 | videosRouter.get('/licences', | ||
68 | openapiOperationDoc({ operationId: 'getLicences' }), | ||
69 | listVideoLicences | ||
70 | ) | ||
71 | videosRouter.get('/languages', | ||
72 | openapiOperationDoc({ operationId: 'getLanguages' }), | ||
73 | listVideoLanguages | ||
74 | ) | ||
75 | videosRouter.get('/privacies', | ||
76 | openapiOperationDoc({ operationId: 'getPrivacies' }), | ||
77 | listVideoPrivacies | ||
78 | ) | ||
67 | 79 | ||
68 | videosRouter.get('/', | 80 | videosRouter.get('/', |
81 | openapiOperationDoc({ operationId: 'getVideos' }), | ||
69 | paginationValidator, | 82 | paginationValidator, |
70 | videosSortValidator, | 83 | videosSortValidator, |
71 | setDefaultVideosSort, | 84 | setDefaultVideosSort, |
@@ -76,6 +89,7 @@ videosRouter.get('/', | |||
76 | ) | 89 | ) |
77 | 90 | ||
78 | videosRouter.get('/:id/description', | 91 | videosRouter.get('/:id/description', |
92 | openapiOperationDoc({ operationId: 'getVideoDesc' }), | ||
79 | asyncMiddleware(videosGetValidator), | 93 | asyncMiddleware(videosGetValidator), |
80 | asyncMiddleware(getVideoDescription) | 94 | asyncMiddleware(getVideoDescription) |
81 | ) | 95 | ) |
@@ -91,6 +105,7 @@ videosRouter.get('/:id', | |||
91 | asyncMiddleware(getVideo) | 105 | asyncMiddleware(getVideo) |
92 | ) | 106 | ) |
93 | videosRouter.post('/:id/views', | 107 | videosRouter.post('/:id/views', |
108 | openapiOperationDoc({ operationId: 'addView' }), | ||
94 | asyncMiddleware(videosCustomGetValidator('only-immutable-attributes')), | 109 | asyncMiddleware(videosCustomGetValidator('only-immutable-attributes')), |
95 | asyncMiddleware(viewVideo) | 110 | asyncMiddleware(viewVideo) |
96 | ) | 111 | ) |
diff --git a/server/controllers/api/videos/watching.ts b/server/controllers/api/videos/watching.ts index 08190e583..8b15525aa 100644 --- a/server/controllers/api/videos/watching.ts +++ b/server/controllers/api/videos/watching.ts | |||
@@ -1,12 +1,19 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { UserWatchingVideo } from '../../../../shared' | 2 | import { UserWatchingVideo } from '../../../../shared' |
3 | import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoWatchingValidator } from '../../../middlewares' | 3 | import { |
4 | asyncMiddleware, | ||
5 | asyncRetryTransactionMiddleware, | ||
6 | authenticate, | ||
7 | openapiOperationDoc, | ||
8 | videoWatchingValidator | ||
9 | } from '../../../middlewares' | ||
4 | import { UserVideoHistoryModel } from '../../../models/user/user-video-history' | 10 | import { UserVideoHistoryModel } from '../../../models/user/user-video-history' |
5 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | 11 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' |
6 | 12 | ||
7 | const watchingRouter = express.Router() | 13 | const watchingRouter = express.Router() |
8 | 14 | ||
9 | watchingRouter.put('/:videoId/watching', | 15 | watchingRouter.put('/:videoId/watching', |
16 | openapiOperationDoc({ operationId: 'setProgress' }), | ||
10 | authenticate, | 17 | authenticate, |
11 | asyncMiddleware(videoWatchingValidator), | 18 | asyncMiddleware(videoWatchingValidator), |
12 | asyncRetryTransactionMiddleware(userWatchVideo) | 19 | asyncRetryTransactionMiddleware(userWatchVideo) |
diff --git a/server/middlewares/validators/videos/video-live.ts b/server/middlewares/validators/videos/video-live.ts index ffc8c47b3..b058ff5c1 100644 --- a/server/middlewares/validators/videos/video-live.ts +++ b/server/middlewares/validators/videos/video-live.ts | |||
@@ -72,7 +72,8 @@ const videoLiveAddValidator = getCommonVideoEditAttributes().concat([ | |||
72 | 72 | ||
73 | return res.fail({ | 73 | return res.fail({ |
74 | status: HttpStatusCode.FORBIDDEN_403, | 74 | status: HttpStatusCode.FORBIDDEN_403, |
75 | message: 'Live is not enabled on this instance' | 75 | message: 'Live is not enabled on this instance', |
76 | type: ServerErrorCode.LIVE_NOT_ENABLED | ||
76 | }) | 77 | }) |
77 | } | 78 | } |
78 | 79 | ||
@@ -81,7 +82,8 @@ const videoLiveAddValidator = getCommonVideoEditAttributes().concat([ | |||
81 | 82 | ||
82 | return res.fail({ | 83 | return res.fail({ |
83 | status: HttpStatusCode.FORBIDDEN_403, | 84 | status: HttpStatusCode.FORBIDDEN_403, |
84 | message: 'Saving live replay is not allowed instance' | 85 | message: 'Saving live replay is not enabled on this instance', |
86 | type: ServerErrorCode.LIVE_NOT_ALLOWING_REPLAY | ||
85 | }) | 87 | }) |
86 | } | 88 | } |
87 | 89 | ||
@@ -116,8 +118,8 @@ const videoLiveAddValidator = getCommonVideoEditAttributes().concat([ | |||
116 | 118 | ||
117 | return res.fail({ | 119 | return res.fail({ |
118 | status: HttpStatusCode.FORBIDDEN_403, | 120 | status: HttpStatusCode.FORBIDDEN_403, |
119 | type: ServerErrorCode.MAX_USER_LIVES_LIMIT_REACHED, | 121 | message: 'Cannot create this live because the max user lives limit is reached.', |
120 | message: 'Cannot create this live because the max user lives limit is reached.' | 122 | type: ServerErrorCode.MAX_USER_LIVES_LIMIT_REACHED |
121 | }) | 123 | }) |
122 | } | 124 | } |
123 | } | 125 | } |
diff --git a/server/middlewares/validators/videos/videos.ts b/server/middlewares/validators/videos/videos.ts index 52e6c5762..7f278c9f6 100644 --- a/server/middlewares/validators/videos/videos.ts +++ b/server/middlewares/validators/videos/videos.ts | |||
@@ -402,7 +402,8 @@ const videosAcceptChangeOwnershipValidator = [ | |||
402 | if (isAble === false) { | 402 | if (isAble === false) { |
403 | res.fail({ | 403 | res.fail({ |
404 | status: HttpStatusCode.PAYLOAD_TOO_LARGE_413, | 404 | status: HttpStatusCode.PAYLOAD_TOO_LARGE_413, |
405 | message: 'The user video quota is exceeded with this video.' | 405 | message: 'The user video quota is exceeded with this video.', |
406 | type: ServerErrorCode.QUOTA_REACHED | ||
406 | }) | 407 | }) |
407 | return | 408 | return |
408 | } | 409 | } |
@@ -628,7 +629,8 @@ async function commonVideoChecksPass (parameters: { | |||
628 | if (!isVideoFileSizeValid(videoFileSize.toString())) { | 629 | if (!isVideoFileSizeValid(videoFileSize.toString())) { |
629 | res.fail({ | 630 | res.fail({ |
630 | status: HttpStatusCode.PAYLOAD_TOO_LARGE_413, | 631 | status: HttpStatusCode.PAYLOAD_TOO_LARGE_413, |
631 | message: 'This file is too large. It exceeds the maximum file size authorized.' | 632 | message: 'This file is too large. It exceeds the maximum file size authorized.', |
633 | type: ServerErrorCode.MAX_FILE_SIZE_REACHED | ||
632 | }) | 634 | }) |
633 | return false | 635 | return false |
634 | } | 636 | } |
@@ -636,7 +638,8 @@ async function commonVideoChecksPass (parameters: { | |||
636 | if (await isAbleToUploadVideo(user.id, videoFileSize) === false) { | 638 | if (await isAbleToUploadVideo(user.id, videoFileSize) === false) { |
637 | res.fail({ | 639 | res.fail({ |
638 | status: HttpStatusCode.PAYLOAD_TOO_LARGE_413, | 640 | status: HttpStatusCode.PAYLOAD_TOO_LARGE_413, |
639 | message: 'The user video quota is exceeded with this video.' | 641 | message: 'The user video quota is exceeded with this video.', |
642 | type: ServerErrorCode.QUOTA_REACHED | ||
640 | }) | 643 | }) |
641 | return false | 644 | return false |
642 | } | 645 | } |
diff --git a/shared/models/server/server-error-code.enum.ts b/shared/models/server/server-error-code.enum.ts index 2795fa569..115421d4d 100644 --- a/shared/models/server/server-error-code.enum.ts +++ b/shared/models/server/server-error-code.enum.ts | |||
@@ -1,18 +1,31 @@ | |||
1 | export const enum ServerErrorCode { | 1 | export const enum ServerErrorCode { |
2 | /** | 2 | /** |
3 | * The simplest form of payload too large: when the file size is over the | ||
4 | * global file size limit | ||
5 | */ | ||
6 | MAX_FILE_SIZE_REACHED = 'max_file_size_reached', | ||
7 | |||
8 | /** | ||
9 | * The payload is too large for the user quota set | ||
10 | */ | ||
11 | QUOTA_REACHED = 'quota_reached', | ||
12 | |||
13 | /** | ||
3 | * Error yielded upon trying to access a video that is not federated, nor can | 14 | * Error yielded upon trying to access a video that is not federated, nor can |
4 | * be. This may be due to: remote videos on instances that are not followed by | 15 | * be. This may be due to: remote videos on instances that are not followed by |
5 | * yours, and with your instance disallowing unknown instances being accessed. | 16 | * yours, and with your instance disallowing unknown instances being accessed. |
6 | */ | 17 | */ |
7 | DOES_NOT_RESPECT_FOLLOW_CONSTRAINTS = 'does_not_respect_follow_constraints', | 18 | DOES_NOT_RESPECT_FOLLOW_CONSTRAINTS = 'does_not_respect_follow_constraints', |
8 | 19 | ||
20 | LIVE_NOT_ENABLED = 'live_not_enabled', | ||
21 | LIVE_NOT_ALLOWING_REPLAY = 'live_not_allowing_replay', | ||
22 | LIVE_CONFLICTING_PERMANENT_AND_SAVE_REPLAY = 'live_conflicting_permanent_and_save_replay', | ||
9 | /** | 23 | /** |
10 | * Pretty self-explanatory: the set maximum number of simultaneous lives was | 24 | * Pretty self-explanatory: the set maximum number of simultaneous lives was |
11 | * reached, and this error is typically there to inform the user trying to | 25 | * reached, and this error is typically there to inform the user trying to |
12 | * broadcast one. | 26 | * broadcast one. |
13 | */ | 27 | */ |
14 | MAX_INSTANCE_LIVES_LIMIT_REACHED = 'max_instance_lives_limit_reached', | 28 | MAX_INSTANCE_LIVES_LIMIT_REACHED = 'max_instance_lives_limit_reached', |
15 | |||
16 | /** | 29 | /** |
17 | * Pretty self-explanatory: the set maximum number of simultaneous lives FOR | 30 | * Pretty self-explanatory: the set maximum number of simultaneous lives FOR |
18 | * THIS USER was reached, and this error is typically there to inform the user | 31 | * THIS USER was reached, and this error is typically there to inform the user |
diff --git a/support/doc/api/openapi.yaml b/support/doc/api/openapi.yaml index 6c5a15087..b43b6bfa0 100644 --- a/support/doc/api/openapi.yaml +++ b/support/doc/api/openapi.yaml | |||
@@ -1802,6 +1802,7 @@ paths: | |||
1802 | '/videos/{id}/views': | 1802 | '/videos/{id}/views': |
1803 | post: | 1803 | post: |
1804 | summary: Add a view to a video | 1804 | summary: Add a view to a video |
1805 | operationId: addView | ||
1805 | tags: | 1806 | tags: |
1806 | - Video | 1807 | - Video |
1807 | parameters: | 1808 | parameters: |
@@ -1813,6 +1814,7 @@ paths: | |||
1813 | '/videos/{id}/watching': | 1814 | '/videos/{id}/watching': |
1814 | put: | 1815 | put: |
1815 | summary: Set watching progress of a video | 1816 | summary: Set watching progress of a video |
1817 | operationId: setProgress | ||
1816 | tags: | 1818 | tags: |
1817 | - Video | 1819 | - Video |
1818 | security: | 1820 | security: |
@@ -1851,7 +1853,10 @@ paths: | |||
1851 | '408': | 1853 | '408': |
1852 | description: upload has timed out | 1854 | description: upload has timed out |
1853 | '413': | 1855 | '413': |
1854 | description: video file too large, due to quota or max body size limit set by the reverse-proxy | 1856 | x-summary: video file too large, due to quota or max body size limit set by the reverse-proxy |
1857 | description: | | ||
1858 | If the response has no body, it means the reverse-proxy didn't let it through. Otherwise disambiguate via `type`: | ||
1859 | - `quota_reached` for quota limits wether daily or global | ||
1855 | headers: | 1860 | headers: |
1856 | X-File-Maximum-Size: | 1861 | X-File-Maximum-Size: |
1857 | schema: | 1862 | schema: |
@@ -1951,7 +1956,11 @@ paths: | |||
1951 | type: number | 1956 | type: number |
1952 | example: 0 | 1957 | example: 0 |
1953 | '413': | 1958 | '413': |
1954 | description: video file too large, due to quota, absolute max file size or concurrent partial upload limit | 1959 | x-summary: video file too large, due to quota, absolute max file size or concurrent partial upload limit |
1960 | description: | | ||
1961 | Disambiguate via `type`: | ||
1962 | - `max_file_size_reached` for the absolute file size limit | ||
1963 | - `quota_reached` for quota limits whether daily or global | ||
1955 | '415': | 1964 | '415': |
1956 | description: video type unsupported | 1965 | description: video type unsupported |
1957 | put: | 1966 | put: |
@@ -2027,10 +2036,14 @@ paths: | |||
2027 | example: 0 | 2036 | example: 0 |
2028 | '403': | 2037 | '403': |
2029 | description: video didn't pass upload filter | 2038 | description: video didn't pass upload filter |
2030 | '413': | 2039 | '404': |
2031 | description: video file too large, due to quota or max body size limit set by the reverse-proxy | 2040 | description: upload not found |
2041 | '409': | ||
2042 | description: chunk doesn't match range | ||
2032 | '422': | 2043 | '422': |
2033 | description: video unreadable | 2044 | description: video unreadable |
2045 | '429': | ||
2046 | description: too many concurrent requests | ||
2034 | delete: | 2047 | delete: |
2035 | summary: Cancel the resumable upload of a video, deleting any data uploaded so far | 2048 | summary: Cancel the resumable upload of a video, deleting any data uploaded so far |
2036 | description: Uses [a resumable protocol](https://github.com/kukhariev/node-uploadx/blob/master/proto.md) to cancel the upload of a video | 2049 | description: Uses [a resumable protocol](https://github.com/kukhariev/node-uploadx/blob/master/proto.md) to cancel the upload of a video |
@@ -2063,6 +2076,8 @@ paths: | |||
2063 | schema: | 2076 | schema: |
2064 | type: number | 2077 | type: number |
2065 | example: 0 | 2078 | example: 0 |
2079 | '404': | ||
2080 | description: upload not found | ||
2066 | 2081 | ||
2067 | /videos/imports: | 2082 | /videos/imports: |
2068 | post: | 2083 | post: |
@@ -2116,8 +2131,20 @@ paths: | |||
2116 | application/json: | 2131 | application/json: |
2117 | schema: | 2132 | schema: |
2118 | $ref: '#/components/schemas/VideoUploadResponse' | 2133 | $ref: '#/components/schemas/VideoUploadResponse' |
2134 | '400': | ||
2135 | x-summary: validation error, or conflicting `saveReplay` and `permanentLive` parameter set | ||
2136 | description: | | ||
2137 | Disambiguate via `type`: | ||
2138 | - default type for a validation error | ||
2139 | - `live_conflicting_permanent_and_save_replay` for conflicting parameters set | ||
2119 | '403': | 2140 | '403': |
2120 | description: live is not enabled, allow replay is not enabled, or max instance/user live videos limit is exceeded | 2141 | x-summary: live is not enabled, allow replay is not enabled, or max instance/user live videos limit is exceeded |
2142 | description: | | ||
2143 | Disambiguate via `type`: | ||
2144 | - `live_not_enabled` for a disabled live feature | ||
2145 | - `live_not_allowing_replay` for a disabled replay feature | ||
2146 | - `max_instance_lives_limit_reached` for the absolute concurrent live limit | ||
2147 | - `max_user_lives_limit_reached` for the user concurrent live limit | ||
2121 | requestBody: | 2148 | requestBody: |
2122 | content: | 2149 | content: |
2123 | multipart/form-data: | 2150 | multipart/form-data: |
@@ -2318,7 +2345,7 @@ paths: | |||
2318 | type: string | 2345 | type: string |
2319 | - name: videoIs | 2346 | - name: videoIs |
2320 | in: query | 2347 | in: query |
2321 | description: only list blacklisted or deleted videos | 2348 | description: only list deleted or blocklisted videos |
2322 | schema: | 2349 | schema: |
2323 | type: string | 2350 | type: string |
2324 | enum: | 2351 | enum: |
@@ -4396,7 +4423,7 @@ components: | |||
4396 | name: sort | 4423 | name: sort |
4397 | in: query | 4424 | in: query |
4398 | required: false | 4425 | required: false |
4399 | description: Sort blacklists by criteria | 4426 | description: Sort blocklists by criteria |
4400 | schema: | 4427 | schema: |
4401 | type: string | 4428 | type: string |
4402 | enum: | 4429 | enum: |
@@ -4859,7 +4886,7 @@ components: | |||
4859 | enum: | 4886 | enum: |
4860 | - 0 | 4887 | - 0 |
4861 | - 1 | 4888 | - 1 |
4862 | description: 'Admin flags for the user (None = `0`, Bypass video blacklist = `1`)' | 4889 | description: 'Admin flags for the user (None = `0`, Bypass video blocklist = `1`)' |
4863 | example: 1 | 4890 | example: 1 |
4864 | 4891 | ||
4865 | VideoStateConstant: | 4892 | VideoStateConstant: |