diff --git a/client/src/app/shared/shared-user-settings/user-video-settings.component.html b/client/src/app/shared/shared-user-settings/user-video-settings.component.html index e069463e4..9ea1a5abe 100644 --- a/client/src/app/shared/shared-user-settings/user-video-settings.component.html +++ b/client/src/app/shared/shared-user-settings/user-video-settings.component.html @@ -1,42 +1,61 @@
-
+
+
-
- -
+ @if (isNsfwFlagsEnabled()) { +
+ +
-
- -
+
+ +
-
- -
+
+ +
+ }
-
+
+
@@ -53,21 +72,18 @@
- + - The sharing system implies that some technical information about your system (such as a public IP address) can be sent to other peers, but greatly helps to reduce server load. + The sharing system implies + that some technical information about your system (such as a public IP address) can be sent to other peers, but greatly helps to reduce server + load.
- + When on a video page, directly start playing the video. @@ -76,8 +92,10 @@
When a video ends, follow up with the next suggested video. diff --git a/client/src/app/shared/shared-user-settings/user-video-settings.component.ts b/client/src/app/shared/shared-user-settings/user-video-settings.component.ts index ba92acc78..773605467 100644 --- a/client/src/app/shared/shared-user-settings/user-video-settings.component.ts +++ b/client/src/app/shared/shared-user-settings/user-video-settings.component.ts @@ -204,6 +204,10 @@ export class UserVideoSettingsComponent implements OnInit, OnDestroy { return this.updateAnonymousProfile(details) } + isNsfwFlagsEnabled () { + return this.serverService.getHTMLConfig().nsfwFlagsSettings.enabled + } + private handleReactiveUpdate () { let oldForm = { ...this.form.value } diff --git a/config/default.yaml b/config/default.yaml index 55b2660da..a9f90d933 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -533,6 +533,11 @@ webrtc: - 'stun:stunserver2024.stunprotocol.org' - 'stun:stun.framasoft.org' +nsfw_flags_settings: + # Allow logged-in/anonymous users to have a more granular control over their NSFW policy + # using NSFW flags (violent content, etc.) set by video authors + enabled: true + cache: previews: size: 500 # Max number of previews you want to cache diff --git a/config/production.yaml.example b/config/production.yaml.example index 4820332d3..7f96f0082 100644 --- a/config/production.yaml.example +++ b/config/production.yaml.example @@ -531,6 +531,11 @@ webrtc: - 'stun:stunserver2024.stunprotocol.org' - 'stun:stun.framasoft.org' +nsfw_flags_settings: + # Allow logged-in/anonymous users to have a more granular control over their NSFW policy + # using NSFW flags (violent content, etc.) set by video authors + enabled: false + ############################################################################### # # From this point, almost all following keys can be overridden by the web interface @@ -1087,6 +1092,11 @@ client: # You can automatically redirect your users on this external platform when they click on the login button redirect_on_single_external_auth: false + # Allow logged-in/anonymous users to have a more granular control over their NSFW policy + # using NSFW flags (violent content, etc.) set by video authors + nsfw_flags_settings: + enabled: true + open_in_app: android: # Use an intent URL: https://developer.chrome.com/docs/android/intents diff --git a/packages/models/src/server/server-config.model.ts b/packages/models/src/server/server-config.model.ts index 1e3108774..537bdc73f 100644 --- a/packages/models/src/server/server-config.model.ts +++ b/packages/models/src/server/server-config.model.ts @@ -399,6 +399,10 @@ export interface ServerConfig { webrtc: { stunServers: string[] } + + nsfwFlagsSettings: { + enabled: boolean + } } export type HTMLServerConfig = Omit diff --git a/packages/tests/src/api/videos/video-nsfw.ts b/packages/tests/src/api/videos/video-nsfw.ts index ac6b67ea5..a630ea7ab 100644 --- a/packages/tests/src/api/videos/video-nsfw.ts +++ b/packages/tests/src/api/videos/video-nsfw.ts @@ -549,6 +549,34 @@ describe('Test video NSFW policy', function () { expect(data.map(v => v.name)).to.have.members([ 'not nsfw', 'nsfw simple', 'nsfw sex', 'import violent', 'live violent' ]) } }) + + it('Should disable NSFW flags policy', async function () { + await servers[0].users.updateMe({ + token: userAccessToken, + nsfwPolicy: 'do_not_list', + nsfwFlagsHidden: NSFWFlag.EXPLICIT_SEX, + nsfwFlagsWarned: NSFWFlag.NONE, + nsfwFlagsBlurred: NSFWFlag.SHOCKING_DISTURBING, + nsfwFlagsDisplayed: NSFWFlag.VIOLENT + }) + + await servers[0].kill() + await servers[0].run({ nsfw_flags_settings: { enabled: false } }) + + const me = await servers[0].users.getMyInfo({ token: userAccessToken }) + expect(me.nsfwPolicy).to.equal('do_not_list') + expect(me.nsfwFlagsHidden).to.equal(0) + expect(me.nsfwFlagsWarned).to.equal(0) + expect(me.nsfwFlagsBlurred).to.equal(0) + expect(me.nsfwFlagsDisplayed).to.equal(0) + + for (const { total, data } of await getVideosFunctions(userAccessToken)) { + expect(total).to.equal(1) + + expect(data).to.have.lengthOf(1) + expect(data.map(v => v.name)).to.have.members([ 'not nsfw' ]) + } + }) }) after(async function () { diff --git a/server/core/controllers/api/config.ts b/server/core/controllers/api/config.ts index 6a68b2abe..f4a687748 100644 --- a/server/core/controllers/api/config.ts +++ b/server/core/controllers/api/config.ts @@ -31,24 +31,20 @@ configRouter.use(apiRateLimiter) const auditLogger = auditLoggerFactory('config') -configRouter.get('/', - openapiOperationDoc({ operationId: 'getConfig' }), - asyncMiddleware(getConfig) -) +configRouter.get('/', openapiOperationDoc({ operationId: 'getConfig' }), asyncMiddleware(getConfig)) -configRouter.get('/about', - openapiOperationDoc({ operationId: 'getAbout' }), - asyncMiddleware(getAbout) -) +configRouter.get('/about', openapiOperationDoc({ operationId: 'getAbout' }), asyncMiddleware(getAbout)) -configRouter.get('/custom', +configRouter.get( + '/custom', openapiOperationDoc({ operationId: 'getCustomConfig' }), authenticate, ensureUserHasRight(UserRight.MANAGE_CONFIGURATION), getCustomConfig ) -configRouter.put('/custom', +configRouter.put( + '/custom', openapiOperationDoc({ operationId: 'putCustomConfig' }), authenticate, ensureUserHasRight(UserRight.MANAGE_CONFIGURATION), @@ -57,7 +53,8 @@ configRouter.put('/custom', asyncMiddleware(updateCustomConfig) ) -configRouter.delete('/custom', +configRouter.delete( + '/custom', openapiOperationDoc({ operationId: 'delCustomConfig' }), authenticate, ensureUserHasRight(UserRight.MANAGE_CONFIGURATION), @@ -67,7 +64,8 @@ configRouter.delete('/custom', // --------------------------------------------------------------------------- -configRouter.post('/instance-banner/pick', +configRouter.post( + '/instance-banner/pick', authenticate, createReqFiles([ 'bannerfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT), ensureUserHasRight(UserRight.MANAGE_CONFIGURATION), @@ -75,7 +73,8 @@ configRouter.post('/instance-banner/pick', asyncMiddleware(updateInstanceImageFactory(ActorImageType.BANNER)) ) -configRouter.delete('/instance-banner', +configRouter.delete( + '/instance-banner', authenticate, ensureUserHasRight(UserRight.MANAGE_CONFIGURATION), asyncMiddleware(deleteInstanceImageFactory(ActorImageType.BANNER)) @@ -83,7 +82,8 @@ configRouter.delete('/instance-banner', // --------------------------------------------------------------------------- -configRouter.post('/instance-avatar/pick', +configRouter.post( + '/instance-avatar/pick', authenticate, createReqFiles([ 'avatarfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT), ensureUserHasRight(UserRight.MANAGE_CONFIGURATION), @@ -91,7 +91,8 @@ configRouter.post('/instance-avatar/pick', asyncMiddleware(updateInstanceImageFactory(ActorImageType.AVATAR)) ) -configRouter.delete('/instance-avatar', +configRouter.delete( + '/instance-avatar', authenticate, ensureUserHasRight(UserRight.MANAGE_CONFIGURATION), asyncMiddleware(deleteInstanceImageFactory(ActorImageType.AVATAR)) diff --git a/server/core/helpers/express-utils.ts b/server/core/helpers/express-utils.ts index 24ac9c4d6..b6cbb23b8 100644 --- a/server/core/helpers/express-utils.ts +++ b/server/core/helpers/express-utils.ts @@ -1,4 +1,4 @@ -import { VideosCommonQuery } from '@peertube/peertube-models' +import { NSFWFlag, VideosCommonQuery } from '@peertube/peertube-models' import { getLowercaseExtension } from '@peertube/peertube-node-utils' import express, { RequestHandler } from 'express' import multer, { diskStorage } from 'multer' @@ -19,8 +19,14 @@ export function buildNSFWFilters (options: { } = {}) { return { nsfw: buildNSFWFilter(options), - nsfwFlagsIncluded: buildNSFWFlagsIncluded(options), - nsfwFlagsExcluded: buildNSFWFlagsExcluded(options) + + nsfwFlagsIncluded: CONFIG.NSFW_FLAGS_SETTINGS.ENABLED + ? buildNSFWFlagsIncluded(options) + : NSFWFlag.NONE, + + nsfwFlagsExcluded: CONFIG.NSFW_FLAGS_SETTINGS.ENABLED + ? buildNSFWFlagsExcluded(options) + : NSFWFlag.NONE } } diff --git a/server/core/initializers/checker-before-init.ts b/server/core/initializers/checker-before-init.ts index 6720f65db..32c61536b 100644 --- a/server/core/initializers/checker-before-init.ts +++ b/server/core/initializers/checker-before-init.ts @@ -6,92 +6,250 @@ import { logger } from '../helpers/logger.js' // ONLY USE CORE MODULES IN THIS FILE! // Check the config files -function checkMissedConfig () { - const required = [ 'listen.port', 'listen.hostname', - 'webserver.https', 'webserver.hostname', 'webserver.port', +export function checkMissedConfig () { + const required = [ + 'listen.port', + 'listen.hostname', + 'webserver.https', + 'webserver.hostname', + 'webserver.port', 'secrets.peertube', 'trust_proxy', - 'oauth2.token_lifetime.access_token', 'oauth2.token_lifetime.refresh_token', - 'database.hostname', 'database.port', 'database.username', 'database.password', 'database.pool.max', - 'smtp.hostname', 'smtp.port', 'smtp.username', 'smtp.password', 'smtp.tls', 'smtp.from_address', - 'email.body.signature', 'email.subject.prefix', - 'storage.avatars', 'storage.web_videos', 'storage.logs', 'storage.previews', 'storage.thumbnails', 'storage.torrents', 'storage.cache', - 'storage.redundancy', 'storage.tmp', 'storage.streaming_playlists', 'storage.plugins', 'storage.well_known', - 'log.level', 'log.rotation.enabled', 'log.rotation.max_file_size', 'log.rotation.max_files', 'log.anonymize_ip', - 'log.log_ping_requests', 'log.log_tracker_unknown_infohash', 'log.prettify_sql', 'log.accept_client_log', - 'open_telemetry.metrics.enabled', 'open_telemetry.metrics.playback_stats_interval', - 'open_telemetry.metrics.prometheus_exporter.hostname', 'open_telemetry.metrics.prometheus_exporter.port', - 'open_telemetry.tracing.enabled', 'open_telemetry.tracing.jaeger_exporter.endpoint', + 'oauth2.token_lifetime.access_token', + 'oauth2.token_lifetime.refresh_token', + 'database.hostname', + 'database.port', + 'database.username', + 'database.password', + 'database.pool.max', + 'smtp.hostname', + 'smtp.port', + 'smtp.username', + 'smtp.password', + 'smtp.tls', + 'smtp.from_address', + 'email.body.signature', + 'email.subject.prefix', + 'storage.avatars', + 'storage.web_videos', + 'storage.logs', + 'storage.previews', + 'storage.thumbnails', + 'storage.torrents', + 'storage.cache', + 'storage.redundancy', + 'storage.tmp', + 'storage.streaming_playlists', + 'storage.plugins', + 'storage.well_known', + 'log.level', + 'log.rotation.enabled', + 'log.rotation.max_file_size', + 'log.rotation.max_files', + 'log.anonymize_ip', + 'log.log_ping_requests', + 'log.log_tracker_unknown_infohash', + 'log.prettify_sql', + 'log.accept_client_log', + 'open_telemetry.metrics.enabled', + 'open_telemetry.metrics.playback_stats_interval', + 'open_telemetry.metrics.prometheus_exporter.hostname', + 'open_telemetry.metrics.prometheus_exporter.port', + 'open_telemetry.tracing.enabled', + 'open_telemetry.tracing.jaeger_exporter.endpoint', 'open_telemetry.metrics.http_request_duration.enabled', - 'user.history.videos.enabled', 'user.video_quota', 'user.video_quota_daily', + 'user.history.videos.enabled', + 'user.video_quota', + 'user.video_quota_daily', 'video_channels.max_per_user', - 'csp.enabled', 'csp.report_only', 'csp.report_uri', - 'security.frameguard.enabled', 'security.powered_by_header.enabled', - 'cache.previews.size', 'cache.captions.size', 'cache.torrents.size', 'cache.storyboards.size', - 'admin.email', 'contact_form.enabled', - 'signup.enabled', 'signup.limit', 'signup.requires_approval', 'signup.requires_email_verification', 'signup.minimum_age', - 'signup.filters.cidr.whitelist', 'signup.filters.cidr.blacklist', - 'redundancy.videos.strategies', 'redundancy.videos.check_interval', - 'transcoding.enabled', 'transcoding.original_file.keep', 'transcoding.threads', 'transcoding.allow_additional_extensions', - 'transcoding.web_videos.enabled', 'transcoding.hls.enabled', 'transcoding.profile', 'transcoding.concurrency', - 'transcoding.resolutions.0p', 'transcoding.resolutions.144p', 'transcoding.resolutions.240p', 'transcoding.resolutions.360p', - 'transcoding.resolutions.480p', 'transcoding.resolutions.720p', 'transcoding.resolutions.1080p', 'transcoding.resolutions.1440p', - 'transcoding.resolutions.2160p', 'transcoding.always_transcode_original_resolution', 'transcoding.remote_runners.enabled', + 'csp.enabled', + 'csp.report_only', + 'csp.report_uri', + 'security.frameguard.enabled', + 'security.powered_by_header.enabled', + 'cache.previews.size', + 'cache.captions.size', + 'cache.torrents.size', + 'cache.storyboards.size', + 'admin.email', + 'contact_form.enabled', + 'signup.enabled', + 'signup.limit', + 'signup.requires_approval', + 'signup.requires_email_verification', + 'signup.minimum_age', + 'signup.filters.cidr.whitelist', + 'signup.filters.cidr.blacklist', + 'redundancy.videos.strategies', + 'redundancy.videos.check_interval', + 'transcoding.enabled', + 'transcoding.original_file.keep', + 'transcoding.threads', + 'transcoding.allow_additional_extensions', + 'transcoding.web_videos.enabled', + 'transcoding.hls.enabled', + 'transcoding.profile', + 'transcoding.concurrency', + 'transcoding.resolutions.0p', + 'transcoding.resolutions.144p', + 'transcoding.resolutions.240p', + 'transcoding.resolutions.360p', + 'transcoding.resolutions.480p', + 'transcoding.resolutions.720p', + 'transcoding.resolutions.1080p', + 'transcoding.resolutions.1440p', + 'transcoding.resolutions.2160p', + 'transcoding.always_transcode_original_resolution', + 'transcoding.remote_runners.enabled', 'transcoding.fps.max', - 'video_studio.enabled', 'video_studio.remote_runners.enabled', + 'video_studio.enabled', + 'video_studio.remote_runners.enabled', 'video_file.update.enabled', - 'remote_runners.stalled_jobs.vod', 'remote_runners.stalled_jobs.live', - 'thumbnails.generation_from_video.frames_to_analyze', 'thumbnails.sizes', - 'import.videos.http.enabled', 'import.videos.torrent.enabled', 'import.videos.concurrency', 'import.videos.timeout', - 'import.videos.http.force_ipv4', 'import.videos.http.proxies', - 'import.video_channel_synchronization.enabled', 'import.video_channel_synchronization.max_per_user', - 'import.video_channel_synchronization.check_interval', 'import.video_channel_synchronization.videos_limit_per_synchronization', + 'remote_runners.stalled_jobs.vod', + 'remote_runners.stalled_jobs.live', + 'thumbnails.generation_from_video.frames_to_analyze', + 'thumbnails.sizes', + 'import.videos.http.enabled', + 'import.videos.torrent.enabled', + 'import.videos.concurrency', + 'import.videos.timeout', + 'import.videos.http.force_ipv4', + 'import.videos.http.proxies', + 'import.video_channel_synchronization.enabled', + 'import.video_channel_synchronization.max_per_user', + 'import.video_channel_synchronization.check_interval', + 'import.video_channel_synchronization.videos_limit_per_synchronization', 'import.video_channel_synchronization.full_sync_videos_limit', - 'auto_blacklist.videos.of_users.enabled', 'trending.videos.interval_days', - 'client.videos.miniature.prefer_author_display_name', 'client.menu.login.redirect_on_single_external_auth', - 'defaults.publish.download_enabled', 'defaults.publish.comments_policy', 'defaults.publish.privacy', 'defaults.publish.licence', + 'auto_blacklist.videos.of_users.enabled', + 'trending.videos.interval_days', + 'client.videos.miniature.prefer_author_display_name', + 'client.menu.login.redirect_on_single_external_auth', + 'defaults.publish.download_enabled', + 'defaults.publish.comments_policy', + 'defaults.publish.privacy', + 'defaults.publish.licence', 'defaults.player.auto_play', - 'instance.name', 'instance.short_description', 'instance.description', 'instance.terms', 'instance.default_client_route', - 'instance.is_nsfw', 'instance.default_nsfw_policy', 'instance.robots', 'instance.securitytxt', - 'instance.server_country', 'instance.support.text', 'instance.social.external_link', 'instance.social.mastodon_link', + 'instance.name', + 'instance.short_description', + 'instance.description', + 'instance.terms', + 'instance.default_client_route', + 'instance.is_nsfw', + 'instance.default_nsfw_policy', + 'instance.robots', + 'instance.securitytxt', + 'instance.server_country', + 'instance.support.text', + 'instance.social.external_link', + 'instance.social.mastodon_link', 'instance.social.bluesky_link', 'services.twitter.username', - 'followers.instance.enabled', 'followers.instance.manual_approval', - 'tracker.enabled', 'tracker.private', 'tracker.reject_too_many_announces', - 'history.videos.max_age', 'views.videos.remote.max_age', 'views.videos.local_buffer_update_interval', 'views.videos.view_expiration', - 'views.videos.watching_interval.anonymous', 'views.videos.watching_interval.users', - 'rates_limit.api.window', 'rates_limit.api.max', 'rates_limit.login.window', 'rates_limit.login.max', - 'rates_limit.signup.window', 'rates_limit.signup.max', 'rates_limit.ask_send_email.window', 'rates_limit.ask_send_email.max', - 'rates_limit.receive_client_log.window', 'rates_limit.receive_client_log.max', 'rates_limit.plugins.window', 'rates_limit.plugins.max', - 'rates_limit.well_known.window', 'rates_limit.well_known.max', 'rates_limit.feeds.window', 'rates_limit.feeds.max', - 'rates_limit.activity_pub.window', 'rates_limit.activity_pub.max', 'rates_limit.client.window', 'rates_limit.client.max', + 'followers.instance.enabled', + 'followers.instance.manual_approval', + 'tracker.enabled', + 'tracker.private', + 'tracker.reject_too_many_announces', + 'history.videos.max_age', + 'views.videos.remote.max_age', + 'views.videos.local_buffer_update_interval', + 'views.videos.view_expiration', + 'views.videos.watching_interval.anonymous', + 'views.videos.watching_interval.users', + 'rates_limit.api.window', + 'rates_limit.api.max', + 'rates_limit.login.window', + 'rates_limit.login.max', + 'rates_limit.signup.window', + 'rates_limit.signup.max', + 'rates_limit.ask_send_email.window', + 'rates_limit.ask_send_email.max', + 'rates_limit.receive_client_log.window', + 'rates_limit.receive_client_log.max', + 'rates_limit.plugins.window', + 'rates_limit.plugins.max', + 'rates_limit.well_known.window', + 'rates_limit.well_known.max', + 'rates_limit.feeds.window', + 'rates_limit.feeds.max', + 'rates_limit.activity_pub.window', + 'rates_limit.activity_pub.max', + 'rates_limit.client.window', + 'rates_limit.client.max', 'static_files.private_files_require_auth', - 'object_storage.enabled', 'object_storage.endpoint', 'object_storage.region', 'object_storage.upload_acl.public', - 'object_storage.upload_acl.private', 'object_storage.proxy.proxify_private_files', 'object_storage.credentials.access_key_id', - 'object_storage.credentials.secret_access_key', 'object_storage.max_upload_part', 'object_storage.streaming_playlists.bucket_name', - 'object_storage.streaming_playlists.prefix', 'object_storage.streaming_playlists.base_url', 'object_storage.web_videos.bucket_name', - 'object_storage.web_videos.prefix', 'object_storage.web_videos.base_url', 'object_storage.original_video_files.bucket_name', - 'object_storage.original_video_files.prefix', 'object_storage.original_video_files.base_url', 'object_storage.max_request_attempts', - 'object_storage.captions.bucket_name', 'object_storage.captions.prefix', 'object_storage.captions.base_url', + 'object_storage.enabled', + 'object_storage.endpoint', + 'object_storage.region', + 'object_storage.upload_acl.public', + 'object_storage.upload_acl.private', + 'object_storage.proxy.proxify_private_files', + 'object_storage.credentials.access_key_id', + 'object_storage.credentials.secret_access_key', + 'object_storage.max_upload_part', + 'object_storage.streaming_playlists.bucket_name', + 'object_storage.streaming_playlists.prefix', + 'object_storage.streaming_playlists.base_url', + 'object_storage.web_videos.bucket_name', + 'object_storage.web_videos.prefix', + 'object_storage.web_videos.base_url', + 'object_storage.original_video_files.bucket_name', + 'object_storage.original_video_files.prefix', + 'object_storage.original_video_files.base_url', + 'object_storage.max_request_attempts', + 'object_storage.captions.bucket_name', + 'object_storage.captions.prefix', + 'object_storage.captions.base_url', 'theme.default', - 'feeds.videos.count', 'feeds.comments.count', - 'geo_ip.enabled', 'geo_ip.country.database_url', 'geo_ip.city.database_url', + 'feeds.videos.count', + 'feeds.comments.count', + 'geo_ip.enabled', + 'geo_ip.country.database_url', + 'geo_ip.city.database_url', 'remote_redundancy.videos.accept_from', - 'federation.enabled', 'federation.prevent_ssrf', 'federation.videos.federate_unlisted', 'federation.videos.cleanup_remote_interactions', - 'peertube.check_latest_version.enabled', 'peertube.check_latest_version.url', - 'search.remote_uri.users', 'search.remote_uri.anonymous', 'search.search_index.enabled', 'search.search_index.url', - 'search.search_index.disable_local_search', 'search.search_index.is_default_search', - 'live.enabled', 'live.allow_replay', 'live.latency_setting.enabled', 'live.max_duration', - 'live.max_user_lives', 'live.max_instance_lives', - 'live.rtmp.enabled', 'live.rtmp.port', 'live.rtmp.hostname', 'live.rtmp.public_hostname', - 'live.rtmps.enabled', 'live.rtmps.port', 'live.rtmps.hostname', 'live.rtmps.public_hostname', - 'live.rtmps.key_file', 'live.rtmps.cert_file', - 'live.transcoding.enabled', 'live.transcoding.threads', 'live.transcoding.profile', - 'live.transcoding.resolutions.144p', 'live.transcoding.resolutions.240p', 'live.transcoding.resolutions.360p', - 'live.transcoding.resolutions.480p', 'live.transcoding.resolutions.720p', 'live.transcoding.resolutions.1080p', - 'live.transcoding.resolutions.1440p', 'live.transcoding.resolutions.2160p', 'live.transcoding.always_transcode_original_resolution', - 'live.transcoding.fps.max', 'live.transcoding.remote_runners.enabled', - 'storyboards.enabled' + 'federation.enabled', + 'federation.prevent_ssrf', + 'federation.videos.federate_unlisted', + 'federation.videos.cleanup_remote_interactions', + 'peertube.check_latest_version.enabled', + 'peertube.check_latest_version.url', + 'search.remote_uri.users', + 'search.remote_uri.anonymous', + 'search.search_index.enabled', + 'search.search_index.url', + 'search.search_index.disable_local_search', + 'search.search_index.is_default_search', + 'live.enabled', + 'live.allow_replay', + 'live.latency_setting.enabled', + 'live.max_duration', + 'live.max_user_lives', + 'live.max_instance_lives', + 'live.rtmp.enabled', + 'live.rtmp.port', + 'live.rtmp.hostname', + 'live.rtmp.public_hostname', + 'live.rtmps.enabled', + 'live.rtmps.port', + 'live.rtmps.hostname', + 'live.rtmps.public_hostname', + 'live.rtmps.key_file', + 'live.rtmps.cert_file', + 'live.transcoding.enabled', + 'live.transcoding.threads', + 'live.transcoding.profile', + 'live.transcoding.resolutions.144p', + 'live.transcoding.resolutions.240p', + 'live.transcoding.resolutions.360p', + 'live.transcoding.resolutions.480p', + 'live.transcoding.resolutions.720p', + 'live.transcoding.resolutions.1080p', + 'live.transcoding.resolutions.1440p', + 'live.transcoding.resolutions.2160p', + 'live.transcoding.always_transcode_original_resolution', + 'live.transcoding.fps.max', + 'live.transcoding.remote_runners.enabled', + 'storyboards.enabled', + 'webrtc.stun_servers', + 'nsfw_flags_settings.enabled' ] const requiredAlternatives = [ @@ -130,7 +288,7 @@ function checkMissedConfig () { // Check the available codecs // We get CONFIG by param to not import it in this file (import orders) -async function checkFFmpeg (CONFIG: { TRANSCODING: { ENABLED: boolean } }) { +export async function checkFFmpeg (CONFIG: { TRANSCODING: { ENABLED: boolean } }) { if (CONFIG.TRANSCODING.ENABLED === false) return undefined const Ffmpeg = (await import('fluent-ffmpeg')).default @@ -149,7 +307,7 @@ async function checkFFmpeg (CONFIG: { TRANSCODING: { ENABLED: boolean } }) { } } -function checkNodeVersion () { +export function checkNodeVersion () { const v = process.version const { major } = parseSemVersion(v) @@ -159,11 +317,3 @@ function checkNodeVersion () { throw new Error('Your NodeJS version ' + v + ' is not supported. Please upgrade.') } } - -// --------------------------------------------------------------------------- - -export { - checkFFmpeg, - checkMissedConfig, - checkNodeVersion -} diff --git a/server/core/initializers/config.ts b/server/core/initializers/config.ts index 0976060c1..07f7ef230 100644 --- a/server/core/initializers/config.ts +++ b/server/core/initializers/config.ts @@ -74,34 +74,60 @@ const CONFIG = { } }, + NSFW_FLAGS_SETTINGS: { + ENABLED: config.get('nsfw_flags_settings.enabled') + }, + CLIENT: { VIDEOS: { MINIATURE: { - get PREFER_AUTHOR_DISPLAY_NAME () { return config.get('client.videos.miniature.prefer_author_display_name') } + get PREFER_AUTHOR_DISPLAY_NAME () { + return config.get('client.videos.miniature.prefer_author_display_name') + } }, RESUMABLE_UPLOAD: { - get MAX_CHUNK_SIZE () { return parseBytes(config.get('client.videos.resumable_upload.max_chunk_size') || 0) } + get MAX_CHUNK_SIZE () { + return parseBytes(config.get('client.videos.resumable_upload.max_chunk_size') || 0) + } } }, MENU: { LOGIN: { - get REDIRECT_ON_SINGLE_EXTERNAL_AUTH () { return config.get('client.menu.login.redirect_on_single_external_auth') } + get REDIRECT_ON_SINGLE_EXTERNAL_AUTH () { + return config.get('client.menu.login.redirect_on_single_external_auth') + } } }, OPEN_IN_APP: { ANDROID: { INTENT: { - get ENABLED () { return config.get('client.open_in_app.android.intent.enabled') }, - get HOST () { return config.get('client.open_in_app.android.intent.host') }, - get SCHEME () { return config.get('client.open_in_app.android.intent.scheme') }, - get FALLBACK_URL () { return config.get('client.open_in_app.android.intent.fallback_url') } + get ENABLED () { + return config.get('client.open_in_app.android.intent.enabled') + }, + get HOST () { + return config.get('client.open_in_app.android.intent.host') + }, + get SCHEME () { + return config.get('client.open_in_app.android.intent.scheme') + }, + get FALLBACK_URL () { + return config.get('client.open_in_app.android.intent.fallback_url') + } } }, IOS: { - get ENABLED () { return config.get('client.open_in_app.ios.enabled') }, - get HOST () { return config.get('client.open_in_app.ios.host') }, - get SCHEME () { return config.get('client.open_in_app.ios.scheme') }, - get FALLBACK_URL () { return config.get('client.open_in_app.ios.fallback_url') } + get ENABLED () { + return config.get('client.open_in_app.ios.enabled') + }, + get HOST () { + return config.get('client.open_in_app.ios.host') + }, + get SCHEME () { + return config.get('client.open_in_app.ios.scheme') + }, + get FALLBACK_URL () { + return config.get('client.open_in_app.ios.fallback_url') + } } } }, @@ -122,7 +148,9 @@ const CONFIG = { } }, PLAYER: { - get AUTO_PLAY () { return config.get('defaults.player.auto_play') } + get AUTO_PLAY () { + return config.get('defaults.player.auto_play') + } } }, @@ -293,8 +321,12 @@ const CONFIG = { VIDEOS: { INTERVAL_DAYS: config.get('trending.videos.interval_days'), ALGORITHMS: { - get ENABLED () { return config.get('trending.videos.algorithms.enabled') }, - get DEFAULT () { return config.get('trending.videos.algorithms.default') } + get ENABLED () { + return config.get('trending.videos.algorithms.enabled') + }, + get DEFAULT () { + return config.get('trending.videos.algorithms.default') + } } } }, @@ -423,177 +455,353 @@ const CONFIG = { STUN_SERVERS: config.get('webrtc.stun_servers') }, ADMIN: { - get EMAIL () { return config.get('admin.email') } + get EMAIL () { + return config.get('admin.email') + } }, CONTACT_FORM: { - get ENABLED () { return config.get('contact_form.enabled') } + get ENABLED () { + return config.get('contact_form.enabled') + } }, SIGNUP: { - get ENABLED () { return config.get('signup.enabled') }, - get REQUIRES_APPROVAL () { return config.get('signup.requires_approval') }, - get LIMIT () { return config.get('signup.limit') }, - get REQUIRES_EMAIL_VERIFICATION () { return config.get('signup.requires_email_verification') }, - get MINIMUM_AGE () { return config.get('signup.minimum_age') }, + get ENABLED () { + return config.get('signup.enabled') + }, + get REQUIRES_APPROVAL () { + return config.get('signup.requires_approval') + }, + get LIMIT () { + return config.get('signup.limit') + }, + get REQUIRES_EMAIL_VERIFICATION () { + return config.get('signup.requires_email_verification') + }, + get MINIMUM_AGE () { + return config.get('signup.minimum_age') + }, FILTERS: { CIDR: { - get WHITELIST () { return config.get('signup.filters.cidr.whitelist') }, - get BLACKLIST () { return config.get('signup.filters.cidr.blacklist') } + get WHITELIST () { + return config.get('signup.filters.cidr.whitelist') + }, + get BLACKLIST () { + return config.get('signup.filters.cidr.blacklist') + } } } }, USER: { HISTORY: { VIDEOS: { - get ENABLED () { return config.get('user.history.videos.enabled') } + get ENABLED () { + return config.get('user.history.videos.enabled') + } } }, - get VIDEO_QUOTA () { return parseBytes(config.get('user.video_quota')) }, - get VIDEO_QUOTA_DAILY () { return parseBytes(config.get('user.video_quota_daily')) }, - get DEFAULT_CHANNEL_NAME () { return config.get('user.default_channel_name') } + get VIDEO_QUOTA () { + return parseBytes(config.get('user.video_quota')) + }, + get VIDEO_QUOTA_DAILY () { + return parseBytes(config.get('user.video_quota_daily')) + }, + get DEFAULT_CHANNEL_NAME () { + return config.get('user.default_channel_name') + } }, VIDEO_CHANNELS: { - get MAX_PER_USER () { return config.get('video_channels.max_per_user') } + get MAX_PER_USER () { + return config.get('video_channels.max_per_user') + } }, TRANSCODING: { - get ENABLED () { return config.get('transcoding.enabled') }, - ORIGINAL_FILE: { - get KEEP () { return config.get('transcoding.original_file.keep') } + get ENABLED () { + return config.get('transcoding.enabled') + }, + ORIGINAL_FILE: { + get KEEP () { + return config.get('transcoding.original_file.keep') + } + }, + get ALLOW_ADDITIONAL_EXTENSIONS () { + return config.get('transcoding.allow_additional_extensions') + }, + get ALLOW_AUDIO_FILES () { + return config.get('transcoding.allow_audio_files') + }, + get THREADS () { + return config.get('transcoding.threads') + }, + get CONCURRENCY () { + return config.get('transcoding.concurrency') + }, + get PROFILE () { + return config.get('transcoding.profile') + }, + get ALWAYS_TRANSCODE_ORIGINAL_RESOLUTION () { + return config.get('transcoding.always_transcode_original_resolution') }, - get ALLOW_ADDITIONAL_EXTENSIONS () { return config.get('transcoding.allow_additional_extensions') }, - get ALLOW_AUDIO_FILES () { return config.get('transcoding.allow_audio_files') }, - get THREADS () { return config.get('transcoding.threads') }, - get CONCURRENCY () { return config.get('transcoding.concurrency') }, - get PROFILE () { return config.get('transcoding.profile') }, - get ALWAYS_TRANSCODE_ORIGINAL_RESOLUTION () { return config.get('transcoding.always_transcode_original_resolution') }, RESOLUTIONS: { - get '0p' () { return config.get('transcoding.resolutions.0p') }, - get '144p' () { return config.get('transcoding.resolutions.144p') }, - get '240p' () { return config.get('transcoding.resolutions.240p') }, - get '360p' () { return config.get('transcoding.resolutions.360p') }, - get '480p' () { return config.get('transcoding.resolutions.480p') }, - get '720p' () { return config.get('transcoding.resolutions.720p') }, - get '1080p' () { return config.get('transcoding.resolutions.1080p') }, - get '1440p' () { return config.get('transcoding.resolutions.1440p') }, - get '2160p' () { return config.get('transcoding.resolutions.2160p') } + get '0p' () { + return config.get('transcoding.resolutions.0p') + }, + get '144p' () { + return config.get('transcoding.resolutions.144p') + }, + get '240p' () { + return config.get('transcoding.resolutions.240p') + }, + get '360p' () { + return config.get('transcoding.resolutions.360p') + }, + get '480p' () { + return config.get('transcoding.resolutions.480p') + }, + get '720p' () { + return config.get('transcoding.resolutions.720p') + }, + get '1080p' () { + return config.get('transcoding.resolutions.1080p') + }, + get '1440p' () { + return config.get('transcoding.resolutions.1440p') + }, + get '2160p' () { + return config.get('transcoding.resolutions.2160p') + } }, FPS: { - get MAX () { return config.get('transcoding.fps.max') } + get MAX () { + return config.get('transcoding.fps.max') + } }, HLS: { - get ENABLED () { return config.get('transcoding.hls.enabled') }, - get SPLIT_AUDIO_AND_VIDEO () { return config.get('transcoding.hls.split_audio_and_video') } + get ENABLED () { + return config.get('transcoding.hls.enabled') + }, + get SPLIT_AUDIO_AND_VIDEO () { + return config.get('transcoding.hls.split_audio_and_video') + } }, WEB_VIDEOS: { - get ENABLED () { return config.get('transcoding.web_videos.enabled') } + get ENABLED () { + return config.get('transcoding.web_videos.enabled') + } }, REMOTE_RUNNERS: { - get ENABLED () { return config.get('transcoding.remote_runners.enabled') } + get ENABLED () { + return config.get('transcoding.remote_runners.enabled') + } } }, LIVE: { - get ENABLED () { return config.get('live.enabled') }, + get ENABLED () { + return config.get('live.enabled') + }, - get MAX_DURATION () { return parseDurationToMs(config.get('live.max_duration')) }, - get MAX_INSTANCE_LIVES () { return config.get('live.max_instance_lives') }, - get MAX_USER_LIVES () { return config.get('live.max_user_lives') }, + get MAX_DURATION () { + return parseDurationToMs(config.get('live.max_duration')) + }, + get MAX_INSTANCE_LIVES () { + return config.get('live.max_instance_lives') + }, + get MAX_USER_LIVES () { + return config.get('live.max_user_lives') + }, - get ALLOW_REPLAY () { return config.get('live.allow_replay') }, + get ALLOW_REPLAY () { + return config.get('live.allow_replay') + }, LATENCY_SETTING: { - get ENABLED () { return config.get('live.latency_setting.enabled') } + get ENABLED () { + return config.get('live.latency_setting.enabled') + } }, RTMP: { - get ENABLED () { return config.get('live.rtmp.enabled') }, - get PORT () { return config.get('live.rtmp.port') }, - get HOSTNAME () { return config.get('live.rtmp.hostname') }, - get PUBLIC_HOSTNAME () { return config.get('live.rtmp.public_hostname') } + get ENABLED () { + return config.get('live.rtmp.enabled') + }, + get PORT () { + return config.get('live.rtmp.port') + }, + get HOSTNAME () { + return config.get('live.rtmp.hostname') + }, + get PUBLIC_HOSTNAME () { + return config.get('live.rtmp.public_hostname') + } }, RTMPS: { - get ENABLED () { return config.get('live.rtmps.enabled') }, - get PORT () { return config.get('live.rtmps.port') }, - get HOSTNAME () { return config.get('live.rtmps.hostname') }, - get PUBLIC_HOSTNAME () { return config.get('live.rtmps.public_hostname') }, - get KEY_FILE () { return config.get('live.rtmps.key_file') }, - get CERT_FILE () { return config.get('live.rtmps.cert_file') } + get ENABLED () { + return config.get('live.rtmps.enabled') + }, + get PORT () { + return config.get('live.rtmps.port') + }, + get HOSTNAME () { + return config.get('live.rtmps.hostname') + }, + get PUBLIC_HOSTNAME () { + return config.get('live.rtmps.public_hostname') + }, + get KEY_FILE () { + return config.get('live.rtmps.key_file') + }, + get CERT_FILE () { + return config.get('live.rtmps.cert_file') + } }, TRANSCODING: { - get ENABLED () { return config.get('live.transcoding.enabled') }, - get THREADS () { return config.get('live.transcoding.threads') }, - get PROFILE () { return config.get('live.transcoding.profile') }, + get ENABLED () { + return config.get('live.transcoding.enabled') + }, + get THREADS () { + return config.get('live.transcoding.threads') + }, + get PROFILE () { + return config.get('live.transcoding.profile') + }, - get ALWAYS_TRANSCODE_ORIGINAL_RESOLUTION () { return config.get('live.transcoding.always_transcode_original_resolution') }, + get ALWAYS_TRANSCODE_ORIGINAL_RESOLUTION () { + return config.get('live.transcoding.always_transcode_original_resolution') + }, RESOLUTIONS: { - get '0p' () { return config.get('live.transcoding.resolutions.0p') }, - get '144p' () { return config.get('live.transcoding.resolutions.144p') }, - get '240p' () { return config.get('live.transcoding.resolutions.240p') }, - get '360p' () { return config.get('live.transcoding.resolutions.360p') }, - get '480p' () { return config.get('live.transcoding.resolutions.480p') }, - get '720p' () { return config.get('live.transcoding.resolutions.720p') }, - get '1080p' () { return config.get('live.transcoding.resolutions.1080p') }, - get '1440p' () { return config.get('live.transcoding.resolutions.1440p') }, - get '2160p' () { return config.get('live.transcoding.resolutions.2160p') } + get '0p' () { + return config.get('live.transcoding.resolutions.0p') + }, + get '144p' () { + return config.get('live.transcoding.resolutions.144p') + }, + get '240p' () { + return config.get('live.transcoding.resolutions.240p') + }, + get '360p' () { + return config.get('live.transcoding.resolutions.360p') + }, + get '480p' () { + return config.get('live.transcoding.resolutions.480p') + }, + get '720p' () { + return config.get('live.transcoding.resolutions.720p') + }, + get '1080p' () { + return config.get('live.transcoding.resolutions.1080p') + }, + get '1440p' () { + return config.get('live.transcoding.resolutions.1440p') + }, + get '2160p' () { + return config.get('live.transcoding.resolutions.2160p') + } }, FPS: { - get MAX () { return config.get('live.transcoding.fps.max') } + get MAX () { + return config.get('live.transcoding.fps.max') + } }, REMOTE_RUNNERS: { - get ENABLED () { return config.get('live.transcoding.remote_runners.enabled') } + get ENABLED () { + return config.get('live.transcoding.remote_runners.enabled') + } } } }, VIDEO_STUDIO: { - get ENABLED () { return config.get('video_studio.enabled') }, + get ENABLED () { + return config.get('video_studio.enabled') + }, REMOTE_RUNNERS: { - get ENABLED () { return config.get('video_studio.remote_runners.enabled') } + get ENABLED () { + return config.get('video_studio.remote_runners.enabled') + } } }, VIDEO_FILE: { UPDATE: { - get ENABLED () { return config.get('video_file.update.enabled') } + get ENABLED () { + return config.get('video_file.update.enabled') + } } }, VIDEO_TRANSCRIPTION: { - get ENABLED () { return config.get('video_transcription.enabled') }, - get ENGINE () { return config.get('video_transcription.engine') }, - get ENGINE_PATH () { return config.get('video_transcription.engine_path') }, - get MODEL () { return config.get('video_transcription.model') }, - get MODEL_PATH () { return config.get('video_transcription.model_path') }, + get ENABLED () { + return config.get('video_transcription.enabled') + }, + get ENGINE () { + return config.get('video_transcription.engine') + }, + get ENGINE_PATH () { + return config.get('video_transcription.engine_path') + }, + get MODEL () { + return config.get('video_transcription.model') + }, + get MODEL_PATH () { + return config.get('video_transcription.model_path') + }, REMOTE_RUNNERS: { - get ENABLED () { return config.get('video_transcription.remote_runners.enabled') } + get ENABLED () { + return config.get('video_transcription.remote_runners.enabled') + } } }, IMPORT: { VIDEOS: { - get CONCURRENCY () { return config.get('import.videos.concurrency') }, - get TIMEOUT () { return parseDurationToMs(config.get('import.videos.timeout')) }, + get CONCURRENCY () { + return config.get('import.videos.concurrency') + }, + get TIMEOUT () { + return parseDurationToMs(config.get('import.videos.timeout')) + }, HTTP: { - get ENABLED () { return config.get('import.videos.http.enabled') }, - - YOUTUBE_DL_RELEASE: { - get URL () { return config.get('import.videos.http.youtube_dl_release.url') }, - get NAME () { return config.get('import.videos.http.youtube_dl_release.name') }, - get PYTHON_PATH () { return config.get('import.videos.http.youtube_dl_release.python_path') } + get ENABLED () { + return config.get('import.videos.http.enabled') }, - get FORCE_IPV4 () { return config.get('import.videos.http.force_ipv4') }, + YOUTUBE_DL_RELEASE: { + get URL () { + return config.get('import.videos.http.youtube_dl_release.url') + }, + get NAME () { + return config.get('import.videos.http.youtube_dl_release.name') + }, + get PYTHON_PATH () { + return config.get('import.videos.http.youtube_dl_release.python_path') + } + }, - get PROXIES () { return config.get('import.videos.http.proxies') } + get FORCE_IPV4 () { + return config.get('import.videos.http.force_ipv4') + }, + + get PROXIES () { + return config.get('import.videos.http.proxies') + } }, TORRENT: { - get ENABLED () { return config.get('import.videos.torrent.enabled') } + get ENABLED () { + return config.get('import.videos.torrent.enabled') + } } }, VIDEO_CHANNEL_SYNCHRONIZATION: { - get ENABLED () { return config.get('import.video_channel_synchronization.enabled') }, - get MAX_PER_USER () { return config.get('import.video_channel_synchronization.max_per_user') }, - get CHECK_INTERVAL () { return parseDurationToMs(config.get('import.video_channel_synchronization.check_interval')) }, + get ENABLED () { + return config.get('import.video_channel_synchronization.enabled') + }, + get MAX_PER_USER () { + return config.get('import.video_channel_synchronization.max_per_user') + }, + get CHECK_INTERVAL () { + return parseDurationToMs(config.get('import.video_channel_synchronization.check_interval')) + }, get VIDEOS_LIMIT_PER_SYNCHRONIZATION () { return config.get('import.video_channel_synchronization.videos_limit_per_synchronization') }, @@ -602,88 +810,162 @@ const CONFIG = { } }, USERS: { - get ENABLED () { return config.get('import.users.enabled') } + get ENABLED () { + return config.get('import.users.enabled') + } } }, EXPORT: { USERS: { - get ENABLED () { return config.get('export.users.enabled') }, - get MAX_USER_VIDEO_QUOTA () { return parseBytes(config.get('export.users.max_user_video_quota')) }, - get EXPORT_EXPIRATION () { return parseDurationToMs(config.get('export.users.export_expiration')) } + get ENABLED () { + return config.get('export.users.enabled') + }, + get MAX_USER_VIDEO_QUOTA () { + return parseBytes(config.get('export.users.max_user_video_quota')) + }, + get EXPORT_EXPIRATION () { + return parseDurationToMs(config.get('export.users.export_expiration')) + } } }, AUTO_BLACKLIST: { VIDEOS: { OF_USERS: { - get ENABLED () { return config.get('auto_blacklist.videos.of_users.enabled') } + get ENABLED () { + return config.get('auto_blacklist.videos.of_users.enabled') + } } } }, CACHE: { PREVIEWS: { - get SIZE () { return config.get('cache.previews.size') } + get SIZE () { + return config.get('cache.previews.size') + } }, VIDEO_CAPTIONS: { - get SIZE () { return config.get('cache.captions.size') } + get SIZE () { + return config.get('cache.captions.size') + } }, TORRENTS: { - get SIZE () { return config.get('cache.torrents.size') } + get SIZE () { + return config.get('cache.torrents.size') + } }, STORYBOARDS: { - get SIZE () { return config.get('cache.storyboards.size') } + get SIZE () { + return config.get('cache.storyboards.size') + } } }, INSTANCE: { - get NAME () { return config.get('instance.name') }, - get SHORT_DESCRIPTION () { return config.get('instance.short_description') }, - get DESCRIPTION () { return config.get('instance.description') }, - get TERMS () { return config.get('instance.terms') }, - get CODE_OF_CONDUCT () { return config.get('instance.code_of_conduct') }, + get NAME () { + return config.get('instance.name') + }, + get SHORT_DESCRIPTION () { + return config.get('instance.short_description') + }, + get DESCRIPTION () { + return config.get('instance.description') + }, + get TERMS () { + return config.get('instance.terms') + }, + get CODE_OF_CONDUCT () { + return config.get('instance.code_of_conduct') + }, - get CREATION_REASON () { return config.get('instance.creation_reason') }, + get CREATION_REASON () { + return config.get('instance.creation_reason') + }, - get MODERATION_INFORMATION () { return config.get('instance.moderation_information') }, - get ADMINISTRATOR () { return config.get('instance.administrator') }, - get MAINTENANCE_LIFETIME () { return config.get('instance.maintenance_lifetime') }, - get BUSINESS_MODEL () { return config.get('instance.business_model') }, - get HARDWARE_INFORMATION () { return config.get('instance.hardware_information') }, + get MODERATION_INFORMATION () { + return config.get('instance.moderation_information') + }, + get ADMINISTRATOR () { + return config.get('instance.administrator') + }, + get MAINTENANCE_LIFETIME () { + return config.get('instance.maintenance_lifetime') + }, + get BUSINESS_MODEL () { + return config.get('instance.business_model') + }, + get HARDWARE_INFORMATION () { + return config.get('instance.hardware_information') + }, - get LANGUAGES () { return config.get('instance.languages') || [] }, - get CATEGORIES () { return config.get('instance.categories') || [] }, + get LANGUAGES () { + return config.get('instance.languages') || [] + }, + get CATEGORIES () { + return config.get('instance.categories') || [] + }, - get IS_NSFW () { return config.get('instance.is_nsfw') }, - get DEFAULT_NSFW_POLICY () { return config.get('instance.default_nsfw_policy') }, + get IS_NSFW () { + return config.get('instance.is_nsfw') + }, + get DEFAULT_NSFW_POLICY () { + return config.get('instance.default_nsfw_policy') + }, - get SERVER_COUNTRY () { return config.get('instance.server_country') }, + get SERVER_COUNTRY () { + return config.get('instance.server_country') + }, SUPPORT: { - get TEXT () { return config.get('instance.support.text') } + get TEXT () { + return config.get('instance.support.text') + } }, SOCIAL: { - get EXTERNAL_LINK () { return config.get('instance.social.external_link') }, - get MASTODON_LINK () { return config.get('instance.social.mastodon_link') }, - get BLUESKY () { return config.get('instance.social.bluesky_link') } + get EXTERNAL_LINK () { + return config.get('instance.social.external_link') + }, + get MASTODON_LINK () { + return config.get('instance.social.mastodon_link') + }, + get BLUESKY () { + return config.get('instance.social.bluesky_link') + } }, - get DEFAULT_CLIENT_ROUTE () { return config.get('instance.default_client_route') }, + get DEFAULT_CLIENT_ROUTE () { + return config.get('instance.default_client_route') + }, CUSTOMIZATIONS: { - get JAVASCRIPT () { return config.get('instance.customizations.javascript') }, - get CSS () { return config.get('instance.customizations.css') } + get JAVASCRIPT () { + return config.get('instance.customizations.javascript') + }, + get CSS () { + return config.get('instance.customizations.css') + } }, - get ROBOTS () { return config.get('instance.robots') }, - get SECURITYTXT () { return config.get('instance.securitytxt') } + get ROBOTS () { + return config.get('instance.robots') + }, + get SECURITYTXT () { + return config.get('instance.securitytxt') + } }, SERVICES: { TWITTER: { - get USERNAME () { return config.get('services.twitter.username') } + get USERNAME () { + return config.get('services.twitter.username') + } } }, FOLLOWERS: { INSTANCE: { - get ENABLED () { return config.get('followers.instance.enabled') }, - get MANUAL_APPROVAL () { return config.get('followers.instance.manual_approval') } + get ENABLED () { + return config.get('followers.instance.enabled') + }, + get MANUAL_APPROVAL () { + return config.get('followers.instance.manual_approval') + } } }, FOLLOWINGS: { @@ -704,28 +986,52 @@ const CONFIG = { } }, THEME: { - get DEFAULT () { return config.get('theme.default') } + get DEFAULT () { + return config.get('theme.default') + } }, BROADCAST_MESSAGE: { - get ENABLED () { return config.get('broadcast_message.enabled') }, - get MESSAGE () { return config.get('broadcast_message.message') }, - get LEVEL () { return config.get('broadcast_message.level') }, - get DISMISSABLE () { return config.get('broadcast_message.dismissable') } + get ENABLED () { + return config.get('broadcast_message.enabled') + }, + get MESSAGE () { + return config.get('broadcast_message.message') + }, + get LEVEL () { + return config.get('broadcast_message.level') + }, + get DISMISSABLE () { + return config.get('broadcast_message.dismissable') + } }, SEARCH: { REMOTE_URI: { - get USERS () { return config.get('search.remote_uri.users') }, - get ANONYMOUS () { return config.get('search.remote_uri.anonymous') } + get USERS () { + return config.get('search.remote_uri.users') + }, + get ANONYMOUS () { + return config.get('search.remote_uri.anonymous') + } }, SEARCH_INDEX: { - get ENABLED () { return config.get('search.search_index.enabled') }, - get URL () { return config.get('search.search_index.url') }, - get DISABLE_LOCAL_SEARCH () { return config.get('search.search_index.disable_local_search') }, - get IS_DEFAULT_SEARCH () { return config.get('search.search_index.is_default_search') } + get ENABLED () { + return config.get('search.search_index.enabled') + }, + get URL () { + return config.get('search.search_index.url') + }, + get DISABLE_LOCAL_SEARCH () { + return config.get('search.search_index.disable_local_search') + }, + get IS_DEFAULT_SEARCH () { + return config.get('search.search_index.is_default_search') + } } }, STORYBOARDS: { - get ENABLED () { return config.get('storyboards.enabled') } + get ENABLED () { + return config.get('storyboards.enabled') + } } } @@ -791,7 +1097,6 @@ function buildVideosRedundancy (objs: any[]): VideosRedundancyStrategy[] { } export function reloadConfig () { - function getConfigDirectories () { if (process.env.NODE_CONFIG_DIR) { return process.env.NODE_CONFIG_DIR.split(':') @@ -804,7 +1109,7 @@ export function reloadConfig () { const directories = getConfigDirectories() for (const fileName in require.cache) { - if (directories.some((dir) => fileName.includes(dir)) === false) { + if (directories.some(dir => fileName.includes(dir)) === false) { continue } diff --git a/server/core/lib/server-config-manager.ts b/server/core/lib/server-config-manager.ts index afc8ef8ae..f44777c65 100644 --- a/server/core/lib/server-config-manager.ts +++ b/server/core/lib/server-config-manager.ts @@ -19,14 +19,11 @@ import { getThemeOrDefault } from './plugins/theme-utils.js' import { VideoTranscodingProfilesManager } from './transcoding/default-transcoding-profiles.js' /** - * * Used to send the server config to clients (using REST/API or plugins API) * We need a singleton class to manage config state depending on external events (to build menu entries etc) - * */ class ServerConfigManager { - private static instance: ServerConfigManager private serverCommit: string @@ -356,6 +353,10 @@ class ServerConfigManager { webrtc: { stunServers: CONFIG.WEBRTC.STUN_SERVERS + }, + + nsfwFlagsSettings: { + enabled: CONFIG.NSFW_FLAGS_SETTINGS.ENABLED } } } @@ -363,14 +364,12 @@ class ServerConfigManager { async getServerConfig (ip?: string): Promise { const { allowed } = await Hooks.wrapPromiseFun( isSignupAllowed, - { ip, signupMode: CONFIG.SIGNUP.REQUIRES_APPROVAL ? 'request-registration' : 'direct-registration' }, - CONFIG.SIGNUP.REQUIRES_APPROVAL ? 'filter:api.user.request-signup.allowed.result' : 'filter:api.user.signup.allowed.result' @@ -393,14 +392,14 @@ class ServerConfigManager { getRegisteredThemes () { return PluginManager.Instance.getRegisteredThemes() - .map(t => ({ - npmName: PluginModel.buildNpmName(t.name, t.type), - name: t.name, - version: t.version, - description: t.description, - css: t.css, - clientScripts: t.clientScripts - })) + .map(t => ({ + npmName: PluginModel.buildNpmName(t.name, t.type), + name: t.name, + version: t.version, + description: t.description, + css: t.css, + clientScripts: t.clientScripts + })) } getBuiltInThemes () { @@ -416,13 +415,13 @@ class ServerConfigManager { getRegisteredPlugins () { return PluginManager.Instance.getRegisteredPlugins() - .map(p => ({ - npmName: PluginModel.buildNpmName(p.name, p.type), - name: p.name, - version: p.version, - description: p.description, - clientScripts: p.clientScripts - })) + .map(p => ({ + npmName: PluginModel.buildNpmName(p.name, p.type), + name: p.name, + version: p.version, + description: p.description, + clientScripts: p.clientScripts + })) } getEnabledResolutions (type: 'vod' | 'live') { @@ -431,8 +430,8 @@ class ServerConfigManager { : CONFIG.LIVE.TRANSCODING return Object.keys(transcoding.RESOLUTIONS) - .filter(key => transcoding.ENABLED && transcoding.RESOLUTIONS[key] === true) - .map(r => parseInt(r, 10) as VideoResolutionType) + .filter(key => transcoding.ENABLED && transcoding.RESOLUTIONS[key] === true) + .map(r => parseInt(r, 10) as VideoResolutionType) } private getIdAndPassAuthPlugins () { diff --git a/server/core/models/user/user.ts b/server/core/models/user/user.ts index e6d2e0362..796ab0be7 100644 --- a/server/core/models/user/user.ts +++ b/server/core/models/user/user.ts @@ -2,15 +2,18 @@ import { forceNumber, hasUserRight, USER_ROLE_LABELS } from '@peertube/peertube- import { AbuseState, MyUser, + NSFWFlag, User, UserAdminFlag, UserRightType, + UserRole, VideoPlaylistType, type NSFWPolicyType, type UserAdminFlagType, - type UserRoleType, - UserRole + type UserRoleType } from '@peertube/peertube-models' +import { isNSFWFlagsValid } from '@server/helpers/custom-validators/videos.js' +import { CONFIG } from '@server/initializers/config.js' import { TokensCache } from '@server/lib/auth/tokens-cache.js' import { LiveQuotaStore } from '@server/lib/live/index.js' import { @@ -75,9 +78,8 @@ import { VideoImportModel } from '../video/video-import.js' import { VideoLiveModel } from '../video/video-live.js' import { VideoPlaylistModel } from '../video/video-playlist.js' import { VideoModel } from '../video/video.js' -import { UserNotificationSettingModel } from './user-notification-setting.js' import { UserExportModel } from './user-export.js' -import { isNSFWFlagsValid } from '@server/helpers/custom-validators/videos.js' +import { UserNotificationSettingModel } from './user-notification-setting.js' enum ScopeNames { FOR_ME_API = 'FOR_ME_API', @@ -999,10 +1001,22 @@ export class UserModel extends SequelizeModel { emailVerified: this.emailVerified, nsfwPolicy: this.nsfwPolicy, - nsfwFlagsDisplayed: this.nsfwFlagsDisplayed, - nsfwFlagsHidden: this.nsfwFlagsHidden, - nsfwFlagsWarned: this.nsfwFlagsWarned, - nsfwFlagsBlurred: this.nsfwFlagsBlurred, + + nsfwFlagsDisplayed: CONFIG.NSFW_FLAGS_SETTINGS.ENABLED + ? this.nsfwFlagsDisplayed + : NSFWFlag.NONE, + + nsfwFlagsHidden: CONFIG.NSFW_FLAGS_SETTINGS.ENABLED + ? this.nsfwFlagsHidden + : NSFWFlag.NONE, + + nsfwFlagsWarned: CONFIG.NSFW_FLAGS_SETTINGS.ENABLED + ? this.nsfwFlagsWarned + : NSFWFlag.NONE, + + nsfwFlagsBlurred: CONFIG.NSFW_FLAGS_SETTINGS.ENABLED + ? this.nsfwFlagsBlurred + : NSFWFlag.NONE, p2pEnabled: this.p2pEnabled,