diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts index 9cff51d45..37119e279 100644 --- a/server/middlewares/validators/users.ts +++ b/server/middlewares/validators/users.ts @@ -196,6 +196,7 @@ const deleteMeValidator = [ const usersUpdateValidator = [ param('id').isInt().not().isEmpty().withMessage('Should have a valid id'), + body('password').optional().custom(isUserPasswordValid).withMessage('Should have a valid password'), body('email').optional().isEmail().withMessage('Should have a valid email attribute'), body('emailVerified').optional().isBoolean().withMessage('Should have a valid email verified attribute'), diff --git a/support/doc/api/openapi.yaml b/support/doc/api/openapi.yaml index 4fbf5b055..7316b0b58 100644 --- a/support/doc/api/openapi.yaml +++ b/support/doc/api/openapi.yaml @@ -195,7 +195,7 @@ tags: description: | PeerTube instances can mirror videos from one another, and help distribute some videos. - For importing videos as your own, refer to [video imports](#tag/Video-Upload/paths/~1videos~1imports/post). + For importing videos as your own, refer to [video imports](#operation/importVideo). x-tagGroups: - name: Accounts tags: @@ -579,7 +579,9 @@ paths: application/json: schema: $ref: '#/components/schemas/AddUser' - description: User to create + description: | + If the smtp server is configured, you can leave the password empty and an email will be sent + asking the user to set it first. required: true get: summary: List users @@ -743,9 +745,11 @@ paths: properties: videoQuotaUsed: type: number + description: The user video quota used so far in bytes example: 16810141515 videoQuotaUsedDaily: type: number + description: The user video quota used today in bytes example: 1681014151 '/users/me/videos/{videoId}/rating': get: @@ -759,9 +763,9 @@ paths: - name: videoId in: path required: true - description: 'The video id ' + description: The video id schema: - type: string + $ref: '#/components/schemas/Video/properties/id' responses: '200': description: successful operation @@ -1075,7 +1079,7 @@ paths: type: object properties: avatarfile: - description: The file to upload. + description: The file to upload type: string format: binary encoding: @@ -1370,7 +1374,12 @@ paths: content: application/json: schema: + nullable: true type: string + minLength: 3 + maxLength: 10000 + example: | + **[Want to help to translate this video?](https://weblate.framasoft.org/projects/what-is-peertube-video/)**\r\n\r\n**Take back the control of your videos! [#JoinPeertube](https://joinpeertube.org)** '/videos/{id}/views': post: summary: Add a view to a video @@ -1757,7 +1766,7 @@ paths: schema: $ref: '#/components/schemas/VideoUploadResponse' '403': - description: Live is not enabled, allow replay is not enabled, or max instance/user live videos limit is exceeded + description: live is not enabled, allow replay is not enabled, or max instance/user live videos limit is exceeded requestBody: content: multipart/form-data: @@ -1862,11 +1871,11 @@ paths: $ref: '#/components/schemas/LiveVideoUpdate' responses: '204': - description: Successful operation + description: successful operation '400': - description: Bad parameters or trying to update a live that has already started + description: bad parameters or trying to update a live that has already started '403': - description: Trying to save replay of the live but saving replay is not enabled on the instance + description: trying to save replay of the live but saving replay is not enabled on the instance /users/me/abuses: get: @@ -2017,7 +2026,8 @@ paths: properties: id: description: Video id to report - type: number + allOf: + - $ref: '#/components/schemas/Video/properties/id' startAt: type: integer description: Timestamp in the video that marks the beginning of the report @@ -2031,13 +2041,14 @@ paths: properties: id: description: Comment id to report - type: number + allOf: + - $ref: '#/components/schemas/VideoComment/properties/id' account: type: object properties: id: description: Account id to report - type: number + type: integer required: - reason responses: @@ -2541,7 +2552,7 @@ paths: $ref: '#/components/schemas/VideoPlaylist' post: summary: Create a video playlist - description: 'If the video playlist is set as public, the videoChannelId is mandatory.' + description: If the video playlist is set as public, `videoChannelId` is mandatory. operationId: createPlaylist security: - OAuth2: [] @@ -2559,9 +2570,9 @@ paths: type: object properties: id: - type: integer + $ref: '#/components/schemas/VideoPlaylist/properties/id' uuid: - $ref: '#/components/schemas/UUIDv4' + $ref: '#/components/schemas/VideoPlaylist/properties/uuid' requestBody: content: multipart/form-data: @@ -2582,9 +2593,12 @@ paths: description: description: Video playlist description type: string + minLength: 3 + maxLength: 1000 videoChannelId: + allOf: + - $ref: '#/components/schemas/id' description: Video channel in which the playlist will be published - type: integer required: - displayName encoding: @@ -2638,8 +2652,9 @@ paths: description: Video playlist description type: string videoChannelId: + allOf: + - $ref: '#/components/schemas/id' description: Video channel in which the playlist will be published - type: integer encoding: thumbnailfile: contentType: image/jpeg @@ -2699,14 +2714,15 @@ paths: type: object properties: videoId: - type: integer - description: 'Video to add in the playlist' + allOf: + - $ref: '#/components/schemas/Video/properties/id' + description: Video to add in the playlist startTimestamp: type: integer - description: 'Start the video at this specific timestamp (in seconds)' + description: Start the video at this specific timestamp (in seconds) stopTimestamp: type: integer - description: 'Stop the video at this specific timestamp (in seconds)' + description: Stop the video at this specific timestamp (in seconds) required: - videoId @@ -2797,7 +2813,7 @@ paths: schema: type: array items: - type: integer + $ref: '#/components/schemas/Video/properties/id' responses: '200': description: successful operation @@ -2960,8 +2976,7 @@ paths: type: object properties: text: - type: string - description: 'Text comment' + $ref: '#/components/schemas/VideoComment/properties/text' required: - text @@ -3298,7 +3313,7 @@ paths: type: object properties: videoId: - type: integer + $ref: '#/components/schemas/Video/properties/id' required: - videoId responses: @@ -3982,9 +3997,7 @@ components: required: true description: The user id schema: - type: integer - minimum: 0 - example: 42 + $ref: '#/components/schemas/id' idOrUUID: name: id in: path @@ -3992,9 +4005,7 @@ components: description: The object id or uuid schema: oneOf: - - type: integer - minimum: 0 - example: 42 + - $ref: '#/components/schemas/id' - $ref: '#/components/schemas/UUIDv4' playlistElementId: name: playlistElementId @@ -4002,28 +4013,28 @@ components: required: true description: Playlist element id schema: - type: integer + $ref: '#/components/schemas/id' abuseId: name: abuseId in: path required: true description: Abuse id schema: - type: integer + $ref: '#/components/schemas/Abuse/properties/id' abuseMessageId: name: abuseMessageId in: path required: true description: Abuse message id schema: - type: integer + $ref: '#/components/schemas/AbuseMessage/properties/id' captionLanguage: name: captionLanguage in: path required: true description: The caption language schema: - type: string + $ref: '#/components/schemas/VideoLanguageSet' channelHandle: name: channelHandle in: path @@ -4046,14 +4057,14 @@ components: required: true description: The thread id (root comment id) schema: - type: integer + $ref: '#/components/schemas/VideoCommentThreadTree/properties/comment/properties/id' commentId: name: commentId in: path required: true description: The comment id schema: - type: integer + $ref: '#/components/schemas/VideoComment/properties/id' isLive: name: isLive in: query @@ -4068,10 +4079,10 @@ components: description: category id of the video (see [/videos/categories](#operation/getCategories)) schema: oneOf: - - type: integer + - $ref: '#/components/schemas/VideoCategorySet' - type: array items: - type: integer + $ref: '#/components/schemas/VideoCategorySet' style: form explode: false tagsOneOf: @@ -4108,10 +4119,10 @@ components: description: language id of the video (see [/videos/languages](#operation/getLanguages)). Use `_unknown` to filter on videos that don't have a video language schema: oneOf: - - type: string + - $ref: '#/components/schemas/VideoLanguageSet' - type: array items: - type: string + $ref: '#/components/schemas/VideoLanguageSet' style: form explode: false licenceOneOf: @@ -4121,10 +4132,10 @@ components: description: licence id of the video (see [/videos/licences](#operation/getLicences)) schema: oneOf: - - type: integer + - $ref: '#/components/schemas/VideoLicenceSet' - type: array items: - type: integer + $ref: '#/components/schemas/VideoLicenceSet' style: form explode: false skipCount: @@ -4221,45 +4232,72 @@ components: moderator: Moderator scope user: User scope schemas: + # Resuable core properties + id: + type: integer + minimum: 1 + example: 42 UUIDv4: type: string format: uuid example: 9c9de5e8-0a1e-484a-b099-e80766180a6d pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' - # the regex above limits the length; - # however, some tools might require explicit settings: minLength: 36 maxLength: 36 + username: + type: string + description: The username of the user + example: chocobozzz + pattern: '/^[a-z0-9._]{1,50}$/' + minLength: 1 + maxLength: 50 + usernameChannel: + type: string + description: The username for the default channel + example: The Capybara Channel + pattern: '/^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\\-_.:]+$/' + password: + type: string + format: password + description: The password of the user + minLength: 6 + maxLength: 255 VideoCategorySet: type: integer description: category id of the video (see [/videos/categories](#operation/getCategories)) + example: 15 VideoConstantNumber-Category: properties: id: $ref: '#/components/schemas/VideoCategorySet' label: type: string + example: Science & Technology VideoLicenceSet: type: integer description: licence id of the video (see [/videos/licences](#operation/getLicences)) + example: 2 VideoConstantNumber-Licence: properties: id: $ref: '#/components/schemas/VideoLicenceSet' label: type: string - + example: Attribution - Share Alike + VideoLanguageSet: type: string description: language id of the video (see [/videos/languages](#operation/getLanguages)) + example: en VideoConstantString-Language: properties: id: $ref: '#/components/schemas/VideoLanguageSet' label: type: string + example: English VideoPlaylistPrivacySet: type: integer @@ -4411,7 +4449,7 @@ components: VideoChannelSummary: properties: id: - type: integer + $ref: '#/components/schemas/id' name: type: string displayName: @@ -4473,7 +4511,7 @@ components: - type: object properties: id: - type: integer + $ref: '#/components/schemas/id' type: type: integer enum: @@ -4509,20 +4547,21 @@ components: VideoInfo: properties: id: - type: integer + $ref: '#/components/schemas/Video/properties/id' uuid: - $ref: '#/components/schemas/UUIDv4' + $ref: '#/components/schemas/Video/properties/uuid' name: - type: string - minLength: 3 - maxLength: 120 + $ref: '#/components/schemas/Video/properties/name' Video: properties: id: - type: integer - example: 8 + description: object id for the video + allOf: + - $ref: '#/components/schemas/id' uuid: - $ref: '#/components/schemas/UUIDv4' + description: universal identifier for the video, that can be used across instances + allOf: + - $ref: '#/components/schemas/UUIDv4' isLive: type: boolean createdAt: @@ -4546,13 +4585,21 @@ components: example: 2010-10-01T10:52:46.396Z description: used to represent a date of first publication, prior to the practical publication date of `publishedAt` category: - $ref: '#/components/schemas/VideoConstantNumber-Category' + allOf: + - $ref: '#/components/schemas/VideoConstantNumber-Category' + description: category in which the video is classified licence: - $ref: '#/components/schemas/VideoConstantNumber-Licence' + allOf: + - $ref: '#/components/schemas/VideoConstantNumber-Licence' + description: licence under which the video is distributed language: - $ref: '#/components/schemas/VideoConstantString-Language' + allOf: + - $ref: '#/components/schemas/VideoConstantString-Language' + description: main language used in the video privacy: - $ref: '#/components/schemas/VideoPrivacyConstant' + allOf: + - $ref: '#/components/schemas/VideoPrivacyConstant' + description: privacy policy used to distribute the video description: type: string example: | @@ -4571,6 +4618,7 @@ components: type: boolean name: type: string + description: title of the video example: What is PeerTube? minLength: 3 maxLength: 120 @@ -4598,7 +4646,9 @@ components: type: boolean nullable: true state: - $ref: '#/components/schemas/VideoStateConstant' + allOf: + - $ref: '#/components/schemas/VideoStateConstant' + description: represents the internal state of the video processing within the PeerTube instance scheduledUpdate: nullable: true allOf: @@ -4677,7 +4727,7 @@ components: FileRedundancyInformation: properties: id: - type: integer + $ref: '#/components/schemas/id' fileUrl: type: string format: url @@ -4702,7 +4752,7 @@ components: VideoRedundancy: properties: id: - type: integer + $ref: '#/components/schemas/id' name: type: string url: @@ -4736,8 +4786,7 @@ components: VideoImport: properties: id: - type: integer - example: 2 + $ref: '#/components/schemas/id' targetUrl: type: string format: url @@ -4773,8 +4822,7 @@ components: Abuse: properties: id: - type: integer - example: 7 + $ref: '#/components/schemas/id' reason: type: string example: The video is a spam @@ -4799,7 +4847,7 @@ components: AbuseMessage: properties: id: - type: integer + $ref: '#/components/schemas/id' message: type: string minLength: 2 @@ -4814,9 +4862,9 @@ components: VideoBlacklist: properties: id: - type: integer + $ref: '#/components/schemas/id' videoId: - type: integer + $ref: '#/components/schemas/Video/properties/id' createdAt: type: string format: date-time @@ -4843,29 +4891,12 @@ components: type: integer nsfw: type: boolean - VideoChannel: - properties: - displayName: - type: string - minLength: 1 - maxLength: 120 - description: - type: string - minLength: 3 - maxLength: 1000 - isLocal: - type: boolean - ownerAccount: - type: object - properties: - id: - type: integer - uuid: - $ref: '#/components/schemas/UUIDv4' VideoPlaylist: properties: id: - type: integer + $ref: '#/components/schemas/id' + uuid: + $ref: '#/components/schemas/UUIDv4' createdAt: type: string format: date-time @@ -4876,8 +4907,6 @@ components: type: string minLength: 3 maxLength: 1000 - uuid: - $ref: '#/components/schemas/UUIDv4' displayName: type: string minLength: 1 @@ -4886,6 +4915,7 @@ components: type: boolean videoLength: type: integer + minimum: 0 thumbnailPath: type: string privacy: @@ -4899,20 +4929,21 @@ components: VideoComment: properties: id: - type: integer + $ref: '#/components/schemas/id' url: type: string format: url text: type: string + description: Text of the comment in Markdown minLength: 1 maxLength: 10000 threadId: type: integer inReplyToCommentId: - type: integer + $ref: '#/components/schemas/id' videoId: - type: integer + $ref: '#/components/schemas/Video/properties/id' createdAt: type: string format: date-time @@ -4921,8 +4952,10 @@ components: format: date-time totalRepliesFromVideoAuthor: type: integer + minimum: 0 totalReplies: type: integer + minimum: 0 account: $ref: '#/components/schemas/Account' VideoCommentThreadTree: @@ -4952,8 +4985,7 @@ components: ActorInfo: properties: id: - type: integer - example: 11 + $ref: '#/components/schemas/id' name: type: string displayName: @@ -4970,8 +5002,7 @@ components: Actor: properties: id: - type: integer - example: 11 + $ref: '#/components/schemas/id' url: type: string format: url @@ -4999,8 +5030,7 @@ components: - $ref: '#/components/schemas/Actor' - properties: userId: - type: string - example: 2 + $ref: '#/components/schemas/id' displayName: type: string description: @@ -5181,8 +5211,10 @@ components: properties: videoQuota: type: integer + example: 16810141515 videoQuotaDaily: type: integer + example: 1681014151 trending: type: object properties: @@ -5301,8 +5333,10 @@ components: properties: videoQuota: type: integer + example: 16810141515 videoQuotaDaily: type: integer + example: 1681014151 transcoding: type: object description: Settings pertaining to transcoding jobs @@ -5399,7 +5433,7 @@ components: Follow: properties: id: - type: integer + $ref: '#/components/schemas/id' follower: $ref: '#/components/schemas/Actor' following: @@ -5438,9 +5472,7 @@ components: Job: properties: id: - type: integer - minimum: 0 - example: 42 + $ref: '#/components/schemas/id' state: type: string enum: @@ -5484,22 +5516,25 @@ components: type: object properties: id: - type: integer - example: 8 + $ref: '#/components/schemas/id' account: type: object properties: id: - type: integer - example: 37 + $ref: '#/components/schemas/id' VideoUploadRequestCommon: properties: name: description: Video name type: string + example: What is PeerTube? + minLength: 3 + maxLength: 120 channelId: description: Channel id that will contain this video type: integer + example: 3 + minimum: 1 privacy: $ref: '#/components/schemas/VideoPrivacySet' category: @@ -5511,6 +5546,8 @@ components: description: description: Video description type: string + example: | + **[Want to help to translate this video?](https://weblate.framasoft.org/projects/what-is-peertube-video/)**\r\n\r\n**Take back the control of your videos! [#JoinPeertube](https://joinpeertube.org)** waitTranscoding: description: Whether or not we wait transcoding before publish the video type: boolean @@ -5527,6 +5564,9 @@ components: minItems: 1 maxItems: 5 uniqueItems: true + example: + - framasoft + - peertube items: type: string minLength: 2 @@ -5576,6 +5616,7 @@ components: description: Video filename including extension type: string format: filename + example: what_is_peertube.mp4 thumbnailfile: description: Video thumbnail file type: string @@ -5590,10 +5631,9 @@ components: type: object properties: id: - type: integer - example: 8 + $ref: '#/components/schemas/Video/properties/id' uuid: - $ref: '#/components/schemas/UUIDv4' + $ref: '#/components/schemas/Video/properties/uuid' CommentThreadResponse: properties: total: @@ -5671,10 +5711,7 @@ components: type: string description: Theme enabled by this user username: - type: string - description: The user username - minLength: 1 - maxLength: 50 + $ref: '#/components/schemas/username' videoChannels: type: array items: @@ -5713,31 +5750,23 @@ components: AddUser: properties: username: - type: string - description: The user username - minLength: 1 - maxLength: 50 - pattern: '/^[a-z0-9._]{1,50}$/' + $ref: '#/components/schemas/username' password: - type: string - format: password - description: The user password. If the smtp server is configured, you can leave empty and an email will be sent - minLength: 6 - maxLength: 255 + $ref: '#/components/schemas/password' email: type: string format: email description: The user email videoQuota: type: integer - description: The user video quota + description: The user video quota in bytes + example: -1 videoQuotaDaily: type: integer - description: The user daily video quota + description: The user daily video quota in bytes + example: -1 channelName: - type: string - description: The user default channel username - pattern: '/^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\\-_.:]+$/' + $ref: '#/components/schemas/usernameChannel' role: $ref: '#/components/schemas/UserRole' adminFlags: @@ -5751,9 +5780,6 @@ components: - role UpdateUser: properties: - id: - type: string - description: The user id email: type: string format: email @@ -5763,10 +5789,10 @@ components: description: Set the email as verified videoQuota: type: integer - description: The updated video quota of the user + description: The updated video quota of the user in bytes videoQuotaDaily: type: integer - description: The updated daily video quota of the user + description: The updated daily video quota of the user in bytes pluginAuth: type: string nullable: true @@ -5776,16 +5802,10 @@ components: $ref: '#/components/schemas/UserRole' adminFlags: $ref: '#/components/schemas/UserAdminFlags' - required: - - id UpdateMe: properties: password: - type: string - format: password - description: Your new password - minLength: 6 - maxLength: 255 + $ref: '#/components/schemas/password' email: type: string format: email @@ -5808,8 +5828,7 @@ components: GetMeVideoRating: properties: id: - type: string - description: Id of the video + $ref: '#/components/schemas/id' rating: type: string enum: @@ -5837,17 +5856,9 @@ components: RegisterUser: properties: username: - type: string - description: The username of the user - minLength: 1 - maxLength: 50 - pattern: '/^[a-z0-9._]{1,50}$/' + $ref: '#/components/schemas/username' password: - type: string - format: password - description: The password of the user - minLength: 6 - maxLength: 255 + $ref: '#/components/schemas/password' email: type: string format: email @@ -5861,9 +5872,7 @@ components: type: object properties: name: - type: string - description: The username for the default channel - pattern: '/^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\\-_.:]+$/' + $ref: '#/components/schemas/usernameChannel' displayName: type: string description: The display name for the default channel @@ -5874,40 +5883,64 @@ components: - password - email - VideoChannelCommon: + VideoChannel: properties: + # GET/POST/PUT properties displayName: type: string + example: Videos of Framasoft minLength: 1 maxLength: 120 description: type: string + example: Videos made with <3 by Framasoft minLength: 3 maxLength: 1000 support: type: string - description: 'A text shown by default on all videos of this channel, to tell the audience how to support it' + description: text shown by default on all videos of this channel, to tell the audience how to support it example: Please support my work on ! <3 minLength: 3 maxLength: 1000 + # GET-only properties + id: + readOnly: true + allOf: + - $ref: '#/components/schemas/id' + isLocal: + readOnly: true + type: boolean + updatedAt: + readOnly: true + type: string + format: date-time + ownerAccount: + readOnly: true + nullable: true + type: object + properties: + id: + type: integer + uuid: + $ref: '#/components/schemas/UUIDv4' VideoChannelCreate: allOf: - - $ref: '#/components/schemas/VideoChannelCommon' + - $ref: '#/components/schemas/VideoChannel' - properties: name: - type: string - minLength: 1 - maxLength: 120 + description: username of the channel to create + allOf: + - $ref: '#/components/schemas/usernameChannel' required: - name - displayName VideoChannelUpdate: allOf: - - $ref: '#/components/schemas/VideoChannelCommon' + - $ref: '#/components/schemas/VideoChannel' - properties: bulkVideosSupportUpdate: type: boolean - description: 'Update the support field for all videos of this channel' + description: Update the support field for all videos of this channel VideoChannelList: properties: total: @@ -6123,7 +6156,7 @@ components: Notification: properties: id: - type: integer + $ref: '#/components/schemas/id' type: type: integer description: > @@ -6171,7 +6204,7 @@ components: type: object properties: id: - type: integer + $ref: '#/components/schemas/id' video: nullable: true $ref: '#/components/schemas/VideoInfo' @@ -6191,7 +6224,7 @@ components: type: object properties: id: - type: integer + $ref: '#/components/schemas/id' threadId: type: integer video: @@ -6203,7 +6236,7 @@ components: type: object properties: id: - type: integer + $ref: '#/components/schemas/id' video: allOf: - $ref: '#/components/schemas/VideoInfo' @@ -6212,7 +6245,7 @@ components: type: object properties: id: - type: integer + $ref: '#/components/schemas/id' video: allOf: - $ref: '#/components/schemas/VideoInfo' @@ -6225,7 +6258,7 @@ components: nullable: true properties: id: - type: integer + $ref: '#/components/schemas/id' follower: $ref: '#/components/schemas/ActorInfo' state: