diff options
author | Chocobozzz <me@florianbigard.com> | 2023-01-19 09:27:16 +0100 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2023-01-19 13:53:40 +0100 |
commit | e364e31e25bd1d4b8d801c845a96d6be708f0a18 (patch) | |
tree | 220785a42af361706eb8243960c5da9cddf4d2be /server/initializers | |
parent | bc48e33b80f357767b98c1d310b04bdda24c6d46 (diff) | |
download | PeerTube-e364e31e25bd1d4b8d801c845a96d6be708f0a18.tar.gz PeerTube-e364e31e25bd1d4b8d801c845a96d6be708f0a18.tar.zst PeerTube-e364e31e25bd1d4b8d801c845a96d6be708f0a18.zip |
Implement signup approval in server
Diffstat (limited to 'server/initializers')
-rw-r--r-- | server/initializers/checker-after-init.ts | 5 | ||||
-rw-r--r-- | server/initializers/checker-before-init.ts | 2 | ||||
-rw-r--r-- | server/initializers/config.ts | 1 | ||||
-rw-r--r-- | server/initializers/constants.ts | 20 | ||||
-rw-r--r-- | server/initializers/database.ts | 6 | ||||
-rw-r--r-- | server/initializers/migrations/0750-user-registration.ts | 58 |
6 files changed, 86 insertions, 6 deletions
diff --git a/server/initializers/checker-after-init.ts b/server/initializers/checker-after-init.ts index dc46b5126..247bc2ad5 100644 --- a/server/initializers/checker-after-init.ts +++ b/server/initializers/checker-after-init.ts | |||
@@ -116,6 +116,11 @@ function checkEmailConfig () { | |||
116 | throw new Error('Emailer is disabled but you require signup email verification.') | 116 | throw new Error('Emailer is disabled but you require signup email verification.') |
117 | } | 117 | } |
118 | 118 | ||
119 | if (CONFIG.SIGNUP.ENABLED && CONFIG.SIGNUP.REQUIRES_APPROVAL) { | ||
120 | // eslint-disable-next-line max-len | ||
121 | logger.warn('Emailer is disabled but signup approval is enabled: PeerTube will not be able to send an email to the user upon acceptance/rejection of the registration request') | ||
122 | } | ||
123 | |||
119 | if (CONFIG.CONTACT_FORM.ENABLED) { | 124 | if (CONFIG.CONTACT_FORM.ENABLED) { |
120 | logger.warn('Emailer is disabled so the contact form will not work.') | 125 | logger.warn('Emailer is disabled so the contact form will not work.') |
121 | } | 126 | } |
diff --git a/server/initializers/checker-before-init.ts b/server/initializers/checker-before-init.ts index 57852241c..8b4d49180 100644 --- a/server/initializers/checker-before-init.ts +++ b/server/initializers/checker-before-init.ts | |||
@@ -28,7 +28,7 @@ function checkMissedConfig () { | |||
28 | 'csp.enabled', 'csp.report_only', 'csp.report_uri', | 28 | 'csp.enabled', 'csp.report_only', 'csp.report_uri', |
29 | 'security.frameguard.enabled', | 29 | 'security.frameguard.enabled', |
30 | 'cache.previews.size', 'cache.captions.size', 'cache.torrents.size', 'admin.email', 'contact_form.enabled', | 30 | 'cache.previews.size', 'cache.captions.size', 'cache.torrents.size', 'admin.email', 'contact_form.enabled', |
31 | 'signup.enabled', 'signup.limit', 'signup.requires_email_verification', 'signup.minimum_age', | 31 | 'signup.enabled', 'signup.limit', 'signup.requires_approval', 'signup.requires_email_verification', 'signup.minimum_age', |
32 | 'signup.filters.cidr.whitelist', 'signup.filters.cidr.blacklist', | 32 | 'signup.filters.cidr.whitelist', 'signup.filters.cidr.blacklist', |
33 | 'redundancy.videos.strategies', 'redundancy.videos.check_interval', | 33 | 'redundancy.videos.strategies', 'redundancy.videos.check_interval', |
34 | 'transcoding.enabled', 'transcoding.threads', 'transcoding.allow_additional_extensions', 'transcoding.hls.enabled', | 34 | 'transcoding.enabled', 'transcoding.threads', 'transcoding.allow_additional_extensions', 'transcoding.hls.enabled', |
diff --git a/server/initializers/config.ts b/server/initializers/config.ts index 28aaf36a9..9685e7bfc 100644 --- a/server/initializers/config.ts +++ b/server/initializers/config.ts | |||
@@ -305,6 +305,7 @@ const CONFIG = { | |||
305 | }, | 305 | }, |
306 | SIGNUP: { | 306 | SIGNUP: { |
307 | get ENABLED () { return config.get<boolean>('signup.enabled') }, | 307 | get ENABLED () { return config.get<boolean>('signup.enabled') }, |
308 | get REQUIRES_APPROVAL () { return config.get<boolean>('signup.requires_approval') }, | ||
308 | get LIMIT () { return config.get<number>('signup.limit') }, | 309 | get LIMIT () { return config.get<number>('signup.limit') }, |
309 | get REQUIRES_EMAIL_VERIFICATION () { return config.get<boolean>('signup.requires_email_verification') }, | 310 | get REQUIRES_EMAIL_VERIFICATION () { return config.get<boolean>('signup.requires_email_verification') }, |
310 | get MINIMUM_AGE () { return config.get<number>('signup.minimum_age') }, | 311 | get MINIMUM_AGE () { return config.get<number>('signup.minimum_age') }, |
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 0dab524d9..2ef3da2e7 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts | |||
@@ -6,6 +6,7 @@ import { randomInt, root } from '@shared/core-utils' | |||
6 | import { | 6 | import { |
7 | AbuseState, | 7 | AbuseState, |
8 | JobType, | 8 | JobType, |
9 | UserRegistrationState, | ||
9 | VideoChannelSyncState, | 10 | VideoChannelSyncState, |
10 | VideoImportState, | 11 | VideoImportState, |
11 | VideoPrivacy, | 12 | VideoPrivacy, |
@@ -25,7 +26,7 @@ import { CONFIG, registerConfigChangedHandler } from './config' | |||
25 | 26 | ||
26 | // --------------------------------------------------------------------------- | 27 | // --------------------------------------------------------------------------- |
27 | 28 | ||
28 | const LAST_MIGRATION_VERSION = 745 | 29 | const LAST_MIGRATION_VERSION = 750 |
29 | 30 | ||
30 | // --------------------------------------------------------------------------- | 31 | // --------------------------------------------------------------------------- |
31 | 32 | ||
@@ -78,6 +79,8 @@ const SORTABLE_COLUMNS = { | |||
78 | ACCOUNT_FOLLOWERS: [ 'createdAt' ], | 79 | ACCOUNT_FOLLOWERS: [ 'createdAt' ], |
79 | CHANNEL_FOLLOWERS: [ 'createdAt' ], | 80 | CHANNEL_FOLLOWERS: [ 'createdAt' ], |
80 | 81 | ||
82 | USER_REGISTRATIONS: [ 'createdAt', 'state' ], | ||
83 | |||
81 | VIDEOS: [ 'name', 'duration', 'createdAt', 'publishedAt', 'originallyPublishedAt', 'views', 'likes', 'trending', 'hot', 'best' ], | 84 | VIDEOS: [ 'name', 'duration', 'createdAt', 'publishedAt', 'originallyPublishedAt', 'views', 'likes', 'trending', 'hot', 'best' ], |
82 | 85 | ||
83 | // Don't forget to update peertube-search-index with the same values | 86 | // Don't forget to update peertube-search-index with the same values |
@@ -290,6 +293,10 @@ const CONSTRAINTS_FIELDS = { | |||
290 | ABUSE_MESSAGES: { | 293 | ABUSE_MESSAGES: { |
291 | MESSAGE: { min: 2, max: 3000 } // Length | 294 | MESSAGE: { min: 2, max: 3000 } // Length |
292 | }, | 295 | }, |
296 | USER_REGISTRATIONS: { | ||
297 | REASON_MESSAGE: { min: 2, max: 3000 }, // Length | ||
298 | MODERATOR_MESSAGE: { min: 2, max: 3000 } // Length | ||
299 | }, | ||
293 | VIDEO_BLACKLIST: { | 300 | VIDEO_BLACKLIST: { |
294 | REASON: { min: 2, max: 300 } // Length | 301 | REASON: { min: 2, max: 300 } // Length |
295 | }, | 302 | }, |
@@ -516,6 +523,12 @@ const ABUSE_STATES: { [ id in AbuseState ]: string } = { | |||
516 | [AbuseState.ACCEPTED]: 'Accepted' | 523 | [AbuseState.ACCEPTED]: 'Accepted' |
517 | } | 524 | } |
518 | 525 | ||
526 | const USER_REGISTRATION_STATES: { [ id in UserRegistrationState ]: string } = { | ||
527 | [UserRegistrationState.PENDING]: 'Pending', | ||
528 | [UserRegistrationState.REJECTED]: 'Rejected', | ||
529 | [UserRegistrationState.ACCEPTED]: 'Accepted' | ||
530 | } | ||
531 | |||
519 | const VIDEO_PLAYLIST_PRIVACIES: { [ id in VideoPlaylistPrivacy ]: string } = { | 532 | const VIDEO_PLAYLIST_PRIVACIES: { [ id in VideoPlaylistPrivacy ]: string } = { |
520 | [VideoPlaylistPrivacy.PUBLIC]: 'Public', | 533 | [VideoPlaylistPrivacy.PUBLIC]: 'Public', |
521 | [VideoPlaylistPrivacy.UNLISTED]: 'Unlisted', | 534 | [VideoPlaylistPrivacy.UNLISTED]: 'Unlisted', |
@@ -660,7 +673,7 @@ const USER_PASSWORD_CREATE_LIFETIME = 60000 * 60 * 24 * 7 // 7 days | |||
660 | 673 | ||
661 | const TWO_FACTOR_AUTH_REQUEST_TOKEN_LIFETIME = 60000 * 10 // 10 minutes | 674 | const TWO_FACTOR_AUTH_REQUEST_TOKEN_LIFETIME = 60000 * 10 // 10 minutes |
662 | 675 | ||
663 | const USER_EMAIL_VERIFY_LIFETIME = 60000 * 60 // 60 minutes | 676 | const EMAIL_VERIFY_LIFETIME = 60000 * 60 // 60 minutes |
664 | 677 | ||
665 | const NSFW_POLICY_TYPES: { [ id: string ]: NSFWPolicyType } = { | 678 | const NSFW_POLICY_TYPES: { [ id: string ]: NSFWPolicyType } = { |
666 | DO_NOT_LIST: 'do_not_list', | 679 | DO_NOT_LIST: 'do_not_list', |
@@ -1069,13 +1082,14 @@ export { | |||
1069 | VIDEO_TRANSCODING_FPS, | 1082 | VIDEO_TRANSCODING_FPS, |
1070 | FFMPEG_NICE, | 1083 | FFMPEG_NICE, |
1071 | ABUSE_STATES, | 1084 | ABUSE_STATES, |
1085 | USER_REGISTRATION_STATES, | ||
1072 | LRU_CACHE, | 1086 | LRU_CACHE, |
1073 | REQUEST_TIMEOUTS, | 1087 | REQUEST_TIMEOUTS, |
1074 | MAX_LOCAL_VIEWER_WATCH_SECTIONS, | 1088 | MAX_LOCAL_VIEWER_WATCH_SECTIONS, |
1075 | USER_PASSWORD_RESET_LIFETIME, | 1089 | USER_PASSWORD_RESET_LIFETIME, |
1076 | USER_PASSWORD_CREATE_LIFETIME, | 1090 | USER_PASSWORD_CREATE_LIFETIME, |
1077 | MEMOIZE_TTL, | 1091 | MEMOIZE_TTL, |
1078 | USER_EMAIL_VERIFY_LIFETIME, | 1092 | EMAIL_VERIFY_LIFETIME, |
1079 | OVERVIEWS, | 1093 | OVERVIEWS, |
1080 | SCHEDULER_INTERVALS_MS, | 1094 | SCHEDULER_INTERVALS_MS, |
1081 | REPEAT_JOBS, | 1095 | REPEAT_JOBS, |
diff --git a/server/initializers/database.ts b/server/initializers/database.ts index f55f40df0..96145f489 100644 --- a/server/initializers/database.ts +++ b/server/initializers/database.ts | |||
@@ -5,7 +5,9 @@ import { TrackerModel } from '@server/models/server/tracker' | |||
5 | import { VideoTrackerModel } from '@server/models/server/video-tracker' | 5 | import { VideoTrackerModel } from '@server/models/server/video-tracker' |
6 | import { UserModel } from '@server/models/user/user' | 6 | import { UserModel } from '@server/models/user/user' |
7 | import { UserNotificationModel } from '@server/models/user/user-notification' | 7 | import { UserNotificationModel } from '@server/models/user/user-notification' |
8 | import { UserRegistrationModel } from '@server/models/user/user-registration' | ||
8 | import { UserVideoHistoryModel } from '@server/models/user/user-video-history' | 9 | import { UserVideoHistoryModel } from '@server/models/user/user-video-history' |
10 | import { VideoChannelSyncModel } from '@server/models/video/video-channel-sync' | ||
9 | import { VideoJobInfoModel } from '@server/models/video/video-job-info' | 11 | import { VideoJobInfoModel } from '@server/models/video/video-job-info' |
10 | import { VideoLiveSessionModel } from '@server/models/video/video-live-session' | 12 | import { VideoLiveSessionModel } from '@server/models/video/video-live-session' |
11 | import { VideoSourceModel } from '@server/models/video/video-source' | 13 | import { VideoSourceModel } from '@server/models/video/video-source' |
@@ -50,7 +52,6 @@ import { VideoStreamingPlaylistModel } from '../models/video/video-streaming-pla | |||
50 | import { VideoTagModel } from '../models/video/video-tag' | 52 | import { VideoTagModel } from '../models/video/video-tag' |
51 | import { VideoViewModel } from '../models/view/video-view' | 53 | import { VideoViewModel } from '../models/view/video-view' |
52 | import { CONFIG } from './config' | 54 | import { CONFIG } from './config' |
53 | import { VideoChannelSyncModel } from '@server/models/video/video-channel-sync' | ||
54 | 55 | ||
55 | require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string | 56 | require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string |
56 | 57 | ||
@@ -155,7 +156,8 @@ async function initDatabaseModels (silent: boolean) { | |||
155 | PluginModel, | 156 | PluginModel, |
156 | ActorCustomPageModel, | 157 | ActorCustomPageModel, |
157 | VideoJobInfoModel, | 158 | VideoJobInfoModel, |
158 | VideoChannelSyncModel | 159 | VideoChannelSyncModel, |
160 | UserRegistrationModel | ||
159 | ]) | 161 | ]) |
160 | 162 | ||
161 | // Check extensions exist in the database | 163 | // Check extensions exist in the database |
diff --git a/server/initializers/migrations/0750-user-registration.ts b/server/initializers/migrations/0750-user-registration.ts new file mode 100644 index 000000000..15bbfd3fd --- /dev/null +++ b/server/initializers/migrations/0750-user-registration.ts | |||
@@ -0,0 +1,58 @@ | |||
1 | |||
2 | import * as Sequelize from 'sequelize' | ||
3 | |||
4 | async function up (utils: { | ||
5 | transaction: Sequelize.Transaction | ||
6 | queryInterface: Sequelize.QueryInterface | ||
7 | sequelize: Sequelize.Sequelize | ||
8 | db: any | ||
9 | }): Promise<void> { | ||
10 | { | ||
11 | const query = ` | ||
12 | CREATE TABLE IF NOT EXISTS "userRegistration" ( | ||
13 | "id" serial, | ||
14 | "state" integer NOT NULL, | ||
15 | "registrationReason" text NOT NULL, | ||
16 | "moderationResponse" text, | ||
17 | "password" varchar(255), | ||
18 | "username" varchar(255) NOT NULL, | ||
19 | "email" varchar(400) NOT NULL, | ||
20 | "emailVerified" boolean, | ||
21 | "accountDisplayName" varchar(255), | ||
22 | "channelHandle" varchar(255), | ||
23 | "channelDisplayName" varchar(255), | ||
24 | "userId" integer REFERENCES "user" ("id") ON DELETE SET NULL ON UPDATE CASCADE, | ||
25 | "createdAt" timestamp with time zone NOT NULL, | ||
26 | "updatedAt" timestamp with time zone NOT NULL, | ||
27 | PRIMARY KEY ("id") | ||
28 | ); | ||
29 | ` | ||
30 | await utils.sequelize.query(query, { transaction: utils.transaction }) | ||
31 | } | ||
32 | |||
33 | { | ||
34 | await utils.queryInterface.addColumn('userNotification', 'userRegistrationId', { | ||
35 | type: Sequelize.INTEGER, | ||
36 | defaultValue: null, | ||
37 | allowNull: true, | ||
38 | references: { | ||
39 | model: 'userRegistration', | ||
40 | key: 'id' | ||
41 | }, | ||
42 | onUpdate: 'CASCADE', | ||
43 | onDelete: 'SET NULL' | ||
44 | }, { transaction: utils.transaction }) | ||
45 | } | ||
46 | } | ||
47 | |||
48 | async function down (utils: { | ||
49 | queryInterface: Sequelize.QueryInterface | ||
50 | transaction: Sequelize.Transaction | ||
51 | }) { | ||
52 | await utils.queryInterface.dropTable('videoChannelSync', { transaction: utils.transaction }) | ||
53 | } | ||
54 | |||
55 | export { | ||
56 | up, | ||
57 | down | ||
58 | } | ||