aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models
diff options
context:
space:
mode:
authorWicklow <123956049+wickloww@users.noreply.github.com>2023-03-31 07:12:21 +0000
committerGitHub <noreply@github.com>2023-03-31 09:12:21 +0200
commit05a60d85997c108d39bcfb14f1ffd4c74f8b1e93 (patch)
tree5041a95ef945620a17f25ba934064b41f6bb00b7 /server/models
parentebd61437c1ec92bea9772924c7051cb00d71f778 (diff)
downloadPeerTube-05a60d85997c108d39bcfb14f1ffd4c74f8b1e93.tar.gz
PeerTube-05a60d85997c108d39bcfb14f1ffd4c74f8b1e93.tar.zst
PeerTube-05a60d85997c108d39bcfb14f1ffd4c74f8b1e93.zip
Feature/Add replay privacy (#5692)
* Add replay settings feature * Fix replay settings behaviour * Fix tests * Fix tests * Fix tests * Update openapi doc and fix tests * Add tests and fix code * Models correction * Add migration and update controller and middleware * Add check params tests * Fix video live middleware * Updated code based on review comments
Diffstat (limited to 'server/models')
-rw-r--r--server/models/video/sql/video/shared/video-table-attributes.ts1
-rw-r--r--server/models/video/video-live-replay-setting.ts42
-rw-r--r--server/models/video/video-live-session.ts49
-rw-r--r--server/models/video/video-live.ts57
-rw-r--r--server/models/video/video.ts1
5 files changed, 146 insertions, 4 deletions
diff --git a/server/models/video/sql/video/shared/video-table-attributes.ts b/server/models/video/sql/video/shared/video-table-attributes.ts
index e2c1c0f6d..34967cd20 100644
--- a/server/models/video/sql/video/shared/video-table-attributes.ts
+++ b/server/models/video/sql/video/shared/video-table-attributes.ts
@@ -160,6 +160,7 @@ export class VideoTableAttributes {
160 'permanentLive', 160 'permanentLive',
161 'latencyMode', 161 'latencyMode',
162 'videoId', 162 'videoId',
163 'replaySettingId',
163 'createdAt', 164 'createdAt',
164 'updatedAt' 165 'updatedAt'
165 ] 166 ]
diff --git a/server/models/video/video-live-replay-setting.ts b/server/models/video/video-live-replay-setting.ts
new file mode 100644
index 000000000..1c824dfa2
--- /dev/null
+++ b/server/models/video/video-live-replay-setting.ts
@@ -0,0 +1,42 @@
1import { isVideoPrivacyValid } from '@server/helpers/custom-validators/videos'
2import { MLiveReplaySetting } from '@server/types/models/video/video-live-replay-setting'
3import { VideoPrivacy } from '@shared/models/videos/video-privacy.enum'
4import { Transaction } from 'sequelize'
5import { AllowNull, Column, CreatedAt, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
6import { throwIfNotValid } from '../shared/sequelize-helpers'
7
8@Table({
9 tableName: 'videoLiveReplaySetting'
10})
11export class VideoLiveReplaySettingModel extends Model<VideoLiveReplaySettingModel> {
12
13 @CreatedAt
14 createdAt: Date
15
16 @UpdatedAt
17 updatedAt: Date
18
19 @AllowNull(false)
20 @Is('VideoPrivacy', value => throwIfNotValid(value, isVideoPrivacyValid, 'privacy'))
21 @Column
22 privacy: VideoPrivacy
23
24 static load (id: number, transaction?: Transaction): Promise<MLiveReplaySetting> {
25 return VideoLiveReplaySettingModel.findOne({
26 where: { id },
27 transaction
28 })
29 }
30
31 static removeSettings (id: number) {
32 return VideoLiveReplaySettingModel.destroy({
33 where: { id }
34 })
35 }
36
37 toFormattedJSON () {
38 return {
39 privacy: this.privacy
40 }
41 }
42}
diff --git a/server/models/video/video-live-session.ts b/server/models/video/video-live-session.ts
index ed386052b..dcded7872 100644
--- a/server/models/video/video-live-session.ts
+++ b/server/models/video/video-live-session.ts
@@ -1,10 +1,23 @@
1import { FindOptions } from 'sequelize' 1import { FindOptions } from 'sequelize'
2import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' 2import {
3 AllowNull,
4 BeforeDestroy,
5 BelongsTo,
6 Column,
7 CreatedAt,
8 DataType,
9 ForeignKey,
10 Model,
11 Scopes,
12 Table,
13 UpdatedAt
14} from 'sequelize-typescript'
3import { MVideoLiveSession, MVideoLiveSessionReplay } from '@server/types/models' 15import { MVideoLiveSession, MVideoLiveSessionReplay } from '@server/types/models'
4import { uuidToShort } from '@shared/extra-utils' 16import { uuidToShort } from '@shared/extra-utils'
5import { LiveVideoError, LiveVideoSession } from '@shared/models' 17import { LiveVideoError, LiveVideoSession } from '@shared/models'
6import { AttributesOnly } from '@shared/typescript-utils' 18import { AttributesOnly } from '@shared/typescript-utils'
7import { VideoModel } from './video' 19import { VideoModel } from './video'
20import { VideoLiveReplaySettingModel } from './video-live-replay-setting'
8 21
9export enum ScopeNames { 22export enum ScopeNames {
10 WITH_REPLAY = 'WITH_REPLAY' 23 WITH_REPLAY = 'WITH_REPLAY'
@@ -17,6 +30,10 @@ export enum ScopeNames {
17 model: VideoModel.unscoped(), 30 model: VideoModel.unscoped(),
18 as: 'ReplayVideo', 31 as: 'ReplayVideo',
19 required: false 32 required: false
33 },
34 {
35 model: VideoLiveReplaySettingModel,
36 required: false
20 } 37 }
21 ] 38 ]
22 } 39 }
@@ -30,6 +47,10 @@ export enum ScopeNames {
30 }, 47 },
31 { 48 {
32 fields: [ 'liveVideoId' ] 49 fields: [ 'liveVideoId' ]
50 },
51 {
52 fields: [ 'replaySettingId' ],
53 unique: true
33 } 54 }
34 ] 55 ]
35}) 56})
@@ -89,6 +110,27 @@ export class VideoLiveSessionModel extends Model<Partial<AttributesOnly<VideoLiv
89 }) 110 })
90 LiveVideo: VideoModel 111 LiveVideo: VideoModel
91 112
113 @ForeignKey(() => VideoLiveReplaySettingModel)
114 @Column
115 replaySettingId: number
116
117 @BelongsTo(() => VideoLiveReplaySettingModel, {
118 foreignKey: {
119 allowNull: true
120 },
121 onDelete: 'set null'
122 })
123 ReplaySetting: VideoLiveReplaySettingModel
124
125 @BeforeDestroy
126 static deleteReplaySetting (instance: VideoLiveSessionModel) {
127 return VideoLiveReplaySettingModel.destroy({
128 where: {
129 id: instance.replaySettingId
130 }
131 })
132 }
133
92 static load (id: number): Promise<MVideoLiveSession> { 134 static load (id: number): Promise<MVideoLiveSession> {
93 return VideoLiveSessionModel.findOne({ 135 return VideoLiveSessionModel.findOne({
94 where: { id } 136 where: { id }
@@ -146,6 +188,10 @@ export class VideoLiveSessionModel extends Model<Partial<AttributesOnly<VideoLiv
146 } 188 }
147 : undefined 189 : undefined
148 190
191 const replaySettings = this.replaySettingId
192 ? this.ReplaySetting.toFormattedJSON()
193 : undefined
194
149 return { 195 return {
150 id: this.id, 196 id: this.id,
151 startDate: this.startDate.toISOString(), 197 startDate: this.startDate.toISOString(),
@@ -154,6 +200,7 @@ export class VideoLiveSessionModel extends Model<Partial<AttributesOnly<VideoLiv
154 : null, 200 : null,
155 endingProcessed: this.endingProcessed, 201 endingProcessed: this.endingProcessed,
156 saveReplay: this.saveReplay, 202 saveReplay: this.saveReplay,
203 replaySettings,
157 replayVideo, 204 replayVideo,
158 error: this.error 205 error: this.error
159 } 206 }
diff --git a/server/models/video/video-live.ts b/server/models/video/video-live.ts
index d2788ef4f..290e1dda7 100644
--- a/server/models/video/video-live.ts
+++ b/server/models/video/video-live.ts
@@ -1,11 +1,24 @@
1import { AllowNull, BelongsTo, Column, CreatedAt, DataType, DefaultScope, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript' 1import {
2 BeforeDestroy,
3 AllowNull,
4 BelongsTo,
5 Column,
6 CreatedAt,
7 DataType,
8 DefaultScope,
9 ForeignKey,
10 Model,
11 Table,
12 UpdatedAt
13} from 'sequelize-typescript'
2import { CONFIG } from '@server/initializers/config' 14import { CONFIG } from '@server/initializers/config'
3import { WEBSERVER } from '@server/initializers/constants' 15import { WEBSERVER } from '@server/initializers/constants'
4import { MVideoLive, MVideoLiveVideo } from '@server/types/models' 16import { MVideoLive, MVideoLiveVideoWithSetting } from '@server/types/models'
5import { LiveVideo, LiveVideoLatencyMode, VideoState } from '@shared/models' 17import { LiveVideo, LiveVideoLatencyMode, VideoState } from '@shared/models'
6import { AttributesOnly } from '@shared/typescript-utils' 18import { AttributesOnly } from '@shared/typescript-utils'
7import { VideoModel } from './video' 19import { VideoModel } from './video'
8import { VideoBlacklistModel } from './video-blacklist' 20import { VideoBlacklistModel } from './video-blacklist'
21import { VideoLiveReplaySettingModel } from './video-live-replay-setting'
9 22
10@DefaultScope(() => ({ 23@DefaultScope(() => ({
11 include: [ 24 include: [
@@ -18,6 +31,10 @@ import { VideoBlacklistModel } from './video-blacklist'
18 required: false 31 required: false
19 } 32 }
20 ] 33 ]
34 },
35 {
36 model: VideoLiveReplaySettingModel,
37 required: false
21 } 38 }
22 ] 39 ]
23})) 40}))
@@ -27,6 +44,10 @@ import { VideoBlacklistModel } from './video-blacklist'
27 { 44 {
28 fields: [ 'videoId' ], 45 fields: [ 'videoId' ],
29 unique: true 46 unique: true
47 },
48 {
49 fields: [ 'replaySettingId' ],
50 unique: true
30 } 51 }
31 ] 52 ]
32}) 53})
@@ -66,6 +87,27 @@ export class VideoLiveModel extends Model<Partial<AttributesOnly<VideoLiveModel>
66 }) 87 })
67 Video: VideoModel 88 Video: VideoModel
68 89
90 @ForeignKey(() => VideoLiveReplaySettingModel)
91 @Column
92 replaySettingId: number
93
94 @BelongsTo(() => VideoLiveReplaySettingModel, {
95 foreignKey: {
96 allowNull: true
97 },
98 onDelete: 'set null'
99 })
100 ReplaySetting: VideoLiveReplaySettingModel
101
102 @BeforeDestroy
103 static deleteReplaySetting (instance: VideoLiveModel) {
104 return VideoLiveReplaySettingModel.destroy({
105 where: {
106 id: instance.replaySettingId
107 }
108 })
109 }
110
69 static loadByStreamKey (streamKey: string) { 111 static loadByStreamKey (streamKey: string) {
70 const query = { 112 const query = {
71 where: { 113 where: {
@@ -84,11 +126,15 @@ export class VideoLiveModel extends Model<Partial<AttributesOnly<VideoLiveModel>
84 required: false 126 required: false
85 } 127 }
86 ] 128 ]
129 },
130 {
131 model: VideoLiveReplaySettingModel.unscoped(),
132 required: false
87 } 133 }
88 ] 134 ]
89 } 135 }
90 136
91 return VideoLiveModel.findOne<MVideoLiveVideo>(query) 137 return VideoLiveModel.findOne<MVideoLiveVideoWithSetting>(query)
92 } 138 }
93 139
94 static loadByVideoId (videoId: number) { 140 static loadByVideoId (videoId: number) {
@@ -120,11 +166,16 @@ export class VideoLiveModel extends Model<Partial<AttributesOnly<VideoLiveModel>
120 } 166 }
121 } 167 }
122 168
169 const replaySettings = this.replaySettingId
170 ? this.ReplaySetting.toFormattedJSON()
171 : undefined
172
123 return { 173 return {
124 ...privateInformation, 174 ...privateInformation,
125 175
126 permanentLive: this.permanentLive, 176 permanentLive: this.permanentLive,
127 saveReplay: this.saveReplay, 177 saveReplay: this.saveReplay,
178 replaySettings,
128 latencyMode: this.latencyMode 179 latencyMode: this.latencyMode
129 } 180 }
130 } 181 }
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index aa9c62e36..0c5ed64ec 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -706,6 +706,7 @@ export class VideoModel extends Model<Partial<AttributesOnly<VideoModel>>> {
706 name: 'videoId', 706 name: 'videoId',
707 allowNull: false 707 allowNull: false
708 }, 708 },
709 hooks: true,
709 onDelete: 'cascade' 710 onDelete: 'cascade'
710 }) 711 })
711 VideoLive: VideoLiveModel 712 VideoLive: VideoLiveModel