aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/account/user.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/models/account/user.ts')
-rw-r--r--server/models/account/user.ts180
1 files changed, 175 insertions, 5 deletions
diff --git a/server/models/account/user.ts b/server/models/account/user.ts
index 1843603f1..017a96657 100644
--- a/server/models/account/user.ts
+++ b/server/models/account/user.ts
@@ -32,6 +32,7 @@ import {
32 isUserUsernameValid, 32 isUserUsernameValid,
33 isUserVideoQuotaDailyValid, 33 isUserVideoQuotaDailyValid,
34 isUserVideoQuotaValid, 34 isUserVideoQuotaValid,
35 isUserVideosHistoryEnabledValid,
35 isUserWebTorrentEnabledValid 36 isUserWebTorrentEnabledValid
36} from '../../helpers/custom-validators/users' 37} from '../../helpers/custom-validators/users'
37import { comparePassword, cryptPassword } from '../../helpers/peertube-crypto' 38import { comparePassword, cryptPassword } from '../../helpers/peertube-crypto'
@@ -43,6 +44,11 @@ import { NSFWPolicyType } from '../../../shared/models/videos/nsfw-policy.type'
43import { values } from 'lodash' 44import { values } from 'lodash'
44import { NSFW_POLICY_TYPES } from '../../initializers' 45import { NSFW_POLICY_TYPES } from '../../initializers'
45import { clearCacheByUserId } from '../../lib/oauth-model' 46import { clearCacheByUserId } from '../../lib/oauth-model'
47import { UserNotificationSettingModel } from './user-notification-setting'
48import { VideoModel } from '../video/video'
49import { ActorModel } from '../activitypub/actor'
50import { ActorFollowModel } from '../activitypub/actor-follow'
51import { VideoImportModel } from '../video/video-import'
46 52
47enum ScopeNames { 53enum ScopeNames {
48 WITH_VIDEO_CHANNEL = 'WITH_VIDEO_CHANNEL' 54 WITH_VIDEO_CHANNEL = 'WITH_VIDEO_CHANNEL'
@@ -53,6 +59,10 @@ enum ScopeNames {
53 { 59 {
54 model: () => AccountModel, 60 model: () => AccountModel,
55 required: true 61 required: true
62 },
63 {
64 model: () => UserNotificationSettingModel,
65 required: true
56 } 66 }
57 ] 67 ]
58}) 68})
@@ -63,6 +73,10 @@ enum ScopeNames {
63 model: () => AccountModel, 73 model: () => AccountModel,
64 required: true, 74 required: true,
65 include: [ () => VideoChannelModel ] 75 include: [ () => VideoChannelModel ]
76 },
77 {
78 model: () => UserNotificationSettingModel,
79 required: true
66 } 80 }
67 ] 81 ]
68 } 82 }
@@ -116,6 +130,12 @@ export class UserModel extends Model<UserModel> {
116 130
117 @AllowNull(false) 131 @AllowNull(false)
118 @Default(true) 132 @Default(true)
133 @Is('UserVideosHistoryEnabled', value => throwIfNotValid(value, isUserVideosHistoryEnabledValid, 'Videos history enabled'))
134 @Column
135 videosHistoryEnabled: boolean
136
137 @AllowNull(false)
138 @Default(true)
119 @Is('UserAutoPlayVideo', value => throwIfNotValid(value, isUserAutoPlayVideoValid, 'auto play video boolean')) 139 @Is('UserAutoPlayVideo', value => throwIfNotValid(value, isUserAutoPlayVideoValid, 'auto play video boolean'))
120 @Column 140 @Column
121 autoPlayVideo: boolean 141 autoPlayVideo: boolean
@@ -160,6 +180,19 @@ export class UserModel extends Model<UserModel> {
160 }) 180 })
161 Account: AccountModel 181 Account: AccountModel
162 182
183 @HasOne(() => UserNotificationSettingModel, {
184 foreignKey: 'userId',
185 onDelete: 'cascade',
186 hooks: true
187 })
188 NotificationSetting: UserNotificationSettingModel
189
190 @HasMany(() => VideoImportModel, {
191 foreignKey: 'userId',
192 onDelete: 'cascade'
193 })
194 VideoImports: VideoImportModel[]
195
163 @HasMany(() => OAuthTokenModel, { 196 @HasMany(() => OAuthTokenModel, {
164 foreignKey: 'userId', 197 foreignKey: 'userId',
165 onDelete: 'cascade' 198 onDelete: 'cascade'
@@ -242,13 +275,12 @@ export class UserModel extends Model<UserModel> {
242 }) 275 })
243 } 276 }
244 277
245 static listEmailsWithRight (right: UserRight) { 278 static listWithRight (right: UserRight) {
246 const roles = Object.keys(USER_ROLE_LABELS) 279 const roles = Object.keys(USER_ROLE_LABELS)
247 .map(k => parseInt(k, 10) as UserRole) 280 .map(k => parseInt(k, 10) as UserRole)
248 .filter(role => hasUserRight(role, right)) 281 .filter(role => hasUserRight(role, right))
249 282
250 const query = { 283 const query = {
251 attribute: [ 'email' ],
252 where: { 284 where: {
253 role: { 285 role: {
254 [Sequelize.Op.in]: roles 286 [Sequelize.Op.in]: roles
@@ -256,9 +288,56 @@ export class UserModel extends Model<UserModel> {
256 } 288 }
257 } 289 }
258 290
259 return UserModel.unscoped() 291 return UserModel.findAll(query)
260 .findAll(query) 292 }
261 .then(u => u.map(u => u.email)) 293
294 static listUserSubscribersOf (actorId: number) {
295 const query = {
296 include: [
297 {
298 model: UserNotificationSettingModel.unscoped(),
299 required: true
300 },
301 {
302 attributes: [ 'userId' ],
303 model: AccountModel.unscoped(),
304 required: true,
305 include: [
306 {
307 attributes: [ ],
308 model: ActorModel.unscoped(),
309 required: true,
310 where: {
311 serverId: null
312 },
313 include: [
314 {
315 attributes: [ ],
316 as: 'ActorFollowings',
317 model: ActorFollowModel.unscoped(),
318 required: true,
319 where: {
320 targetActorId: actorId
321 }
322 }
323 ]
324 }
325 ]
326 }
327 ]
328 }
329
330 return UserModel.unscoped().findAll(query)
331 }
332
333 static listByUsernames (usernames: string[]) {
334 const query = {
335 where: {
336 username: usernames
337 }
338 }
339
340 return UserModel.findAll(query)
262 } 341 }
263 342
264 static loadById (id: number) { 343 static loadById (id: number) {
@@ -307,6 +386,95 @@ export class UserModel extends Model<UserModel> {
307 return UserModel.findOne(query) 386 return UserModel.findOne(query)
308 } 387 }
309 388
389 static loadByVideoId (videoId: number) {
390 const query = {
391 include: [
392 {
393 required: true,
394 attributes: [ 'id' ],
395 model: AccountModel.unscoped(),
396 include: [
397 {
398 required: true,
399 attributes: [ 'id' ],
400 model: VideoChannelModel.unscoped(),
401 include: [
402 {
403 required: true,
404 attributes: [ 'id' ],
405 model: VideoModel.unscoped(),
406 where: {
407 id: videoId
408 }
409 }
410 ]
411 }
412 ]
413 }
414 ]
415 }
416
417 return UserModel.findOne(query)
418 }
419
420 static loadByVideoImportId (videoImportId: number) {
421 const query = {
422 include: [
423 {
424 required: true,
425 attributes: [ 'id' ],
426 model: VideoImportModel.unscoped(),
427 where: {
428 id: videoImportId
429 }
430 }
431 ]
432 }
433
434 return UserModel.findOne(query)
435 }
436
437 static loadByChannelActorId (videoChannelActorId: number) {
438 const query = {
439 include: [
440 {
441 required: true,
442 attributes: [ 'id' ],
443 model: AccountModel.unscoped(),
444 include: [
445 {
446 required: true,
447 attributes: [ 'id' ],
448 model: VideoChannelModel.unscoped(),
449 where: {
450 actorId: videoChannelActorId
451 }
452 }
453 ]
454 }
455 ]
456 }
457
458 return UserModel.findOne(query)
459 }
460
461 static loadByAccountActorId (accountActorId: number) {
462 const query = {
463 include: [
464 {
465 required: true,
466 attributes: [ 'id' ],
467 model: AccountModel.unscoped(),
468 where: {
469 actorId: accountActorId
470 }
471 }
472 ]
473 }
474
475 return UserModel.findOne(query)
476 }
477
310 static getOriginalVideoFileTotalFromUser (user: UserModel) { 478 static getOriginalVideoFileTotalFromUser (user: UserModel) {
311 // Don't use sequelize because we need to use a sub query 479 // Don't use sequelize because we need to use a sub query
312 const query = UserModel.generateUserQuotaBaseSQL() 480 const query = UserModel.generateUserQuotaBaseSQL()
@@ -363,6 +531,7 @@ export class UserModel extends Model<UserModel> {
363 emailVerified: this.emailVerified, 531 emailVerified: this.emailVerified,
364 nsfwPolicy: this.nsfwPolicy, 532 nsfwPolicy: this.nsfwPolicy,
365 webTorrentEnabled: this.webTorrentEnabled, 533 webTorrentEnabled: this.webTorrentEnabled,
534 videosHistoryEnabled: this.videosHistoryEnabled,
366 autoPlayVideo: this.autoPlayVideo, 535 autoPlayVideo: this.autoPlayVideo,
367 role: this.role, 536 role: this.role,
368 roleLabel: USER_ROLE_LABELS[ this.role ], 537 roleLabel: USER_ROLE_LABELS[ this.role ],
@@ -372,6 +541,7 @@ export class UserModel extends Model<UserModel> {
372 blocked: this.blocked, 541 blocked: this.blocked,
373 blockedReason: this.blockedReason, 542 blockedReason: this.blockedReason,
374 account: this.Account.toFormattedJSON(), 543 account: this.Account.toFormattedJSON(),
544 notificationSettings: this.NotificationSetting ? this.NotificationSetting.toFormattedJSON() : undefined,
375 videoChannels: [], 545 videoChannels: [],
376 videoQuotaUsed: videoQuotaUsed !== undefined 546 videoQuotaUsed: videoQuotaUsed !== undefined
377 ? parseInt(videoQuotaUsed, 10) 547 ? parseInt(videoQuotaUsed, 10)