diff options
Diffstat (limited to 'server/initializers')
-rw-r--r-- | server/initializers/constants.ts | 29 | ||||
-rw-r--r-- | server/initializers/database.ts | 41 | ||||
-rw-r--r-- | server/initializers/migrations/0250-video-abuse-state.ts | 4 | ||||
-rw-r--r-- | server/initializers/migrations/0470-cleanup-indexes.ts (renamed from server/initializers/migrations/0470-cleaup-indexes.ts) | 0 | ||||
-rw-r--r-- | server/initializers/migrations/0520-abuses-split.ts | 90 |
5 files changed, 133 insertions, 31 deletions
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index e730e3c84..2e9d3956e 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts | |||
@@ -1,9 +1,17 @@ | |||
1 | import { join } from 'path' | 1 | import { join } from 'path' |
2 | import { randomBytes } from 'crypto' | 2 | import { randomBytes } from 'crypto' |
3 | import { JobType, VideoRateType, VideoResolution, VideoState } from '../../shared/models' | ||
4 | import { ActivityPubActorType } from '../../shared/models/activitypub' | 3 | import { ActivityPubActorType } from '../../shared/models/activitypub' |
5 | import { FollowState } from '../../shared/models/actors' | 4 | import { FollowState } from '../../shared/models/actors' |
6 | import { VideoAbuseState, VideoImportState, VideoPrivacy, VideoTranscodingFPS } from '../../shared/models/videos' | 5 | import { |
6 | AbuseState, | ||
7 | VideoImportState, | ||
8 | VideoPrivacy, | ||
9 | VideoTranscodingFPS, | ||
10 | JobType, | ||
11 | VideoRateType, | ||
12 | VideoResolution, | ||
13 | VideoState | ||
14 | } from '../../shared/models' | ||
7 | // Do not use barrels, remain constants as independent as possible | 15 | // Do not use barrels, remain constants as independent as possible |
8 | import { isTestInstance, sanitizeHost, sanitizeUrl, root } from '../helpers/core-utils' | 16 | import { isTestInstance, sanitizeHost, sanitizeUrl, root } from '../helpers/core-utils' |
9 | import { NSFWPolicyType } from '../../shared/models/videos/nsfw-policy.type' | 17 | import { NSFWPolicyType } from '../../shared/models/videos/nsfw-policy.type' |
@@ -15,7 +23,7 @@ import { CONFIG, registerConfigChangedHandler } from './config' | |||
15 | 23 | ||
16 | // --------------------------------------------------------------------------- | 24 | // --------------------------------------------------------------------------- |
17 | 25 | ||
18 | const LAST_MIGRATION_VERSION = 515 | 26 | const LAST_MIGRATION_VERSION = 520 |
19 | 27 | ||
20 | // --------------------------------------------------------------------------- | 28 | // --------------------------------------------------------------------------- |
21 | 29 | ||
@@ -51,7 +59,6 @@ const SORTABLE_COLUMNS = { | |||
51 | USER_SUBSCRIPTIONS: [ 'id', 'createdAt' ], | 59 | USER_SUBSCRIPTIONS: [ 'id', 'createdAt' ], |
52 | ACCOUNTS: [ 'createdAt' ], | 60 | ACCOUNTS: [ 'createdAt' ], |
53 | JOBS: [ 'createdAt' ], | 61 | JOBS: [ 'createdAt' ], |
54 | VIDEO_ABUSES: [ 'id', 'createdAt', 'state' ], | ||
55 | VIDEO_CHANNELS: [ 'id', 'name', 'updatedAt', 'createdAt' ], | 62 | VIDEO_CHANNELS: [ 'id', 'name', 'updatedAt', 'createdAt' ], |
56 | VIDEO_IMPORTS: [ 'createdAt' ], | 63 | VIDEO_IMPORTS: [ 'createdAt' ], |
57 | VIDEO_COMMENT_THREADS: [ 'createdAt', 'totalReplies' ], | 64 | VIDEO_COMMENT_THREADS: [ 'createdAt', 'totalReplies' ], |
@@ -66,6 +73,8 @@ const SORTABLE_COLUMNS = { | |||
66 | VIDEOS_SEARCH: [ 'name', 'duration', 'createdAt', 'publishedAt', 'originallyPublishedAt', 'views', 'likes', 'match' ], | 73 | VIDEOS_SEARCH: [ 'name', 'duration', 'createdAt', 'publishedAt', 'originallyPublishedAt', 'views', 'likes', 'match' ], |
67 | VIDEO_CHANNELS_SEARCH: [ 'match', 'displayName', 'createdAt' ], | 74 | VIDEO_CHANNELS_SEARCH: [ 'match', 'displayName', 'createdAt' ], |
68 | 75 | ||
76 | ABUSES: [ 'id', 'createdAt', 'state' ], | ||
77 | |||
69 | ACCOUNTS_BLOCKLIST: [ 'createdAt' ], | 78 | ACCOUNTS_BLOCKLIST: [ 'createdAt' ], |
70 | SERVERS_BLOCKLIST: [ 'createdAt' ], | 79 | SERVERS_BLOCKLIST: [ 'createdAt' ], |
71 | 80 | ||
@@ -193,7 +202,7 @@ const CONSTRAINTS_FIELDS = { | |||
193 | VIDEO_LANGUAGES: { max: 500 }, // Array length | 202 | VIDEO_LANGUAGES: { max: 500 }, // Array length |
194 | BLOCKED_REASON: { min: 3, max: 250 } // Length | 203 | BLOCKED_REASON: { min: 3, max: 250 } // Length |
195 | }, | 204 | }, |
196 | VIDEO_ABUSES: { | 205 | ABUSES: { |
197 | REASON: { min: 2, max: 3000 }, // Length | 206 | REASON: { min: 2, max: 3000 }, // Length |
198 | MODERATION_COMMENT: { min: 2, max: 3000 } // Length | 207 | MODERATION_COMMENT: { min: 2, max: 3000 } // Length |
199 | }, | 208 | }, |
@@ -378,10 +387,10 @@ const VIDEO_IMPORT_STATES = { | |||
378 | [VideoImportState.REJECTED]: 'Rejected' | 387 | [VideoImportState.REJECTED]: 'Rejected' |
379 | } | 388 | } |
380 | 389 | ||
381 | const VIDEO_ABUSE_STATES = { | 390 | const ABUSE_STATES = { |
382 | [VideoAbuseState.PENDING]: 'Pending', | 391 | [AbuseState.PENDING]: 'Pending', |
383 | [VideoAbuseState.REJECTED]: 'Rejected', | 392 | [AbuseState.REJECTED]: 'Rejected', |
384 | [VideoAbuseState.ACCEPTED]: 'Accepted' | 393 | [AbuseState.ACCEPTED]: 'Accepted' |
385 | } | 394 | } |
386 | 395 | ||
387 | const VIDEO_PLAYLIST_PRIVACIES = { | 396 | const VIDEO_PLAYLIST_PRIVACIES = { |
@@ -778,7 +787,7 @@ export { | |||
778 | VIDEO_RATE_TYPES, | 787 | VIDEO_RATE_TYPES, |
779 | VIDEO_TRANSCODING_FPS, | 788 | VIDEO_TRANSCODING_FPS, |
780 | FFMPEG_NICE, | 789 | FFMPEG_NICE, |
781 | VIDEO_ABUSE_STATES, | 790 | ABUSE_STATES, |
782 | VIDEO_CHANNELS, | 791 | VIDEO_CHANNELS, |
783 | LRU_CACHE, | 792 | LRU_CACHE, |
784 | JOB_REQUEST_TIMEOUT, | 793 | JOB_REQUEST_TIMEOUT, |
diff --git a/server/initializers/database.ts b/server/initializers/database.ts index 633d4f956..0775f1fad 100644 --- a/server/initializers/database.ts +++ b/server/initializers/database.ts | |||
@@ -1,44 +1,45 @@ | |||
1 | import { QueryTypes, Transaction } from 'sequelize' | ||
1 | import { Sequelize as SequelizeTypescript } from 'sequelize-typescript' | 2 | import { Sequelize as SequelizeTypescript } from 'sequelize-typescript' |
3 | import { AbuseModel } from '@server/models/abuse/abuse' | ||
4 | import { VideoAbuseModel } from '@server/models/abuse/video-abuse' | ||
5 | import { VideoCommentAbuseModel } from '@server/models/abuse/video-comment-abuse' | ||
2 | import { isTestInstance } from '../helpers/core-utils' | 6 | import { isTestInstance } from '../helpers/core-utils' |
3 | import { logger } from '../helpers/logger' | 7 | import { logger } from '../helpers/logger' |
4 | |||
5 | import { AccountModel } from '../models/account/account' | 8 | import { AccountModel } from '../models/account/account' |
9 | import { AccountBlocklistModel } from '../models/account/account-blocklist' | ||
6 | import { AccountVideoRateModel } from '../models/account/account-video-rate' | 10 | import { AccountVideoRateModel } from '../models/account/account-video-rate' |
7 | import { UserModel } from '../models/account/user' | 11 | import { UserModel } from '../models/account/user' |
12 | import { UserNotificationModel } from '../models/account/user-notification' | ||
13 | import { UserNotificationSettingModel } from '../models/account/user-notification-setting' | ||
14 | import { UserVideoHistoryModel } from '../models/account/user-video-history' | ||
8 | import { ActorModel } from '../models/activitypub/actor' | 15 | import { ActorModel } from '../models/activitypub/actor' |
9 | import { ActorFollowModel } from '../models/activitypub/actor-follow' | 16 | import { ActorFollowModel } from '../models/activitypub/actor-follow' |
10 | import { ApplicationModel } from '../models/application/application' | 17 | import { ApplicationModel } from '../models/application/application' |
11 | import { AvatarModel } from '../models/avatar/avatar' | 18 | import { AvatarModel } from '../models/avatar/avatar' |
12 | import { OAuthClientModel } from '../models/oauth/oauth-client' | 19 | import { OAuthClientModel } from '../models/oauth/oauth-client' |
13 | import { OAuthTokenModel } from '../models/oauth/oauth-token' | 20 | import { OAuthTokenModel } from '../models/oauth/oauth-token' |
21 | import { VideoRedundancyModel } from '../models/redundancy/video-redundancy' | ||
22 | import { PluginModel } from '../models/server/plugin' | ||
14 | import { ServerModel } from '../models/server/server' | 23 | import { ServerModel } from '../models/server/server' |
24 | import { ServerBlocklistModel } from '../models/server/server-blocklist' | ||
25 | import { ScheduleVideoUpdateModel } from '../models/video/schedule-video-update' | ||
15 | import { TagModel } from '../models/video/tag' | 26 | import { TagModel } from '../models/video/tag' |
27 | import { ThumbnailModel } from '../models/video/thumbnail' | ||
16 | import { VideoModel } from '../models/video/video' | 28 | import { VideoModel } from '../models/video/video' |
17 | import { VideoAbuseModel } from '../models/video/video-abuse' | ||
18 | import { VideoBlacklistModel } from '../models/video/video-blacklist' | 29 | import { VideoBlacklistModel } from '../models/video/video-blacklist' |
30 | import { VideoCaptionModel } from '../models/video/video-caption' | ||
31 | import { VideoChangeOwnershipModel } from '../models/video/video-change-ownership' | ||
19 | import { VideoChannelModel } from '../models/video/video-channel' | 32 | import { VideoChannelModel } from '../models/video/video-channel' |
20 | import { VideoCommentModel } from '../models/video/video-comment' | 33 | import { VideoCommentModel } from '../models/video/video-comment' |
21 | import { VideoFileModel } from '../models/video/video-file' | 34 | import { VideoFileModel } from '../models/video/video-file' |
22 | import { VideoShareModel } from '../models/video/video-share' | ||
23 | import { VideoTagModel } from '../models/video/video-tag' | ||
24 | import { CONFIG } from './config' | ||
25 | import { ScheduleVideoUpdateModel } from '../models/video/schedule-video-update' | ||
26 | import { VideoCaptionModel } from '../models/video/video-caption' | ||
27 | import { VideoImportModel } from '../models/video/video-import' | 35 | import { VideoImportModel } from '../models/video/video-import' |
28 | import { VideoViewModel } from '../models/video/video-view' | ||
29 | import { VideoChangeOwnershipModel } from '../models/video/video-change-ownership' | ||
30 | import { VideoRedundancyModel } from '../models/redundancy/video-redundancy' | ||
31 | import { UserVideoHistoryModel } from '../models/account/user-video-history' | ||
32 | import { AccountBlocklistModel } from '../models/account/account-blocklist' | ||
33 | import { ServerBlocklistModel } from '../models/server/server-blocklist' | ||
34 | import { UserNotificationModel } from '../models/account/user-notification' | ||
35 | import { UserNotificationSettingModel } from '../models/account/user-notification-setting' | ||
36 | import { VideoStreamingPlaylistModel } from '../models/video/video-streaming-playlist' | ||
37 | import { VideoPlaylistModel } from '../models/video/video-playlist' | 36 | import { VideoPlaylistModel } from '../models/video/video-playlist' |
38 | import { VideoPlaylistElementModel } from '../models/video/video-playlist-element' | 37 | import { VideoPlaylistElementModel } from '../models/video/video-playlist-element' |
39 | import { ThumbnailModel } from '../models/video/thumbnail' | 38 | import { VideoShareModel } from '../models/video/video-share' |
40 | import { PluginModel } from '../models/server/plugin' | 39 | import { VideoStreamingPlaylistModel } from '../models/video/video-streaming-playlist' |
41 | import { QueryTypes, Transaction } from 'sequelize' | 40 | import { VideoTagModel } from '../models/video/video-tag' |
41 | import { VideoViewModel } from '../models/video/video-view' | ||
42 | import { CONFIG } from './config' | ||
42 | 43 | ||
43 | require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string | 44 | require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string |
44 | 45 | ||
@@ -86,6 +87,8 @@ async function initDatabaseModels (silent: boolean) { | |||
86 | TagModel, | 87 | TagModel, |
87 | AccountVideoRateModel, | 88 | AccountVideoRateModel, |
88 | UserModel, | 89 | UserModel, |
90 | AbuseModel, | ||
91 | VideoCommentAbuseModel, | ||
89 | VideoAbuseModel, | 92 | VideoAbuseModel, |
90 | VideoModel, | 93 | VideoModel, |
91 | VideoChangeOwnershipModel, | 94 | VideoChangeOwnershipModel, |
diff --git a/server/initializers/migrations/0250-video-abuse-state.ts b/server/initializers/migrations/0250-video-abuse-state.ts index 50de25182..e4993c393 100644 --- a/server/initializers/migrations/0250-video-abuse-state.ts +++ b/server/initializers/migrations/0250-video-abuse-state.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import { VideoAbuseState } from '../../../shared/models/videos' | 2 | import { AbuseState } from '../../../shared/models' |
3 | 3 | ||
4 | async function up (utils: { | 4 | async function up (utils: { |
5 | transaction: Sequelize.Transaction | 5 | transaction: Sequelize.Transaction |
@@ -16,7 +16,7 @@ async function up (utils: { | |||
16 | } | 16 | } |
17 | 17 | ||
18 | { | 18 | { |
19 | const query = 'UPDATE "videoAbuse" SET "state" = ' + VideoAbuseState.PENDING | 19 | const query = 'UPDATE "videoAbuse" SET "state" = ' + AbuseState.PENDING |
20 | await utils.sequelize.query(query) | 20 | await utils.sequelize.query(query) |
21 | } | 21 | } |
22 | 22 | ||
diff --git a/server/initializers/migrations/0470-cleaup-indexes.ts b/server/initializers/migrations/0470-cleanup-indexes.ts index 7365c30f8..7365c30f8 100644 --- a/server/initializers/migrations/0470-cleaup-indexes.ts +++ b/server/initializers/migrations/0470-cleanup-indexes.ts | |||
diff --git a/server/initializers/migrations/0520-abuses-split.ts b/server/initializers/migrations/0520-abuses-split.ts new file mode 100644 index 000000000..b02a21989 --- /dev/null +++ b/server/initializers/migrations/0520-abuses-split.ts | |||
@@ -0,0 +1,90 @@ | |||
1 | import * as Sequelize from 'sequelize' | ||
2 | |||
3 | async function up (utils: { | ||
4 | transaction: Sequelize.Transaction | ||
5 | queryInterface: Sequelize.QueryInterface | ||
6 | sequelize: Sequelize.Sequelize | ||
7 | }): Promise<void> { | ||
8 | await utils.queryInterface.renameTable('videoAbuse', 'abuse') | ||
9 | |||
10 | await utils.sequelize.query(` | ||
11 | ALTER TABLE "abuse" | ||
12 | ADD COLUMN "flaggedAccountId" INTEGER REFERENCES "account" ("id") ON DELETE SET NULL ON UPDATE CASCADE | ||
13 | `) | ||
14 | |||
15 | await utils.sequelize.query(` | ||
16 | UPDATE "abuse" SET "videoId" = NULL | ||
17 | WHERE "videoId" NOT IN (SELECT "id" FROM "video") | ||
18 | `) | ||
19 | |||
20 | await utils.sequelize.query(` | ||
21 | UPDATE "abuse" SET "flaggedAccountId" = "videoChannel"."accountId" | ||
22 | FROM "video" INNER JOIN "videoChannel" ON "video"."channelId" = "videoChannel"."id" | ||
23 | WHERE "abuse"."videoId" = "video"."id" | ||
24 | `) | ||
25 | |||
26 | await utils.sequelize.query('DROP INDEX IF EXISTS video_abuse_video_id;') | ||
27 | await utils.sequelize.query('DROP INDEX IF EXISTS video_abuse_reporter_account_id;') | ||
28 | |||
29 | await utils.sequelize.query(` | ||
30 | CREATE TABLE IF NOT EXISTS "videoAbuse" ( | ||
31 | "id" serial, | ||
32 | "startAt" integer DEFAULT NULL, | ||
33 | "endAt" integer DEFAULT NULL, | ||
34 | "deletedVideo" jsonb DEFAULT NULL, | ||
35 | "abuseId" integer NOT NULL REFERENCES "abuse" ("id") ON DELETE CASCADE ON UPDATE CASCADE, | ||
36 | "videoId" integer REFERENCES "video" ("id") ON DELETE SET NULL ON UPDATE CASCADE, | ||
37 | "createdAt" TIMESTAMP WITH time zone NOT NULL, | ||
38 | "updatedAt" timestamp WITH time zone NOT NULL, | ||
39 | PRIMARY KEY ("id") | ||
40 | ); | ||
41 | `) | ||
42 | |||
43 | await utils.sequelize.query(` | ||
44 | CREATE TABLE IF NOT EXISTS "commentAbuse" ( | ||
45 | "id" serial, | ||
46 | "abuseId" integer NOT NULL REFERENCES "abuse" ("id") ON DELETE CASCADE ON UPDATE CASCADE, | ||
47 | "videoCommentId" integer REFERENCES "videoComment" ("id") ON DELETE SET NULL ON UPDATE CASCADE, | ||
48 | "createdAt" timestamp WITH time zone NOT NULL, | ||
49 | "updatedAt" timestamp WITH time zone NOT NULL, | ||
50 | PRIMARY KEY ("id") | ||
51 | ); | ||
52 | `) | ||
53 | |||
54 | await utils.sequelize.query(` | ||
55 | INSERT INTO "videoAbuse" ("startAt", "endAt", "deletedVideo", "abuseId", "videoId", "createdAt", "updatedAt") | ||
56 | SELECT "abuse"."startAt", "abuse"."endAt", "abuse"."deletedVideo", "abuse"."id", "abuse"."videoId", | ||
57 | "abuse"."createdAt", "abuse"."updatedAt" | ||
58 | FROM "abuse" | ||
59 | `) | ||
60 | |||
61 | await utils.queryInterface.removeColumn('abuse', 'startAt') | ||
62 | await utils.queryInterface.removeColumn('abuse', 'endAt') | ||
63 | await utils.queryInterface.removeColumn('abuse', 'deletedVideo') | ||
64 | await utils.queryInterface.removeColumn('abuse', 'videoId') | ||
65 | |||
66 | await utils.sequelize.query('DROP INDEX IF EXISTS user_notification_video_abuse_id') | ||
67 | await utils.queryInterface.renameColumn('userNotification', 'videoAbuseId', 'abuseId') | ||
68 | await utils.sequelize.query( | ||
69 | 'ALTER TABLE "userNotification" RENAME CONSTRAINT "userNotification_videoAbuseId_fkey" TO "userNotification_abuseId_fkey"' | ||
70 | ) | ||
71 | |||
72 | await utils.sequelize.query( | ||
73 | 'ALTER TABLE "abuse" RENAME CONSTRAINT "videoAbuse_reporterAccountId_fkey" TO "abuse_reporterAccountId_fkey"' | ||
74 | ) | ||
75 | |||
76 | await utils.sequelize.query( | ||
77 | 'ALTER INDEX IF EXISTS "videoAbuse_pkey" RENAME TO "abuse_pkey"' | ||
78 | ) | ||
79 | |||
80 | await utils.queryInterface.renameColumn('userNotificationSetting', 'videoAbuseAsModerator', 'abuseAsModerator') | ||
81 | } | ||
82 | |||
83 | function down (options) { | ||
84 | throw new Error('Not implemented.') | ||
85 | } | ||
86 | |||
87 | export { | ||
88 | up, | ||
89 | down | ||
90 | } | ||