aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/initializers
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2023-01-19 09:27:16 +0100
committerChocobozzz <chocobozzz@cpy.re>2023-01-19 13:53:40 +0100
commite364e31e25bd1d4b8d801c845a96d6be708f0a18 (patch)
tree220785a42af361706eb8243960c5da9cddf4d2be /server/initializers
parentbc48e33b80f357767b98c1d310b04bdda24c6d46 (diff)
downloadPeerTube-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.ts5
-rw-r--r--server/initializers/checker-before-init.ts2
-rw-r--r--server/initializers/config.ts1
-rw-r--r--server/initializers/constants.ts20
-rw-r--r--server/initializers/database.ts6
-rw-r--r--server/initializers/migrations/0750-user-registration.ts58
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'
6import { 6import {
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
28const LAST_MIGRATION_VERSION = 745 29const 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
526const USER_REGISTRATION_STATES: { [ id in UserRegistrationState ]: string } = {
527 [UserRegistrationState.PENDING]: 'Pending',
528 [UserRegistrationState.REJECTED]: 'Rejected',
529 [UserRegistrationState.ACCEPTED]: 'Accepted'
530}
531
519const VIDEO_PLAYLIST_PRIVACIES: { [ id in VideoPlaylistPrivacy ]: string } = { 532const 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
661const TWO_FACTOR_AUTH_REQUEST_TOKEN_LIFETIME = 60000 * 10 // 10 minutes 674const TWO_FACTOR_AUTH_REQUEST_TOKEN_LIFETIME = 60000 * 10 // 10 minutes
662 675
663const USER_EMAIL_VERIFY_LIFETIME = 60000 * 60 // 60 minutes 676const EMAIL_VERIFY_LIFETIME = 60000 * 60 // 60 minutes
664 677
665const NSFW_POLICY_TYPES: { [ id: string ]: NSFWPolicyType } = { 678const 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'
5import { VideoTrackerModel } from '@server/models/server/video-tracker' 5import { VideoTrackerModel } from '@server/models/server/video-tracker'
6import { UserModel } from '@server/models/user/user' 6import { UserModel } from '@server/models/user/user'
7import { UserNotificationModel } from '@server/models/user/user-notification' 7import { UserNotificationModel } from '@server/models/user/user-notification'
8import { UserRegistrationModel } from '@server/models/user/user-registration'
8import { UserVideoHistoryModel } from '@server/models/user/user-video-history' 9import { UserVideoHistoryModel } from '@server/models/user/user-video-history'
10import { VideoChannelSyncModel } from '@server/models/video/video-channel-sync'
9import { VideoJobInfoModel } from '@server/models/video/video-job-info' 11import { VideoJobInfoModel } from '@server/models/video/video-job-info'
10import { VideoLiveSessionModel } from '@server/models/video/video-live-session' 12import { VideoLiveSessionModel } from '@server/models/video/video-live-session'
11import { VideoSourceModel } from '@server/models/video/video-source' 13import { VideoSourceModel } from '@server/models/video/video-source'
@@ -50,7 +52,6 @@ import { VideoStreamingPlaylistModel } from '../models/video/video-streaming-pla
50import { VideoTagModel } from '../models/video/video-tag' 52import { VideoTagModel } from '../models/video/video-tag'
51import { VideoViewModel } from '../models/view/video-view' 53import { VideoViewModel } from '../models/view/video-view'
52import { CONFIG } from './config' 54import { CONFIG } from './config'
53import { VideoChannelSyncModel } from '@server/models/video/video-channel-sync'
54 55
55require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string 56require('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
2import * as Sequelize from 'sequelize'
3
4async 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
48async function down (utils: {
49 queryInterface: Sequelize.QueryInterface
50 transaction: Sequelize.Transaction
51}) {
52 await utils.queryInterface.dropTable('videoChannelSync', { transaction: utils.transaction })
53}
54
55export {
56 up,
57 down
58}