diff options
Diffstat (limited to 'server/initializers')
-rw-r--r-- | server/initializers/checker-after-init.ts | 15 | ||||
-rw-r--r-- | server/initializers/checker-before-init.ts | 10 | ||||
-rw-r--r-- | server/initializers/config.ts | 20 | ||||
-rw-r--r-- | server/initializers/constants.ts | 68 | ||||
-rw-r--r-- | server/initializers/installer.ts | 10 | ||||
-rw-r--r-- | server/initializers/migrations/0745-user-otp.ts | 29 |
6 files changed, 135 insertions, 17 deletions
diff --git a/server/initializers/checker-after-init.ts b/server/initializers/checker-after-init.ts index 42839d1c9..09e878eee 100644 --- a/server/initializers/checker-after-init.ts +++ b/server/initializers/checker-after-init.ts | |||
@@ -42,6 +42,7 @@ function checkConfig () { | |||
42 | logger.warn('services.csp-logger configuration has been renamed to csp.report_uri. Please update your configuration file.') | 42 | logger.warn('services.csp-logger configuration has been renamed to csp.report_uri. Please update your configuration file.') |
43 | } | 43 | } |
44 | 44 | ||
45 | checkSecretsConfig() | ||
45 | checkEmailConfig() | 46 | checkEmailConfig() |
46 | checkNSFWPolicyConfig() | 47 | checkNSFWPolicyConfig() |
47 | checkLocalRedundancyConfig() | 48 | checkLocalRedundancyConfig() |
@@ -103,6 +104,12 @@ export { | |||
103 | 104 | ||
104 | // --------------------------------------------------------------------------- | 105 | // --------------------------------------------------------------------------- |
105 | 106 | ||
107 | function checkSecretsConfig () { | ||
108 | if (!CONFIG.SECRETS.PEERTUBE) { | ||
109 | throw new Error('secrets.peertube is missing in config. Generate one using `openssl rand -hex 32`') | ||
110 | } | ||
111 | } | ||
112 | |||
106 | function checkEmailConfig () { | 113 | function checkEmailConfig () { |
107 | if (!isEmailEnabled()) { | 114 | if (!isEmailEnabled()) { |
108 | if (CONFIG.SIGNUP.ENABLED && CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION) { | 115 | if (CONFIG.SIGNUP.ENABLED && CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION) { |
@@ -271,6 +278,14 @@ function checkObjectStorageConfig () { | |||
271 | 'Object storage bucket prefixes should be set to different values when the same bucket is used for both types of video.' | 278 | 'Object storage bucket prefixes should be set to different values when the same bucket is used for both types of video.' |
272 | ) | 279 | ) |
273 | } | 280 | } |
281 | |||
282 | if (!CONFIG.OBJECT_STORAGE.UPLOAD_ACL.PUBLIC) { | ||
283 | throw new Error('object_storage.upload_acl.public must be set') | ||
284 | } | ||
285 | |||
286 | if (!CONFIG.OBJECT_STORAGE.UPLOAD_ACL.PRIVATE) { | ||
287 | throw new Error('object_storage.upload_acl.private must be set') | ||
288 | } | ||
274 | } | 289 | } |
275 | } | 290 | } |
276 | 291 | ||
diff --git a/server/initializers/checker-before-init.ts b/server/initializers/checker-before-init.ts index 3188903be..42be7ee6e 100644 --- a/server/initializers/checker-before-init.ts +++ b/server/initializers/checker-before-init.ts | |||
@@ -11,12 +11,13 @@ const config: IConfig = require('config') | |||
11 | function checkMissedConfig () { | 11 | function checkMissedConfig () { |
12 | const required = [ 'listen.port', 'listen.hostname', | 12 | const required = [ 'listen.port', 'listen.hostname', |
13 | 'webserver.https', 'webserver.hostname', 'webserver.port', | 13 | 'webserver.https', 'webserver.hostname', 'webserver.port', |
14 | 'secrets.peertube', | ||
14 | 'trust_proxy', | 15 | 'trust_proxy', |
15 | 'database.hostname', 'database.port', 'database.username', 'database.password', 'database.pool.max', | 16 | 'database.hostname', 'database.port', 'database.username', 'database.password', 'database.pool.max', |
16 | 'smtp.hostname', 'smtp.port', 'smtp.username', 'smtp.password', 'smtp.tls', 'smtp.from_address', | 17 | 'smtp.hostname', 'smtp.port', 'smtp.username', 'smtp.password', 'smtp.tls', 'smtp.from_address', |
17 | 'email.body.signature', 'email.subject.prefix', | 18 | 'email.body.signature', 'email.subject.prefix', |
18 | 'storage.avatars', 'storage.videos', 'storage.logs', 'storage.previews', 'storage.thumbnails', 'storage.torrents', 'storage.cache', | 19 | 'storage.avatars', 'storage.videos', 'storage.logs', 'storage.previews', 'storage.thumbnails', 'storage.torrents', 'storage.cache', |
19 | 'storage.redundancy', 'storage.tmp', 'storage.streaming_playlists', 'storage.plugins', | 20 | 'storage.redundancy', 'storage.tmp', 'storage.streaming_playlists', 'storage.plugins', 'storage.well_known', |
20 | 'log.level', | 21 | 'log.level', |
21 | 'user.video_quota', 'user.video_quota_daily', | 22 | 'user.video_quota', 'user.video_quota_daily', |
22 | 'video_channels.max_per_user', | 23 | 'video_channels.max_per_user', |
@@ -34,6 +35,7 @@ function checkMissedConfig () { | |||
34 | 'import.videos.http.enabled', 'import.videos.torrent.enabled', 'import.videos.concurrency', 'import.videos.timeout', | 35 | 'import.videos.http.enabled', 'import.videos.torrent.enabled', 'import.videos.concurrency', 'import.videos.timeout', |
35 | 'import.video_channel_synchronization.enabled', 'import.video_channel_synchronization.max_per_user', | 36 | 'import.video_channel_synchronization.enabled', 'import.video_channel_synchronization.max_per_user', |
36 | 'import.video_channel_synchronization.check_interval', 'import.video_channel_synchronization.videos_limit_per_synchronization', | 37 | 'import.video_channel_synchronization.check_interval', 'import.video_channel_synchronization.videos_limit_per_synchronization', |
38 | 'import.video_channel_synchronization.full_sync_videos_limit', | ||
37 | 'auto_blacklist.videos.of_users.enabled', 'trending.videos.interval_days', | 39 | 'auto_blacklist.videos.of_users.enabled', 'trending.videos.interval_days', |
38 | 'client.videos.miniature.display_author_avatar', | 40 | 'client.videos.miniature.display_author_avatar', |
39 | 'client.videos.miniature.prefer_author_display_name', 'client.menu.login.redirect_on_single_external_auth', | 41 | 'client.videos.miniature.prefer_author_display_name', 'client.menu.login.redirect_on_single_external_auth', |
@@ -45,6 +47,12 @@ function checkMissedConfig () { | |||
45 | 'tracker.enabled', 'tracker.private', 'tracker.reject_too_many_announces', | 47 | 'tracker.enabled', 'tracker.private', 'tracker.reject_too_many_announces', |
46 | 'history.videos.max_age', 'views.videos.remote.max_age', 'views.videos.local_buffer_update_interval', 'views.videos.ip_view_expiration', | 48 | 'history.videos.max_age', 'views.videos.remote.max_age', 'views.videos.local_buffer_update_interval', 'views.videos.ip_view_expiration', |
47 | 'rates_limit.login.window', 'rates_limit.login.max', 'rates_limit.ask_send_email.window', 'rates_limit.ask_send_email.max', | 49 | 'rates_limit.login.window', 'rates_limit.login.max', 'rates_limit.ask_send_email.window', 'rates_limit.ask_send_email.max', |
50 | 'static_files.private_files_require_auth', | ||
51 | 'object_storage.enabled', 'object_storage.endpoint', 'object_storage.region', 'object_storage.upload_acl.public', | ||
52 | 'object_storage.upload_acl.private', 'object_storage.proxy.proxify_private_files', 'object_storage.credentials.access_key_id', | ||
53 | 'object_storage.credentials.secret_access_key', 'object_storage.max_upload_part', 'object_storage.streaming_playlists.bucket_name', | ||
54 | 'object_storage.streaming_playlists.prefix', 'object_storage.streaming_playlists.base_url', 'object_storage.videos.bucket_name', | ||
55 | 'object_storage.videos.prefix', 'object_storage.videos.base_url', | ||
48 | 'theme.default', | 56 | 'theme.default', |
49 | 'feeds.videos.count', 'feeds.comments.count', | 57 | 'feeds.videos.count', 'feeds.comments.count', |
50 | 'geo_ip.enabled', 'geo_ip.country.database_url', | 58 | 'geo_ip.enabled', 'geo_ip.country.database_url', |
diff --git a/server/initializers/config.ts b/server/initializers/config.ts index 2c92bea22..3dd1f6971 100644 --- a/server/initializers/config.ts +++ b/server/initializers/config.ts | |||
@@ -20,6 +20,9 @@ const CONFIG = { | |||
20 | PORT: config.get<number>('listen.port'), | 20 | PORT: config.get<number>('listen.port'), |
21 | HOSTNAME: config.get<string>('listen.hostname') | 21 | HOSTNAME: config.get<string>('listen.hostname') |
22 | }, | 22 | }, |
23 | SECRETS: { | ||
24 | PEERTUBE: config.get<string>('secrets.peertube') | ||
25 | }, | ||
23 | DATABASE: { | 26 | DATABASE: { |
24 | DBNAME: config.has('database.name') ? config.get<string>('database.name') : 'peertube' + config.get<string>('database.suffix'), | 27 | DBNAME: config.has('database.name') ? config.get<string>('database.name') : 'peertube' + config.get<string>('database.suffix'), |
25 | HOSTNAME: config.get<string>('database.hostname'), | 28 | HOSTNAME: config.get<string>('database.hostname'), |
@@ -107,18 +110,28 @@ const CONFIG = { | |||
107 | TORRENTS_DIR: buildPath(config.get<string>('storage.torrents')), | 110 | TORRENTS_DIR: buildPath(config.get<string>('storage.torrents')), |
108 | CACHE_DIR: buildPath(config.get<string>('storage.cache')), | 111 | CACHE_DIR: buildPath(config.get<string>('storage.cache')), |
109 | PLUGINS_DIR: buildPath(config.get<string>('storage.plugins')), | 112 | PLUGINS_DIR: buildPath(config.get<string>('storage.plugins')), |
110 | CLIENT_OVERRIDES_DIR: buildPath(config.get<string>('storage.client_overrides')) | 113 | CLIENT_OVERRIDES_DIR: buildPath(config.get<string>('storage.client_overrides')), |
114 | WELL_KNOWN_DIR: buildPath(config.get<string>('storage.well_known')) | ||
115 | }, | ||
116 | STATIC_FILES: { | ||
117 | PRIVATE_FILES_REQUIRE_AUTH: config.get<boolean>('static_files.private_files_require_auth') | ||
111 | }, | 118 | }, |
112 | OBJECT_STORAGE: { | 119 | OBJECT_STORAGE: { |
113 | ENABLED: config.get<boolean>('object_storage.enabled'), | 120 | ENABLED: config.get<boolean>('object_storage.enabled'), |
114 | MAX_UPLOAD_PART: bytes.parse(config.get<string>('object_storage.max_upload_part')), | 121 | MAX_UPLOAD_PART: bytes.parse(config.get<string>('object_storage.max_upload_part')), |
115 | ENDPOINT: config.get<string>('object_storage.endpoint'), | 122 | ENDPOINT: config.get<string>('object_storage.endpoint'), |
116 | REGION: config.get<string>('object_storage.region'), | 123 | REGION: config.get<string>('object_storage.region'), |
117 | UPLOAD_ACL: config.get<string>('object_storage.upload_acl'), | 124 | UPLOAD_ACL: { |
125 | PUBLIC: config.get<string>('object_storage.upload_acl.public'), | ||
126 | PRIVATE: config.get<string>('object_storage.upload_acl.private') | ||
127 | }, | ||
118 | CREDENTIALS: { | 128 | CREDENTIALS: { |
119 | ACCESS_KEY_ID: config.get<string>('object_storage.credentials.access_key_id'), | 129 | ACCESS_KEY_ID: config.get<string>('object_storage.credentials.access_key_id'), |
120 | SECRET_ACCESS_KEY: config.get<string>('object_storage.credentials.secret_access_key') | 130 | SECRET_ACCESS_KEY: config.get<string>('object_storage.credentials.secret_access_key') |
121 | }, | 131 | }, |
132 | PROXY: { | ||
133 | PROXIFY_PRIVATE_FILES: config.get<boolean>('object_storage.proxy.proxify_private_files') | ||
134 | }, | ||
122 | VIDEOS: { | 135 | VIDEOS: { |
123 | BUCKET_NAME: config.get<string>('object_storage.videos.bucket_name'), | 136 | BUCKET_NAME: config.get<string>('object_storage.videos.bucket_name'), |
124 | PREFIX: config.get<string>('object_storage.videos.prefix'), | 137 | PREFIX: config.get<string>('object_storage.videos.prefix'), |
@@ -405,6 +418,9 @@ const CONFIG = { | |||
405 | get CHECK_INTERVAL () { return parseDurationToMs(config.get<string>('import.video_channel_synchronization.check_interval')) }, | 418 | get CHECK_INTERVAL () { return parseDurationToMs(config.get<string>('import.video_channel_synchronization.check_interval')) }, |
406 | get VIDEOS_LIMIT_PER_SYNCHRONIZATION () { | 419 | get VIDEOS_LIMIT_PER_SYNCHRONIZATION () { |
407 | return config.get<number>('import.video_channel_synchronization.videos_limit_per_synchronization') | 420 | return config.get<number>('import.video_channel_synchronization.videos_limit_per_synchronization') |
421 | }, | ||
422 | get FULL_SYNC_VIDEOS_LIMIT () { | ||
423 | return config.get<number>('import.video_channel_synchronization.full_sync_videos_limit') | ||
408 | } | 424 | } |
409 | } | 425 | } |
410 | }, | 426 | }, |
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 7039ab457..66eb31230 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import { RepeatOptions } from 'bullmq' | 1 | import { RepeatOptions } from 'bullmq' |
2 | import { randomBytes } from 'crypto' | 2 | import { Encoding, randomBytes } from 'crypto' |
3 | import { invert } from 'lodash' | 3 | import { invert } from 'lodash' |
4 | import { join } from 'path' | 4 | import { join } from 'path' |
5 | import { randomInt, root } from '@shared/core-utils' | 5 | import { randomInt, root } from '@shared/core-utils' |
@@ -25,7 +25,7 @@ import { CONFIG, registerConfigChangedHandler } from './config' | |||
25 | 25 | ||
26 | // --------------------------------------------------------------------------- | 26 | // --------------------------------------------------------------------------- |
27 | 27 | ||
28 | const LAST_MIGRATION_VERSION = 740 | 28 | const LAST_MIGRATION_VERSION = 745 |
29 | 29 | ||
30 | // --------------------------------------------------------------------------- | 30 | // --------------------------------------------------------------------------- |
31 | 31 | ||
@@ -116,7 +116,8 @@ const ROUTE_CACHE_LIFETIME = { | |||
116 | ACTIVITY_PUB: { | 116 | ACTIVITY_PUB: { |
117 | VIDEOS: '1 second' // 1 second, cache concurrent requests after a broadcast for example | 117 | VIDEOS: '1 second' // 1 second, cache concurrent requests after a broadcast for example |
118 | }, | 118 | }, |
119 | STATS: '4 hours' | 119 | STATS: '4 hours', |
120 | WELL_KNOWN: '1 day' | ||
120 | } | 121 | } |
121 | 122 | ||
122 | // --------------------------------------------------------------------------- | 123 | // --------------------------------------------------------------------------- |
@@ -636,9 +637,18 @@ let PRIVATE_RSA_KEY_SIZE = 2048 | |||
636 | // Password encryption | 637 | // Password encryption |
637 | const BCRYPT_SALT_SIZE = 10 | 638 | const BCRYPT_SALT_SIZE = 10 |
638 | 639 | ||
640 | const ENCRYPTION = { | ||
641 | ALGORITHM: 'aes-256-cbc', | ||
642 | IV: 16, | ||
643 | SALT: 'peertube', | ||
644 | ENCODING: 'hex' as Encoding | ||
645 | } | ||
646 | |||
639 | const USER_PASSWORD_RESET_LIFETIME = 60000 * 60 // 60 minutes | 647 | const USER_PASSWORD_RESET_LIFETIME = 60000 * 60 // 60 minutes |
640 | const USER_PASSWORD_CREATE_LIFETIME = 60000 * 60 * 24 * 7 // 7 days | 648 | const USER_PASSWORD_CREATE_LIFETIME = 60000 * 60 * 24 * 7 // 7 days |
641 | 649 | ||
650 | const TWO_FACTOR_AUTH_REQUEST_TOKEN_LIFETIME = 60000 * 10 // 10 minutes | ||
651 | |||
642 | const USER_EMAIL_VERIFY_LIFETIME = 60000 * 60 // 60 minutes | 652 | const USER_EMAIL_VERIFY_LIFETIME = 60000 * 60 // 60 minutes |
643 | 653 | ||
644 | const NSFW_POLICY_TYPES: { [ id: string ]: NSFWPolicyType } = { | 654 | const NSFW_POLICY_TYPES: { [ id: string ]: NSFWPolicyType } = { |
@@ -652,10 +662,15 @@ const NSFW_POLICY_TYPES: { [ id: string ]: NSFWPolicyType } = { | |||
652 | // Express static paths (router) | 662 | // Express static paths (router) |
653 | const STATIC_PATHS = { | 663 | const STATIC_PATHS = { |
654 | THUMBNAILS: '/static/thumbnails/', | 664 | THUMBNAILS: '/static/thumbnails/', |
665 | |||
655 | WEBSEED: '/static/webseed/', | 666 | WEBSEED: '/static/webseed/', |
667 | PRIVATE_WEBSEED: '/static/webseed/private/', | ||
668 | |||
656 | REDUNDANCY: '/static/redundancy/', | 669 | REDUNDANCY: '/static/redundancy/', |
670 | |||
657 | STREAMING_PLAYLISTS: { | 671 | STREAMING_PLAYLISTS: { |
658 | HLS: '/static/streaming-playlists/hls' | 672 | HLS: '/static/streaming-playlists/hls', |
673 | PRIVATE_HLS: '/static/streaming-playlists/hls/private/' | ||
659 | } | 674 | } |
660 | } | 675 | } |
661 | const STATIC_DOWNLOAD_PATHS = { | 676 | const STATIC_DOWNLOAD_PATHS = { |
@@ -670,6 +685,13 @@ const LAZY_STATIC_PATHS = { | |||
670 | VIDEO_CAPTIONS: '/lazy-static/video-captions/', | 685 | VIDEO_CAPTIONS: '/lazy-static/video-captions/', |
671 | TORRENTS: '/lazy-static/torrents/' | 686 | TORRENTS: '/lazy-static/torrents/' |
672 | } | 687 | } |
688 | const OBJECT_STORAGE_PROXY_PATHS = { | ||
689 | PRIVATE_WEBSEED: '/object-storage-proxy/webseed/private/', | ||
690 | |||
691 | STREAMING_PLAYLISTS: { | ||
692 | PRIVATE_HLS: '/object-storage-proxy/streaming-playlists/hls/private/' | ||
693 | } | ||
694 | } | ||
673 | 695 | ||
674 | // Cache control | 696 | // Cache control |
675 | const STATIC_MAX_AGE = { | 697 | const STATIC_MAX_AGE = { |
@@ -735,12 +757,32 @@ const LRU_CACHE = { | |||
735 | }, | 757 | }, |
736 | ACTOR_IMAGE_STATIC: { | 758 | ACTOR_IMAGE_STATIC: { |
737 | MAX_SIZE: 500 | 759 | MAX_SIZE: 500 |
760 | }, | ||
761 | STATIC_VIDEO_FILES_RIGHTS_CHECK: { | ||
762 | MAX_SIZE: 5000, | ||
763 | TTL: parseDurationToMs('10 seconds') | ||
764 | }, | ||
765 | VIDEO_TOKENS: { | ||
766 | MAX_SIZE: 100_000, | ||
767 | TTL: parseDurationToMs('8 hours') | ||
738 | } | 768 | } |
739 | } | 769 | } |
740 | 770 | ||
741 | const RESUMABLE_UPLOAD_DIRECTORY = join(CONFIG.STORAGE.TMP_DIR, 'resumable-uploads') | 771 | const DIRECTORIES = { |
742 | const HLS_STREAMING_PLAYLIST_DIRECTORY = join(CONFIG.STORAGE.STREAMING_PLAYLISTS_DIR, 'hls') | 772 | RESUMABLE_UPLOAD: join(CONFIG.STORAGE.TMP_DIR, 'resumable-uploads'), |
743 | const HLS_REDUNDANCY_DIRECTORY = join(CONFIG.STORAGE.REDUNDANCY_DIR, 'hls') | 773 | |
774 | HLS_STREAMING_PLAYLIST: { | ||
775 | PUBLIC: join(CONFIG.STORAGE.STREAMING_PLAYLISTS_DIR, 'hls'), | ||
776 | PRIVATE: join(CONFIG.STORAGE.STREAMING_PLAYLISTS_DIR, 'hls', 'private') | ||
777 | }, | ||
778 | |||
779 | VIDEOS: { | ||
780 | PUBLIC: CONFIG.STORAGE.VIDEOS_DIR, | ||
781 | PRIVATE: join(CONFIG.STORAGE.VIDEOS_DIR, 'private') | ||
782 | }, | ||
783 | |||
784 | HLS_REDUNDANCY: join(CONFIG.STORAGE.REDUNDANCY_DIR, 'hls') | ||
785 | } | ||
744 | 786 | ||
745 | const RESUMABLE_UPLOAD_SESSION_LIFETIME = SCHEDULER_INTERVALS_MS.REMOVE_DANGLING_RESUMABLE_UPLOADS | 787 | const RESUMABLE_UPLOAD_SESSION_LIFETIME = SCHEDULER_INTERVALS_MS.REMOVE_DANGLING_RESUMABLE_UPLOADS |
746 | 788 | ||
@@ -804,6 +846,10 @@ const REDUNDANCY = { | |||
804 | } | 846 | } |
805 | 847 | ||
806 | const ACCEPT_HEADERS = [ 'html', 'application/json' ].concat(ACTIVITY_PUB.POTENTIAL_ACCEPT_HEADERS) | 848 | const ACCEPT_HEADERS = [ 'html', 'application/json' ].concat(ACTIVITY_PUB.POTENTIAL_ACCEPT_HEADERS) |
849 | const OTP = { | ||
850 | HEADER_NAME: 'x-peertube-otp', | ||
851 | HEADER_REQUIRED_VALUE: 'required; app' | ||
852 | } | ||
807 | 853 | ||
808 | const ASSETS_PATH = { | 854 | const ASSETS_PATH = { |
809 | DEFAULT_AUDIO_BACKGROUND: join(root(), 'dist', 'server', 'assets', 'default-audio-background.jpg'), | 855 | DEFAULT_AUDIO_BACKGROUND: join(root(), 'dist', 'server', 'assets', 'default-audio-background.jpg'), |
@@ -952,13 +998,14 @@ const VIDEO_FILTERS = { | |||
952 | export { | 998 | export { |
953 | WEBSERVER, | 999 | WEBSERVER, |
954 | API_VERSION, | 1000 | API_VERSION, |
1001 | ENCRYPTION, | ||
955 | VIDEO_LIVE, | 1002 | VIDEO_LIVE, |
956 | PEERTUBE_VERSION, | 1003 | PEERTUBE_VERSION, |
957 | LAZY_STATIC_PATHS, | 1004 | LAZY_STATIC_PATHS, |
1005 | OBJECT_STORAGE_PROXY_PATHS, | ||
958 | SEARCH_INDEX, | 1006 | SEARCH_INDEX, |
959 | RESUMABLE_UPLOAD_DIRECTORY, | 1007 | DIRECTORIES, |
960 | RESUMABLE_UPLOAD_SESSION_LIFETIME, | 1008 | RESUMABLE_UPLOAD_SESSION_LIFETIME, |
961 | HLS_REDUNDANCY_DIRECTORY, | ||
962 | P2P_MEDIA_LOADER_PEER_VERSION, | 1009 | P2P_MEDIA_LOADER_PEER_VERSION, |
963 | ACTOR_IMAGES_SIZE, | 1010 | ACTOR_IMAGES_SIZE, |
964 | ACCEPT_HEADERS, | 1011 | ACCEPT_HEADERS, |
@@ -985,13 +1032,13 @@ export { | |||
985 | FOLLOW_STATES, | 1032 | FOLLOW_STATES, |
986 | DEFAULT_USER_THEME_NAME, | 1033 | DEFAULT_USER_THEME_NAME, |
987 | SERVER_ACTOR_NAME, | 1034 | SERVER_ACTOR_NAME, |
1035 | TWO_FACTOR_AUTH_REQUEST_TOKEN_LIFETIME, | ||
988 | PLUGIN_GLOBAL_CSS_FILE_NAME, | 1036 | PLUGIN_GLOBAL_CSS_FILE_NAME, |
989 | PLUGIN_GLOBAL_CSS_PATH, | 1037 | PLUGIN_GLOBAL_CSS_PATH, |
990 | PRIVATE_RSA_KEY_SIZE, | 1038 | PRIVATE_RSA_KEY_SIZE, |
991 | VIDEO_FILTERS, | 1039 | VIDEO_FILTERS, |
992 | ROUTE_CACHE_LIFETIME, | 1040 | ROUTE_CACHE_LIFETIME, |
993 | SORTABLE_COLUMNS, | 1041 | SORTABLE_COLUMNS, |
994 | HLS_STREAMING_PLAYLIST_DIRECTORY, | ||
995 | JOB_TTL, | 1042 | JOB_TTL, |
996 | DEFAULT_THEME_NAME, | 1043 | DEFAULT_THEME_NAME, |
997 | NSFW_POLICY_TYPES, | 1044 | NSFW_POLICY_TYPES, |
@@ -1040,6 +1087,7 @@ export { | |||
1040 | PLUGIN_EXTERNAL_AUTH_TOKEN_LIFETIME, | 1087 | PLUGIN_EXTERNAL_AUTH_TOKEN_LIFETIME, |
1041 | ASSETS_PATH, | 1088 | ASSETS_PATH, |
1042 | FILES_CONTENT_HASH, | 1089 | FILES_CONTENT_HASH, |
1090 | OTP, | ||
1043 | loadLanguages, | 1091 | loadLanguages, |
1044 | buildLanguages, | 1092 | buildLanguages, |
1045 | generateContentHash | 1093 | generateContentHash |
diff --git a/server/initializers/installer.ts b/server/initializers/installer.ts index b02be9567..f5d8eedf1 100644 --- a/server/initializers/installer.ts +++ b/server/initializers/installer.ts | |||
@@ -10,7 +10,7 @@ import { ApplicationModel } from '../models/application/application' | |||
10 | import { OAuthClientModel } from '../models/oauth/oauth-client' | 10 | import { OAuthClientModel } from '../models/oauth/oauth-client' |
11 | import { applicationExist, clientsExist, usersExist } from './checker-after-init' | 11 | import { applicationExist, clientsExist, usersExist } from './checker-after-init' |
12 | import { CONFIG } from './config' | 12 | import { CONFIG } from './config' |
13 | import { FILES_CACHE, HLS_STREAMING_PLAYLIST_DIRECTORY, LAST_MIGRATION_VERSION, RESUMABLE_UPLOAD_DIRECTORY } from './constants' | 13 | import { DIRECTORIES, FILES_CACHE, LAST_MIGRATION_VERSION } from './constants' |
14 | import { sequelizeTypescript } from './database' | 14 | import { sequelizeTypescript } from './database' |
15 | 15 | ||
16 | async function installApplication () { | 16 | async function installApplication () { |
@@ -92,11 +92,13 @@ function createDirectoriesIfNotExist () { | |||
92 | tasks.push(ensureDir(dir)) | 92 | tasks.push(ensureDir(dir)) |
93 | } | 93 | } |
94 | 94 | ||
95 | // Playlist directories | 95 | tasks.push(ensureDir(DIRECTORIES.HLS_STREAMING_PLAYLIST.PRIVATE)) |
96 | tasks.push(ensureDir(HLS_STREAMING_PLAYLIST_DIRECTORY)) | 96 | tasks.push(ensureDir(DIRECTORIES.HLS_STREAMING_PLAYLIST.PUBLIC)) |
97 | tasks.push(ensureDir(DIRECTORIES.VIDEOS.PUBLIC)) | ||
98 | tasks.push(ensureDir(DIRECTORIES.VIDEOS.PRIVATE)) | ||
97 | 99 | ||
98 | // Resumable upload directory | 100 | // Resumable upload directory |
99 | tasks.push(ensureDir(RESUMABLE_UPLOAD_DIRECTORY)) | 101 | tasks.push(ensureDir(DIRECTORIES.RESUMABLE_UPLOAD)) |
100 | 102 | ||
101 | return Promise.all(tasks) | 103 | return Promise.all(tasks) |
102 | } | 104 | } |
diff --git a/server/initializers/migrations/0745-user-otp.ts b/server/initializers/migrations/0745-user-otp.ts new file mode 100644 index 000000000..157308ea1 --- /dev/null +++ b/server/initializers/migrations/0745-user-otp.ts | |||
@@ -0,0 +1,29 @@ | |||
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 | db: any | ||
8 | }): Promise<void> { | ||
9 | const { transaction } = utils | ||
10 | |||
11 | const data = { | ||
12 | type: Sequelize.STRING, | ||
13 | defaultValue: null, | ||
14 | allowNull: true | ||
15 | } | ||
16 | await utils.queryInterface.addColumn('user', 'otpSecret', data, { transaction }) | ||
17 | |||
18 | } | ||
19 | |||
20 | async function down (utils: { | ||
21 | queryInterface: Sequelize.QueryInterface | ||
22 | transaction: Sequelize.Transaction | ||
23 | }) { | ||
24 | } | ||
25 | |||
26 | export { | ||
27 | up, | ||
28 | down | ||
29 | } | ||