diff options
Diffstat (limited to 'server/models/account')
-rw-r--r-- | server/models/account/account-blocklist.ts | 10 | ||||
-rw-r--r-- | server/models/account/account.ts | 9 | ||||
-rw-r--r-- | server/models/account/user-notification-setting.ts | 8 | ||||
-rw-r--r-- | server/models/account/user-notification.ts | 102 | ||||
-rw-r--r-- | server/models/account/user.ts | 38 |
5 files changed, 112 insertions, 55 deletions
diff --git a/server/models/account/account-blocklist.ts b/server/models/account/account-blocklist.ts index cf8872fd5..577b7dc19 100644 --- a/server/models/account/account-blocklist.ts +++ b/server/models/account/account-blocklist.ts | |||
@@ -1,12 +1,12 @@ | |||
1 | import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' | ||
2 | import { AccountModel } from './account' | ||
3 | import { getSort, searchAttribute } from '../utils' | ||
4 | import { AccountBlock } from '../../../shared/models/blocklist' | ||
5 | import { Op } from 'sequelize' | ||
6 | import * as Bluebird from 'bluebird' | 1 | import * as Bluebird from 'bluebird' |
2 | import { Op } from 'sequelize' | ||
3 | import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' | ||
7 | import { MAccountBlocklist, MAccountBlocklistAccounts, MAccountBlocklistFormattable } from '@server/types/models' | 4 | import { MAccountBlocklist, MAccountBlocklistAccounts, MAccountBlocklistFormattable } from '@server/types/models' |
5 | import { AccountBlock } from '../../../shared/models' | ||
8 | import { ActorModel } from '../activitypub/actor' | 6 | import { ActorModel } from '../activitypub/actor' |
9 | import { ServerModel } from '../server/server' | 7 | import { ServerModel } from '../server/server' |
8 | import { getSort, searchAttribute } from '../utils' | ||
9 | import { AccountModel } from './account' | ||
10 | 10 | ||
11 | enum ScopeNames { | 11 | enum ScopeNames { |
12 | WITH_ACCOUNTS = 'WITH_ACCOUNTS' | 12 | WITH_ACCOUNTS = 'WITH_ACCOUNTS' |
diff --git a/server/models/account/account.ts b/server/models/account/account.ts index 4395d179a..f97519b14 100644 --- a/server/models/account/account.ts +++ b/server/models/account/account.ts | |||
@@ -42,6 +42,7 @@ export enum ScopeNames { | |||
42 | } | 42 | } |
43 | 43 | ||
44 | export type SummaryOptions = { | 44 | export type SummaryOptions = { |
45 | actorRequired?: boolean // Default: true | ||
45 | whereActor?: WhereOptions | 46 | whereActor?: WhereOptions |
46 | withAccountBlockerIds?: number[] | 47 | withAccountBlockerIds?: number[] |
47 | } | 48 | } |
@@ -65,12 +66,12 @@ export type SummaryOptions = { | |||
65 | } | 66 | } |
66 | 67 | ||
67 | const query: FindOptions = { | 68 | const query: FindOptions = { |
68 | attributes: [ 'id', 'name' ], | 69 | attributes: [ 'id', 'name', 'actorId' ], |
69 | include: [ | 70 | include: [ |
70 | { | 71 | { |
71 | attributes: [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ], | 72 | attributes: [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ], |
72 | model: ActorModel.unscoped(), | 73 | model: ActorModel.unscoped(), |
73 | required: true, | 74 | required: options.actorRequired ?? true, |
74 | where: whereActor, | 75 | where: whereActor, |
75 | include: [ | 76 | include: [ |
76 | serverInclude, | 77 | serverInclude, |
@@ -388,6 +389,10 @@ export class AccountModel extends Model<AccountModel> { | |||
388 | .findAll(query) | 389 | .findAll(query) |
389 | } | 390 | } |
390 | 391 | ||
392 | getClientUrl () { | ||
393 | return WEBSERVER.URL + '/accounts/' + this.Actor.getIdentifier() | ||
394 | } | ||
395 | |||
391 | toFormattedJSON (this: MAccountFormattable): Account { | 396 | toFormattedJSON (this: MAccountFormattable): Account { |
392 | const actor = this.Actor.toFormattedJSON() | 397 | const actor = this.Actor.toFormattedJSON() |
393 | const account = { | 398 | const account = { |
diff --git a/server/models/account/user-notification-setting.ts b/server/models/account/user-notification-setting.ts index b69b47265..d8f3f13da 100644 --- a/server/models/account/user-notification-setting.ts +++ b/server/models/account/user-notification-setting.ts | |||
@@ -51,11 +51,11 @@ export class UserNotificationSettingModel extends Model<UserNotificationSettingM | |||
51 | @AllowNull(false) | 51 | @AllowNull(false) |
52 | @Default(null) | 52 | @Default(null) |
53 | @Is( | 53 | @Is( |
54 | 'UserNotificationSettingVideoAbuseAsModerator', | 54 | 'UserNotificationSettingAbuseAsModerator', |
55 | value => throwIfNotValid(value, isUserNotificationSettingValid, 'videoAbuseAsModerator') | 55 | value => throwIfNotValid(value, isUserNotificationSettingValid, 'abuseAsModerator') |
56 | ) | 56 | ) |
57 | @Column | 57 | @Column |
58 | videoAbuseAsModerator: UserNotificationSettingValue | 58 | abuseAsModerator: UserNotificationSettingValue |
59 | 59 | ||
60 | @AllowNull(false) | 60 | @AllowNull(false) |
61 | @Default(null) | 61 | @Default(null) |
@@ -166,7 +166,7 @@ export class UserNotificationSettingModel extends Model<UserNotificationSettingM | |||
166 | return { | 166 | return { |
167 | newCommentOnMyVideo: this.newCommentOnMyVideo, | 167 | newCommentOnMyVideo: this.newCommentOnMyVideo, |
168 | newVideoFromSubscription: this.newVideoFromSubscription, | 168 | newVideoFromSubscription: this.newVideoFromSubscription, |
169 | videoAbuseAsModerator: this.videoAbuseAsModerator, | 169 | abuseAsModerator: this.abuseAsModerator, |
170 | videoAutoBlacklistAsModerator: this.videoAutoBlacklistAsModerator, | 170 | videoAutoBlacklistAsModerator: this.videoAutoBlacklistAsModerator, |
171 | blacklistOnMyVideo: this.blacklistOnMyVideo, | 171 | blacklistOnMyVideo: this.blacklistOnMyVideo, |
172 | myVideoPublished: this.myVideoPublished, | 172 | myVideoPublished: this.myVideoPublished, |
diff --git a/server/models/account/user-notification.ts b/server/models/account/user-notification.ts index 30985bb0f..2945bf709 100644 --- a/server/models/account/user-notification.ts +++ b/server/models/account/user-notification.ts | |||
@@ -1,22 +1,24 @@ | |||
1 | import { FindOptions, ModelIndexesOptions, Op, WhereOptions } from 'sequelize' | ||
1 | import { AllowNull, BelongsTo, Column, CreatedAt, Default, ForeignKey, Is, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' | 2 | import { AllowNull, BelongsTo, Column, CreatedAt, Default, ForeignKey, Is, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' |
3 | import { UserNotificationIncludes, UserNotificationModelForApi } from '@server/types/models/user' | ||
2 | import { UserNotification, UserNotificationType } from '../../../shared' | 4 | import { UserNotification, UserNotificationType } from '../../../shared' |
3 | import { getSort, throwIfNotValid } from '../utils' | ||
4 | import { isBooleanValid } from '../../helpers/custom-validators/misc' | 5 | import { isBooleanValid } from '../../helpers/custom-validators/misc' |
5 | import { isUserNotificationTypeValid } from '../../helpers/custom-validators/user-notifications' | 6 | import { isUserNotificationTypeValid } from '../../helpers/custom-validators/user-notifications' |
6 | import { UserModel } from './user' | 7 | import { AbuseModel } from '../abuse/abuse' |
7 | import { VideoModel } from '../video/video' | 8 | import { VideoAbuseModel } from '../abuse/video-abuse' |
8 | import { VideoCommentModel } from '../video/video-comment' | 9 | import { VideoCommentAbuseModel } from '../abuse/video-comment-abuse' |
9 | import { FindOptions, ModelIndexesOptions, Op, WhereOptions } from 'sequelize' | ||
10 | import { VideoChannelModel } from '../video/video-channel' | ||
11 | import { AccountModel } from './account' | ||
12 | import { VideoAbuseModel } from '../video/video-abuse' | ||
13 | import { VideoBlacklistModel } from '../video/video-blacklist' | ||
14 | import { VideoImportModel } from '../video/video-import' | ||
15 | import { ActorModel } from '../activitypub/actor' | 10 | import { ActorModel } from '../activitypub/actor' |
16 | import { ActorFollowModel } from '../activitypub/actor-follow' | 11 | import { ActorFollowModel } from '../activitypub/actor-follow' |
17 | import { AvatarModel } from '../avatar/avatar' | 12 | import { AvatarModel } from '../avatar/avatar' |
18 | import { ServerModel } from '../server/server' | 13 | import { ServerModel } from '../server/server' |
19 | import { UserNotificationIncludes, UserNotificationModelForApi } from '@server/types/models/user' | 14 | import { getSort, throwIfNotValid } from '../utils' |
15 | import { VideoModel } from '../video/video' | ||
16 | import { VideoBlacklistModel } from '../video/video-blacklist' | ||
17 | import { VideoChannelModel } from '../video/video-channel' | ||
18 | import { VideoCommentModel } from '../video/video-comment' | ||
19 | import { VideoImportModel } from '../video/video-import' | ||
20 | import { AccountModel } from './account' | ||
21 | import { UserModel } from './user' | ||
20 | 22 | ||
21 | enum ScopeNames { | 23 | enum ScopeNames { |
22 | WITH_ALL = 'WITH_ALL' | 24 | WITH_ALL = 'WITH_ALL' |
@@ -87,9 +89,41 @@ function buildAccountInclude (required: boolean, withActor = false) { | |||
87 | 89 | ||
88 | { | 90 | { |
89 | attributes: [ 'id' ], | 91 | attributes: [ 'id' ], |
90 | model: VideoAbuseModel.unscoped(), | 92 | model: AbuseModel.unscoped(), |
91 | required: false, | 93 | required: false, |
92 | include: [ buildVideoInclude(true) ] | 94 | include: [ |
95 | { | ||
96 | attributes: [ 'id' ], | ||
97 | model: VideoAbuseModel.unscoped(), | ||
98 | required: false, | ||
99 | include: [ buildVideoInclude(true) ] | ||
100 | }, | ||
101 | { | ||
102 | attributes: [ 'id' ], | ||
103 | model: VideoCommentAbuseModel.unscoped(), | ||
104 | required: false, | ||
105 | include: [ | ||
106 | { | ||
107 | attributes: [ 'id', 'originCommentId' ], | ||
108 | model: VideoCommentModel, | ||
109 | required: true, | ||
110 | include: [ | ||
111 | { | ||
112 | attributes: [ 'id', 'name', 'uuid' ], | ||
113 | model: VideoModel.unscoped(), | ||
114 | required: true | ||
115 | } | ||
116 | ] | ||
117 | } | ||
118 | ] | ||
119 | }, | ||
120 | { | ||
121 | model: AccountModel, | ||
122 | as: 'FlaggedAccount', | ||
123 | required: true, | ||
124 | include: [ buildActorWithAvatarInclude() ] | ||
125 | } | ||
126 | ] | ||
93 | }, | 127 | }, |
94 | 128 | ||
95 | { | 129 | { |
@@ -179,9 +213,9 @@ function buildAccountInclude (required: boolean, withActor = false) { | |||
179 | } | 213 | } |
180 | }, | 214 | }, |
181 | { | 215 | { |
182 | fields: [ 'videoAbuseId' ], | 216 | fields: [ 'abuseId' ], |
183 | where: { | 217 | where: { |
184 | videoAbuseId: { | 218 | abuseId: { |
185 | [Op.ne]: null | 219 | [Op.ne]: null |
186 | } | 220 | } |
187 | } | 221 | } |
@@ -276,17 +310,17 @@ export class UserNotificationModel extends Model<UserNotificationModel> { | |||
276 | }) | 310 | }) |
277 | Comment: VideoCommentModel | 311 | Comment: VideoCommentModel |
278 | 312 | ||
279 | @ForeignKey(() => VideoAbuseModel) | 313 | @ForeignKey(() => AbuseModel) |
280 | @Column | 314 | @Column |
281 | videoAbuseId: number | 315 | abuseId: number |
282 | 316 | ||
283 | @BelongsTo(() => VideoAbuseModel, { | 317 | @BelongsTo(() => AbuseModel, { |
284 | foreignKey: { | 318 | foreignKey: { |
285 | allowNull: true | 319 | allowNull: true |
286 | }, | 320 | }, |
287 | onDelete: 'cascade' | 321 | onDelete: 'cascade' |
288 | }) | 322 | }) |
289 | VideoAbuse: VideoAbuseModel | 323 | Abuse: AbuseModel |
290 | 324 | ||
291 | @ForeignKey(() => VideoBlacklistModel) | 325 | @ForeignKey(() => VideoBlacklistModel) |
292 | @Column | 326 | @Column |
@@ -397,10 +431,7 @@ export class UserNotificationModel extends Model<UserNotificationModel> { | |||
397 | video: this.formatVideo(this.Comment.Video) | 431 | video: this.formatVideo(this.Comment.Video) |
398 | } : undefined | 432 | } : undefined |
399 | 433 | ||
400 | const videoAbuse = this.VideoAbuse ? { | 434 | const abuse = this.Abuse ? this.formatAbuse(this.Abuse) : undefined |
401 | id: this.VideoAbuse.id, | ||
402 | video: this.formatVideo(this.VideoAbuse.Video) | ||
403 | } : undefined | ||
404 | 435 | ||
405 | const videoBlacklist = this.VideoBlacklist ? { | 436 | const videoBlacklist = this.VideoBlacklist ? { |
406 | id: this.VideoBlacklist.id, | 437 | id: this.VideoBlacklist.id, |
@@ -439,7 +470,7 @@ export class UserNotificationModel extends Model<UserNotificationModel> { | |||
439 | video, | 470 | video, |
440 | videoImport, | 471 | videoImport, |
441 | comment, | 472 | comment, |
442 | videoAbuse, | 473 | abuse, |
443 | videoBlacklist, | 474 | videoBlacklist, |
444 | account, | 475 | account, |
445 | actorFollow, | 476 | actorFollow, |
@@ -456,6 +487,29 @@ export class UserNotificationModel extends Model<UserNotificationModel> { | |||
456 | } | 487 | } |
457 | } | 488 | } |
458 | 489 | ||
490 | formatAbuse (this: UserNotificationModelForApi, abuse: UserNotificationIncludes.AbuseInclude) { | ||
491 | const commentAbuse = abuse.VideoCommentAbuse?.VideoComment ? { | ||
492 | threadId: abuse.VideoCommentAbuse.VideoComment.getThreadId(), | ||
493 | |||
494 | video: { | ||
495 | id: abuse.VideoCommentAbuse.VideoComment.Video.id, | ||
496 | name: abuse.VideoCommentAbuse.VideoComment.Video.name, | ||
497 | uuid: abuse.VideoCommentAbuse.VideoComment.Video.uuid | ||
498 | } | ||
499 | } : undefined | ||
500 | |||
501 | const videoAbuse = abuse.VideoAbuse?.Video ? this.formatVideo(abuse.VideoAbuse.Video) : undefined | ||
502 | |||
503 | const accountAbuse = (!commentAbuse && !videoAbuse) ? this.formatActor(abuse.FlaggedAccount) : undefined | ||
504 | |||
505 | return { | ||
506 | id: abuse.id, | ||
507 | video: videoAbuse, | ||
508 | comment: commentAbuse, | ||
509 | account: accountAbuse | ||
510 | } | ||
511 | } | ||
512 | |||
459 | formatActor ( | 513 | formatActor ( |
460 | this: UserNotificationModelForApi, | 514 | this: UserNotificationModelForApi, |
461 | accountOrChannel: UserNotificationIncludes.AccountIncludeActor | UserNotificationIncludes.VideoChannelIncludeActor | 515 | accountOrChannel: UserNotificationIncludes.AccountIncludeActor | UserNotificationIncludes.VideoChannelIncludeActor |
diff --git a/server/models/account/user.ts b/server/models/account/user.ts index de193131a..5f45f8e7c 100644 --- a/server/models/account/user.ts +++ b/server/models/account/user.ts | |||
@@ -19,7 +19,7 @@ import { | |||
19 | Table, | 19 | Table, |
20 | UpdatedAt | 20 | UpdatedAt |
21 | } from 'sequelize-typescript' | 21 | } from 'sequelize-typescript' |
22 | import { hasUserRight, MyUser, USER_ROLE_LABELS, UserRight, VideoAbuseState, VideoPlaylistType, VideoPrivacy } from '../../../shared' | 22 | import { hasUserRight, MyUser, USER_ROLE_LABELS, UserRight, AbuseState, VideoPlaylistType, VideoPrivacy } from '../../../shared' |
23 | import { User, UserRole } from '../../../shared/models/users' | 23 | import { User, UserRole } from '../../../shared/models/users' |
24 | import { | 24 | import { |
25 | isNoInstanceConfigWarningModal, | 25 | isNoInstanceConfigWarningModal, |
@@ -168,28 +168,26 @@ enum ScopeNames { | |||
168 | '(' + | 168 | '(' + |
169 | `SELECT concat_ws(':', "abuses", "acceptedAbuses") ` + | 169 | `SELECT concat_ws(':', "abuses", "acceptedAbuses") ` + |
170 | 'FROM (' + | 170 | 'FROM (' + |
171 | 'SELECT COUNT("videoAbuse"."id") AS "abuses", ' + | 171 | 'SELECT COUNT("abuse"."id") AS "abuses", ' + |
172 | `COUNT("videoAbuse"."id") FILTER (WHERE "videoAbuse"."state" = ${VideoAbuseState.ACCEPTED}) AS "acceptedAbuses" ` + | 172 | `COUNT("abuse"."id") FILTER (WHERE "abuse"."state" = ${AbuseState.ACCEPTED}) AS "acceptedAbuses" ` + |
173 | 'FROM "videoAbuse" ' + | 173 | 'FROM "abuse" ' + |
174 | 'INNER JOIN "video" ON "videoAbuse"."videoId" = "video"."id" ' + | 174 | 'INNER JOIN "account" ON "account"."id" = "abuse"."flaggedAccountId" ' + |
175 | 'INNER JOIN "videoChannel" ON "videoChannel"."id" = "video"."channelId" ' + | ||
176 | 'INNER JOIN "account" ON "account"."id" = "videoChannel"."accountId" ' + | ||
177 | 'WHERE "account"."userId" = "UserModel"."id"' + | 175 | 'WHERE "account"."userId" = "UserModel"."id"' + |
178 | ') t' + | 176 | ') t' + |
179 | ')' | 177 | ')' |
180 | ), | 178 | ), |
181 | 'videoAbusesCount' | 179 | 'abusesCount' |
182 | ], | 180 | ], |
183 | [ | 181 | [ |
184 | literal( | 182 | literal( |
185 | '(' + | 183 | '(' + |
186 | 'SELECT COUNT("videoAbuse"."id") ' + | 184 | 'SELECT COUNT("abuse"."id") ' + |
187 | 'FROM "videoAbuse" ' + | 185 | 'FROM "abuse" ' + |
188 | 'INNER JOIN "account" ON "account"."id" = "videoAbuse"."reporterAccountId" ' + | 186 | 'INNER JOIN "account" ON "account"."id" = "abuse"."reporterAccountId" ' + |
189 | 'WHERE "account"."userId" = "UserModel"."id"' + | 187 | 'WHERE "account"."userId" = "UserModel"."id"' + |
190 | ')' | 188 | ')' |
191 | ), | 189 | ), |
192 | 'videoAbusesCreatedCount' | 190 | 'abusesCreatedCount' |
193 | ], | 191 | ], |
194 | [ | 192 | [ |
195 | literal( | 193 | literal( |
@@ -780,8 +778,8 @@ export class UserModel extends Model<UserModel> { | |||
780 | const videoQuotaUsed = this.get('videoQuotaUsed') | 778 | const videoQuotaUsed = this.get('videoQuotaUsed') |
781 | const videoQuotaUsedDaily = this.get('videoQuotaUsedDaily') | 779 | const videoQuotaUsedDaily = this.get('videoQuotaUsedDaily') |
782 | const videosCount = this.get('videosCount') | 780 | const videosCount = this.get('videosCount') |
783 | const [ videoAbusesCount, videoAbusesAcceptedCount ] = (this.get('videoAbusesCount') as string || ':').split(':') | 781 | const [ abusesCount, abusesAcceptedCount ] = (this.get('abusesCount') as string || ':').split(':') |
784 | const videoAbusesCreatedCount = this.get('videoAbusesCreatedCount') | 782 | const abusesCreatedCount = this.get('abusesCreatedCount') |
785 | const videoCommentsCount = this.get('videoCommentsCount') | 783 | const videoCommentsCount = this.get('videoCommentsCount') |
786 | 784 | ||
787 | const json: User = { | 785 | const json: User = { |
@@ -815,14 +813,14 @@ export class UserModel extends Model<UserModel> { | |||
815 | videosCount: videosCount !== undefined | 813 | videosCount: videosCount !== undefined |
816 | ? parseInt(videosCount + '', 10) | 814 | ? parseInt(videosCount + '', 10) |
817 | : undefined, | 815 | : undefined, |
818 | videoAbusesCount: videoAbusesCount | 816 | abusesCount: abusesCount |
819 | ? parseInt(videoAbusesCount, 10) | 817 | ? parseInt(abusesCount, 10) |
820 | : undefined, | 818 | : undefined, |
821 | videoAbusesAcceptedCount: videoAbusesAcceptedCount | 819 | abusesAcceptedCount: abusesAcceptedCount |
822 | ? parseInt(videoAbusesAcceptedCount, 10) | 820 | ? parseInt(abusesAcceptedCount, 10) |
823 | : undefined, | 821 | : undefined, |
824 | videoAbusesCreatedCount: videoAbusesCreatedCount !== undefined | 822 | abusesCreatedCount: abusesCreatedCount !== undefined |
825 | ? parseInt(videoAbusesCreatedCount + '', 10) | 823 | ? parseInt(abusesCreatedCount + '', 10) |
826 | : undefined, | 824 | : undefined, |
827 | videoCommentsCount: videoCommentsCount !== undefined | 825 | videoCommentsCount: videoCommentsCount !== undefined |
828 | ? parseInt(videoCommentsCount + '', 10) | 826 | ? parseInt(videoCommentsCount + '', 10) |