aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/middlewares/validators/videos/video-ownership-changes.ts
blob: 95e4cebced7506266f52b72205a7e70cf2bbff13 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import express from 'express'
import { param } from 'express-validator'
import { isIdValid } from '@server/helpers/custom-validators/misc'
import { checkUserCanTerminateOwnershipChange } from '@server/helpers/custom-validators/video-ownership'
import { logger } from '@server/helpers/logger'
import { isAbleToUploadVideo } from '@server/lib/user'
import { AccountModel } from '@server/models/account/account'
import { MVideoWithAllFiles } from '@server/types/models'
import {
  HttpStatusCode,
  ServerErrorCode,
  UserRight,
  VideoChangeOwnershipAccept,
  VideoChangeOwnershipStatus,
  VideoState
} from '@shared/models'
import {
  areValidationErrors,
  checkUserCanManageVideo,
  doesChangeVideoOwnershipExist,
  doesVideoChannelOfAccountExist,
  doesVideoExist,
  isValidVideoIdParam
} from '../shared'

const videosChangeOwnershipValidator = [
  isValidVideoIdParam('videoId'),

  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
    logger.debug('Checking changeOwnership parameters', { parameters: req.params })

    if (areValidationErrors(req, res)) return
    if (!await doesVideoExist(req.params.videoId, res)) return

    // Check if the user who did the request is able to change the ownership of the video
    if (!checkUserCanManageVideo(res.locals.oauth.token.User, res.locals.videoAll, UserRight.CHANGE_VIDEO_OWNERSHIP, res)) return

    const nextOwner = await AccountModel.loadLocalByName(req.body.username)
    if (!nextOwner) {
      res.fail({ message: 'Changing video ownership to a remote account is not supported yet' })
      return
    }

    res.locals.nextOwner = nextOwner
    return next()
  }
]

const videosTerminateChangeOwnershipValidator = [
  param('id')
    .custom(isIdValid).withMessage('Should have a valid id'),

  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
    logger.debug('Checking changeOwnership parameters', { parameters: req.params })

    if (areValidationErrors(req, res)) return
    if (!await doesChangeVideoOwnershipExist(req.params.id, res)) return

    // Check if the user who did the request is able to change the ownership of the video
    if (!checkUserCanTerminateOwnershipChange(res.locals.oauth.token.User, res.locals.videoChangeOwnership, res)) return

    const videoChangeOwnership = res.locals.videoChangeOwnership

    if (videoChangeOwnership.status !== VideoChangeOwnershipStatus.WAITING) {
      res.fail({
        status: HttpStatusCode.FORBIDDEN_403,
        message: 'Ownership already accepted or refused'
      })
      return
    }

    return next()
  }
]

const videosAcceptChangeOwnershipValidator = [
  async (req: express.Request, res: express.Response, next: express.NextFunction) => {
    const body = req.body as VideoChangeOwnershipAccept
    if (!await doesVideoChannelOfAccountExist(body.channelId, res.locals.oauth.token.User, res)) return

    const videoChangeOwnership = res.locals.videoChangeOwnership

    const video = videoChangeOwnership.Video

    if (!await checkCanAccept(video, res)) return

    return next()
  }
]

export {
  videosChangeOwnershipValidator,
  videosTerminateChangeOwnershipValidator,
  videosAcceptChangeOwnershipValidator
}

// ---------------------------------------------------------------------------

async function checkCanAccept (video: MVideoWithAllFiles, res: express.Response): Promise<boolean> {
  if (video.isLive) {

    if (video.state !== VideoState.WAITING_FOR_LIVE) {
      res.fail({
        status: HttpStatusCode.BAD_REQUEST_400,
        message: 'You can accept an ownership change of a published live.'
      })

      return false
    }

    return true
  }

  const user = res.locals.oauth.token.User

  if (!await isAbleToUploadVideo(user.id, video.getMaxQualityFile().size)) {
    res.fail({
      status: HttpStatusCode.PAYLOAD_TOO_LARGE_413,
      message: 'The user video quota is exceeded with this video.',
      type: ServerErrorCode.QUOTA_REACHED
    })

    return false
  }

  return true
}