aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.github/CONTRIBUTING.md2
-rw-r--r--config/dev.yaml105
-rw-r--r--config/test.yaml22
-rwxr-xr-xscripts/dev/client.sh6
-rwxr-xr-xscripts/dev/embed.sh4
-rwxr-xr-xscripts/dev/index.sh2
-rwxr-xr-xscripts/dev/server.sh2
-rw-r--r--server.ts4
-rw-r--r--server/controllers/api/oauth-clients.ts3
-rw-r--r--server/controllers/plugins.ts4
-rw-r--r--server/helpers/core-utils.ts9
-rw-r--r--server/helpers/custom-validators/activitypub/misc.ts4
-rw-r--r--server/helpers/custom-validators/servers.ts6
-rw-r--r--server/initializers/checker-after-init.ts7
-rw-r--r--server/initializers/constants.ts81
-rw-r--r--server/initializers/database.ts8
-rw-r--r--server/lib/client-html.ts4
-rw-r--r--server/lib/emailer.ts6
-rw-r--r--server/lib/job-queue/handlers/video-views-stats.ts4
-rw-r--r--server/lib/schedulers/actor-follow-scheduler.ts4
-rw-r--r--server/lib/schedulers/remove-old-jobs-scheduler.ts6
-rw-r--r--server/lib/views/shared/video-viewer-counters.ts4
-rw-r--r--server/lib/views/shared/video-viewer-stats.ts4
-rw-r--r--server/middlewares/validators/follows.ts6
-rw-r--r--server/middlewares/validators/oembed.ts4
-rw-r--r--support/doc/plugins/guide.md2
26 files changed, 207 insertions, 106 deletions
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 4bc590bde..e8570dd2b 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -216,7 +216,7 @@ Instance configurations are in `config/test-{1,2,3}.yaml`.
216To test emails with PeerTube: 216To test emails with PeerTube:
217 217
218 * Run [mailslurper](http://mailslurper.com/) 218 * Run [mailslurper](http://mailslurper.com/)
219 * Run PeerTube using mailslurper SMTP port: `NODE_CONFIG='{ "smtp": { "hostname": "localhost", "port": 2500, "tls": false } }' NODE_ENV=test npm start` 219 * Run PeerTube using mailslurper SMTP port: `NODE_CONFIG='{ "smtp": { "hostname": "localhost", "port": 2500, "tls": false } }' NODE_ENV=dev node dist/server`
220 220
221## Plugins & Themes 221## Plugins & Themes
222 222
diff --git a/config/dev.yaml b/config/dev.yaml
new file mode 100644
index 000000000..15e239b29
--- /dev/null
+++ b/config/dev.yaml
@@ -0,0 +1,105 @@
1listen:
2 hostname: '::'
3 port: 9000
4
5webserver:
6 https: false
7
8database:
9 hostname: 'localhost'
10 port: 5432
11
12redis:
13 hostname: 'localhost'
14
15smtp:
16 hostname: null
17 port: 1025
18 tls: false
19 disable_starttls: true
20 from_address: 'test-admin@localhost'
21 username: null
22 password: null
23
24log:
25 level: 'debug'
26
27contact_form:
28 enabled: true
29
30peertube:
31 check_latest_version:
32 enabled: false
33
34redundancy:
35 videos:
36 check_interval: '5 minutes'
37 strategies:
38 -
39 size: '1000MB'
40 min_lifetime: '10 minutes'
41 strategy: 'most-views'
42 -
43 size: '1000MB'
44 min_lifetime: '10 minutes'
45 strategy: 'trending'
46 -
47 size: '1000MB'
48 min_lifetime: '10 minutes'
49 strategy: 'recently-added'
50 min_views: 1
51
52cache:
53 previews:
54 size: 10
55 captions:
56 size: 10
57 torrents:
58 size: 10
59
60signup:
61 enabled: true
62 requires_email_verification: false
63
64live:
65 enabled: true
66
67 allow_replay: true
68
69 transcoding:
70 enabled: true
71 threads: 2
72
73 resolutions:
74 360p: true
75 720p: true
76
77import:
78 videos:
79 concurrency: 2
80 http:
81 enabled: true
82 torrent:
83 enabled: true
84
85instance:
86 default_nsfw_policy: 'display'
87
88plugins:
89 index:
90 check_latest_versions_interval: '10 minutes'
91
92federation:
93 videos:
94 cleanup_remote_interactions: false
95
96views:
97 videos:
98 remote:
99 max_age: -1
100
101geo_ip:
102 enabled: true
103
104video_studio:
105 enabled: true
diff --git a/config/test.yaml b/config/test.yaml
index 8118c479b..3e08f0ac8 100644
--- a/config/test.yaml
+++ b/config/test.yaml
@@ -133,28 +133,6 @@ plugins:
133 index: 133 index:
134 check_latest_versions_interval: '10 minutes' 134 check_latest_versions_interval: '10 minutes'
135 135
136search:
137 # Add ability to fetch remote videos/actors by their URI, that may not be federated with your instance
138 # If enabled, the associated group will be able to "escape" from the instance follows
139 # That means they will be able to follow channels, watch videos, list videos of non followed instances
140 remote_uri:
141 users: true
142 anonymous: false
143
144 # Use a third party index instead of your local index, only for search results
145 # Useful to discover content outside of your instance
146 search_index:
147 enabled: false
148 # URL of the search index, that should use the same search API and routes
149 # than PeerTube: https://docs.joinpeertube.org/api-rest-reference.html
150 # You should deploy your own with https://framagit.org/framasoft/peertube/search-index,
151 # and can use https://search.joinpeertube.org/ for tests, but keep in mind the latter is an unmoderated search index
152 url: 'http://localhost:3234'
153 # You can disable local search, so users only use the search index
154 disable_local_search: false
155 # If you did not disable local search, you can decide to use the search index by default
156 is_default_search: true
157
158federation: 136federation:
159 videos: 137 videos:
160 federate_unlisted: true 138 federate_unlisted: true
diff --git a/scripts/dev/client.sh b/scripts/dev/client.sh
index 1846f9a7d..92e8bb6ac 100755
--- a/scripts/dev/client.sh
+++ b/scripts/dev/client.sh
@@ -9,12 +9,12 @@ if [ ! -z ${2+x} ] && [ "$2" = "--ar-locale" ]; then
9fi 9fi
10 10
11clientCommand="cd client && node --max_old_space_size=4096 node_modules/.bin/ng serve --proxy-config proxy.config.json --hmr --configuration $clientConfiguration --host 0.0.0.0 --disable-host-check --port 3000" 11clientCommand="cd client && node --max_old_space_size=4096 node_modules/.bin/ng serve --proxy-config proxy.config.json --hmr --configuration $clientConfiguration --host 0.0.0.0 --disable-host-check --port 3000"
12serverCommand="npm run build:server && NODE_ENV=test node dist/server" 12serverCommand="npm run build:server && NODE_ENV=dev node dist/server"
13 13
14if [ ! -z ${1+x} ] && [ "$1" = "--skip-server" ]; then 14if [ ! -z ${1+x} ] && [ "$1" = "--skip-server" ]; then
15 NODE_ENV=test eval $clientCommand 15 eval $clientCommand
16else 16else
17 NODE_ENV=test node node_modules/.bin/concurrently -k \ 17 node node_modules/.bin/concurrently -k \
18 "$clientCommand" \ 18 "$clientCommand" \
19 "$serverCommand" 19 "$serverCommand"
20fi 20fi
diff --git a/scripts/dev/embed.sh b/scripts/dev/embed.sh
index b4835604e..e694950e6 100755
--- a/scripts/dev/embed.sh
+++ b/scripts/dev/embed.sh
@@ -2,6 +2,6 @@
2 2
3set -eu 3set -eu
4 4
5NODE_ENV=test npm run concurrently -- -k \ 5npm run concurrently -- -k \
6 "cd client && npm run webpack -- --config webpack/webpack.video-embed.js --mode development --watch" \ 6 "cd client && npm run webpack -- --config webpack/webpack.video-embed.js --mode development --watch" \
7 "npm run build:server && NODE_ENV=test npm start" 7 "npm run build:server && NODE_ENV=dev npm start"
diff --git a/scripts/dev/index.sh b/scripts/dev/index.sh
index beb88606f..7e0332115 100755
--- a/scripts/dev/index.sh
+++ b/scripts/dev/index.sh
@@ -2,6 +2,6 @@
2 2
3set -eu 3set -eu
4 4
5NODE_ENV=test npm run concurrently -- -k \ 5npm run concurrently -- -k \
6 "sh scripts/dev/client.sh --skip-server ${1:-}" \ 6 "sh scripts/dev/client.sh --skip-server ${1:-}" \
7 "sh scripts/dev/server.sh --skip-client" 7 "sh scripts/dev/server.sh --skip-client"
diff --git a/scripts/dev/server.sh b/scripts/dev/server.sh
index 9dae43a63..c52c5124c 100755
--- a/scripts/dev/server.sh
+++ b/scripts/dev/server.sh
@@ -22,4 +22,4 @@ npm run resolve-tspaths:server
22cp -r ./server/static ./server/assets ./dist/server 22cp -r ./server/static ./server/assets ./dist/server
23cp -r "./server/lib/emails" "./dist/server/lib" 23cp -r "./server/lib/emails" "./dist/server/lib"
24 24
25./node_modules/.bin/tsc-watch --build --preserveWatchOutput --verbose --onSuccess 'sh -c "npm run resolve-tspaths:server && NODE_ENV=test node dist/server"' 25./node_modules/.bin/tsc-watch --build --preserveWatchOutput --verbose --onSuccess 'sh -c "npm run resolve-tspaths:server && NODE_ENV=dev node dist/server"'
diff --git a/server.ts b/server.ts
index 73b7441f9..7ab20643b 100644
--- a/server.ts
+++ b/server.ts
@@ -134,7 +134,7 @@ import { HttpStatusCode } from './shared/models/http/http-error-codes'
134import { VideosTorrentCache } from '@server/lib/files-cache/videos-torrent-cache' 134import { VideosTorrentCache } from '@server/lib/files-cache/videos-torrent-cache'
135import { ServerConfigManager } from '@server/lib/server-config-manager' 135import { ServerConfigManager } from '@server/lib/server-config-manager'
136import { VideoViewsManager } from '@server/lib/views/video-views-manager' 136import { VideoViewsManager } from '@server/lib/views/video-views-manager'
137import { isTestInstance } from './server/helpers/core-utils' 137import { isTestOrDevInstance } from './server/helpers/core-utils'
138import { OpenTelemetryMetrics } from '@server/lib/opentelemetry/metrics' 138import { OpenTelemetryMetrics } from '@server/lib/opentelemetry/metrics'
139 139
140// ----------- Command line ----------- 140// ----------- Command line -----------
@@ -148,7 +148,7 @@ cli
148// ----------- App ----------- 148// ----------- App -----------
149 149
150// Enable CORS for develop 150// Enable CORS for develop
151if (isTestInstance()) { 151if (isTestOrDevInstance()) {
152 app.use(cors({ 152 app.use(cors({
153 origin: '*', 153 origin: '*',
154 exposedHeaders: 'Retry-After', 154 exposedHeaders: 'Retry-After',
diff --git a/server/controllers/api/oauth-clients.ts b/server/controllers/api/oauth-clients.ts
index 2d847bdc1..eb7942fd6 100644
--- a/server/controllers/api/oauth-clients.ts
+++ b/server/controllers/api/oauth-clients.ts
@@ -1,4 +1,5 @@
1import express from 'express' 1import express from 'express'
2import { isTestOrDevInstance } from '@server/helpers/core-utils'
2import { OAuthClientModel } from '@server/models/oauth/oauth-client' 3import { OAuthClientModel } from '@server/models/oauth/oauth-client'
3import { HttpStatusCode, OAuthClientLocal } from '@shared/models' 4import { HttpStatusCode, OAuthClientLocal } from '@shared/models'
4import { logger } from '../../helpers/logger' 5import { logger } from '../../helpers/logger'
@@ -22,7 +23,7 @@ async function getLocalClient (req: express.Request, res: express.Response, next
22 } 23 }
23 24
24 // Don't make this check if this is a test instance 25 // Don't make this check if this is a test instance
25 if (process.env.NODE_ENV !== 'test' && req.get('host') !== headerHostShouldBe) { 26 if (!isTestOrDevInstance() && req.get('host') !== headerHostShouldBe) {
26 logger.info('Getting client tokens for host %s is forbidden (expected %s).', req.get('host'), headerHostShouldBe) 27 logger.info('Getting client tokens for host %s is forbidden (expected %s).', req.get('host'), headerHostShouldBe)
27 return res.fail({ 28 return res.fail({
28 status: HttpStatusCode.FORBIDDEN_403, 29 status: HttpStatusCode.FORBIDDEN_403,
diff --git a/server/controllers/plugins.ts b/server/controllers/plugins.ts
index 28fffc9e1..51db1ad89 100644
--- a/server/controllers/plugins.ts
+++ b/server/controllers/plugins.ts
@@ -5,7 +5,7 @@ import { optionalAuthenticate } from '@server/middlewares/auth'
5import { getCompleteLocale, is18nLocale } from '../../shared/core-utils/i18n' 5import { getCompleteLocale, is18nLocale } from '../../shared/core-utils/i18n'
6import { HttpStatusCode } from '../../shared/models/http/http-error-codes' 6import { HttpStatusCode } from '../../shared/models/http/http-error-codes'
7import { PluginType } from '../../shared/models/plugins/plugin.type' 7import { PluginType } from '../../shared/models/plugins/plugin.type'
8import { isTestInstance } from '../helpers/core-utils' 8import { isProdInstance } from '../helpers/core-utils'
9import { PLUGIN_GLOBAL_CSS_PATH } from '../initializers/constants' 9import { PLUGIN_GLOBAL_CSS_PATH } from '../initializers/constants'
10import { PluginManager, RegisteredPlugin } from '../lib/plugins/plugin-manager' 10import { PluginManager, RegisteredPlugin } from '../lib/plugins/plugin-manager'
11import { getExternalAuthValidator, getPluginValidator, pluginStaticDirectoryValidator } from '../middlewares/validators/plugins' 11import { getExternalAuthValidator, getPluginValidator, pluginStaticDirectoryValidator } from '../middlewares/validators/plugins'
@@ -13,7 +13,7 @@ import { serveThemeCSSValidator } from '../middlewares/validators/themes'
13 13
14const sendFileOptions = { 14const sendFileOptions = {
15 maxAge: '30 days', 15 maxAge: '30 days',
16 immutable: !isTestInstance() 16 immutable: isProdInstance()
17} 17}
18 18
19const pluginsRouter = express.Router() 19const pluginsRouter = express.Router()
diff --git a/server/helpers/core-utils.ts b/server/helpers/core-utils.ts
index 6ebe8e2ac..4bbf0228d 100644
--- a/server/helpers/core-utils.ts
+++ b/server/helpers/core-utils.ts
@@ -165,6 +165,14 @@ function isTestInstance () {
165 return process.env.NODE_ENV === 'test' 165 return process.env.NODE_ENV === 'test'
166} 166}
167 167
168function isDevInstance () {
169 return process.env.NODE_ENV === 'dev'
170}
171
172function isTestOrDevInstance () {
173 return isTestInstance() || isDevInstance()
174}
175
168function isProdInstance () { 176function isProdInstance () {
169 return process.env.NODE_ENV === 'production' 177 return process.env.NODE_ENV === 'production'
170} 178}
@@ -270,6 +278,7 @@ const pipelinePromise = promisify(pipeline)
270 278
271export { 279export {
272 isTestInstance, 280 isTestInstance,
281 isTestOrDevInstance,
273 isProdInstance, 282 isProdInstance,
274 getAppNumber, 283 getAppNumber,
275 284
diff --git a/server/helpers/custom-validators/activitypub/misc.ts b/server/helpers/custom-validators/activitypub/misc.ts
index 9d823299f..ff15f115f 100644
--- a/server/helpers/custom-validators/activitypub/misc.ts
+++ b/server/helpers/custom-validators/activitypub/misc.ts
@@ -1,6 +1,6 @@
1import validator from 'validator' 1import validator from 'validator'
2import { CONSTRAINTS_FIELDS } from '../../../initializers/constants' 2import { CONSTRAINTS_FIELDS } from '../../../initializers/constants'
3import { isTestInstance } from '../../core-utils' 3import { isTestOrDevInstance } from '../../core-utils'
4import { exists } from '../misc' 4import { exists } from '../misc'
5 5
6function isUrlValid (url: string) { 6function isUrlValid (url: string) {
@@ -13,7 +13,7 @@ function isUrlValid (url: string) {
13 } 13 }
14 14
15 // We validate 'localhost', so we don't have the top level domain 15 // We validate 'localhost', so we don't have the top level domain
16 if (isTestInstance()) { 16 if (isTestOrDevInstance()) {
17 isURLOptions.require_tld = false 17 isURLOptions.require_tld = false
18 } 18 }
19 19
diff --git a/server/helpers/custom-validators/servers.ts b/server/helpers/custom-validators/servers.ts
index c0f8b6aeb..b9f45c282 100644
--- a/server/helpers/custom-validators/servers.ts
+++ b/server/helpers/custom-validators/servers.ts
@@ -1,7 +1,7 @@
1import validator from 'validator' 1import validator from 'validator'
2import { exists, isArray } from './misc'
3import { isTestInstance } from '../core-utils'
4import { CONSTRAINTS_FIELDS } from '../../initializers/constants' 2import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
3import { isTestOrDevInstance } from '../core-utils'
4import { exists, isArray } from './misc'
5 5
6function isHostValid (host: string) { 6function isHostValid (host: string) {
7 const isURLOptions = { 7 const isURLOptions = {
@@ -10,7 +10,7 @@ function isHostValid (host: string) {
10 } 10 }
11 11
12 // We validate 'localhost', so we don't have the top level domain 12 // We validate 'localhost', so we don't have the top level domain
13 if (isTestInstance()) { 13 if (isTestOrDevInstance()) {
14 isURLOptions.require_tld = false 14 isURLOptions.require_tld = false
15 } 15 }
16 16
diff --git a/server/initializers/checker-after-init.ts b/server/initializers/checker-after-init.ts
index f65798c42..e542a5395 100644
--- a/server/initializers/checker-after-init.ts
+++ b/server/initializers/checker-after-init.ts
@@ -4,7 +4,7 @@ import { URL } from 'url'
4import { getFFmpegVersion } from '@server/helpers/ffmpeg' 4import { getFFmpegVersion } from '@server/helpers/ffmpeg'
5import { VideoRedundancyConfigFilter } from '@shared/models/redundancy/video-redundancy-config-filter.type' 5import { VideoRedundancyConfigFilter } from '@shared/models/redundancy/video-redundancy-config-filter.type'
6import { RecentlyAddedStrategy } from '../../shared/models/redundancy' 6import { RecentlyAddedStrategy } from '../../shared/models/redundancy'
7import { isProdInstance, isTestInstance, parseSemVersion } from '../helpers/core-utils' 7import { isProdInstance, parseSemVersion } from '../helpers/core-utils'
8import { isArray } from '../helpers/custom-validators/misc' 8import { isArray } from '../helpers/custom-validators/misc'
9import { logger } from '../helpers/logger' 9import { logger } from '../helpers/logger'
10import { ApplicationModel, getServerActor } from '../models/application/application' 10import { ApplicationModel, getServerActor } from '../models/application/application'
@@ -34,6 +34,9 @@ async function checkActivityPubUrls () {
34// Some checks on configuration files or throw if there is an error 34// Some checks on configuration files or throw if there is an error
35function checkConfig () { 35function checkConfig () {
36 36
37 const configFiles = config.util.getConfigSources().map(s => s.name).join(' -> ')
38 logger.info('Using following configuration file hierarchy: %s.', configFiles)
39
37 // Moved configuration keys 40 // Moved configuration keys
38 if (config.has('services.csp-logger')) { 41 if (config.has('services.csp-logger')) {
39 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.')
@@ -128,7 +131,7 @@ function checkLocalRedundancyConfig () {
128 } 131 }
129 132
130 // Lifetime should not be < 10 hours 133 // Lifetime should not be < 10 hours
131 if (!isTestInstance() && r.minLifetime < 1000 * 3600 * 10) { 134 if (isProdInstance() && r.minLifetime < 1000 * 3600 * 10) {
132 throw new Error('Video redundancy minimum lifetime should be >= 10 hours for strategy ' + r.strategy) 135 throw new Error('Video redundancy minimum lifetime should be >= 10 hours for strategy ' + r.strategy)
133 } 136 }
134 } 137 }
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts
index e3683269c..009f878fc 100644
--- a/server/initializers/constants.ts
+++ b/server/initializers/constants.ts
@@ -19,7 +19,7 @@ import { NSFWPolicyType } from '../../shared/models/videos/nsfw-policy.type'
19import { VideoPlaylistPrivacy } from '../../shared/models/videos/playlist/video-playlist-privacy.model' 19import { VideoPlaylistPrivacy } from '../../shared/models/videos/playlist/video-playlist-privacy.model'
20import { VideoPlaylistType } from '../../shared/models/videos/playlist/video-playlist-type.model' 20import { VideoPlaylistType } from '../../shared/models/videos/playlist/video-playlist-type.model'
21// Do not use barrels, remain constants as independent as possible 21// Do not use barrels, remain constants as independent as possible
22import { isTestInstance, parseDurationToMs, sanitizeHost, sanitizeUrl } from '../helpers/core-utils' 22import { isTestInstance, isTestOrDevInstance, parseDurationToMs, sanitizeHost, sanitizeUrl } from '../helpers/core-utils'
23import { CONFIG, registerConfigChangedHandler } from './config' 23import { CONFIG, registerConfigChangedHandler } from './config'
24 24
25// --------------------------------------------------------------------------- 25// ---------------------------------------------------------------------------
@@ -822,57 +822,62 @@ const STATS_TIMESERIE = {
822// --------------------------------------------------------------------------- 822// ---------------------------------------------------------------------------
823 823
824// Special constants for a test instance 824// Special constants for a test instance
825if (isTestInstance() === true && process.env.PRODUCTION_CONSTANTS !== 'true') { 825if (process.env.PRODUCTION_CONSTANTS !== 'true') {
826 PRIVATE_RSA_KEY_SIZE = 1024 826 if (isTestOrDevInstance()) {
827 PRIVATE_RSA_KEY_SIZE = 1024
827 828
828 ACTOR_FOLLOW_SCORE.BASE = 20 829 ACTOR_FOLLOW_SCORE.BASE = 20
829 830
830 REMOTE_SCHEME.HTTP = 'http' 831 REMOTE_SCHEME.HTTP = 'http'
831 REMOTE_SCHEME.WS = 'ws' 832 REMOTE_SCHEME.WS = 'ws'
832 833
833 STATIC_MAX_AGE.SERVER = '0' 834 STATIC_MAX_AGE.SERVER = '0'
834 835
835 ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE = 2 836 SCHEDULER_INTERVALS_MS.ACTOR_FOLLOW_SCORES = 1000
836 ACTIVITY_PUB.ACTOR_REFRESH_INTERVAL = 10 * 1000 // 10 seconds 837 SCHEDULER_INTERVALS_MS.REMOVE_OLD_JOBS = 10000
837 ACTIVITY_PUB.VIDEO_REFRESH_INTERVAL = 10 * 1000 // 10 seconds 838 SCHEDULER_INTERVALS_MS.REMOVE_OLD_HISTORY = 5000
838 ACTIVITY_PUB.VIDEO_PLAYLIST_REFRESH_INTERVAL = 10 * 1000 // 10 seconds 839 SCHEDULER_INTERVALS_MS.REMOVE_OLD_VIEWS = 5000
840 SCHEDULER_INTERVALS_MS.UPDATE_VIDEOS = 5000
841 SCHEDULER_INTERVALS_MS.AUTO_FOLLOW_INDEX_INSTANCES = 5000
842 SCHEDULER_INTERVALS_MS.UPDATE_INBOX_STATS = 5000
843 SCHEDULER_INTERVALS_MS.CHECK_PEERTUBE_VERSION = 2000
839 844
840 CONSTRAINTS_FIELDS.ACTORS.IMAGE.FILE_SIZE.max = 100 * 1024 // 100KB 845 REPEAT_JOBS['videos-views-stats'] = { every: 5000 }
841 CONSTRAINTS_FIELDS.VIDEOS.IMAGE.FILE_SIZE.max = 400 * 1024 // 400KB
842 846
843 SCHEDULER_INTERVALS_MS.ACTOR_FOLLOW_SCORES = 1000 847 REPEAT_JOBS['activitypub-cleaner'] = { every: 5000 }
844 SCHEDULER_INTERVALS_MS.REMOVE_OLD_JOBS = 10000 848 AP_CLEANER.PERIOD = 5000
845 SCHEDULER_INTERVALS_MS.REMOVE_OLD_HISTORY = 5000
846 SCHEDULER_INTERVALS_MS.REMOVE_OLD_VIEWS = 5000
847 SCHEDULER_INTERVALS_MS.UPDATE_VIDEOS = 5000
848 SCHEDULER_INTERVALS_MS.AUTO_FOLLOW_INDEX_INSTANCES = 5000
849 SCHEDULER_INTERVALS_MS.UPDATE_INBOX_STATS = 5000
850 SCHEDULER_INTERVALS_MS.CHECK_PEERTUBE_VERSION = 2000
851 849
852 REPEAT_JOBS['videos-views-stats'] = { every: 5000 } 850 REDUNDANCY.VIDEOS.RANDOMIZED_FACTOR = 1
853 851
854 REPEAT_JOBS['activitypub-cleaner'] = { every: 5000 } 852 CONTACT_FORM_LIFETIME = 1000 // 1 second
855 AP_CLEANER.PERIOD = 5000
856 853
857 REDUNDANCY.VIDEOS.RANDOMIZED_FACTOR = 1 854 JOB_ATTEMPTS['email'] = 1
858 855
859 VIEW_LIFETIME.VIEWER_COUNTER = 1000 * 5 // 5 second 856 FILES_CACHE.VIDEO_CAPTIONS.MAX_AGE = 3000
860 VIEW_LIFETIME.VIEWER_STATS = 1000 * 5 // 5 second 857 MEMOIZE_TTL.OVERVIEWS_SAMPLE = 3000
861 CONTACT_FORM_LIFETIME = 1000 // 1 second 858 MEMOIZE_TTL.LIVE_ABLE_TO_UPLOAD = 3000
859 OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD = 2
862 860
863 JOB_ATTEMPTS['email'] = 1 861 PLUGIN_EXTERNAL_AUTH_TOKEN_LIFETIME = 5000
862 }
863
864 if (isTestInstance()) {
865 ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE = 2
866 ACTIVITY_PUB.ACTOR_REFRESH_INTERVAL = 10 * 1000 // 10 seconds
867 ACTIVITY_PUB.VIDEO_REFRESH_INTERVAL = 10 * 1000 // 10 seconds
868 ACTIVITY_PUB.VIDEO_PLAYLIST_REFRESH_INTERVAL = 10 * 1000 // 10 seconds
864 869
865 FILES_CACHE.VIDEO_CAPTIONS.MAX_AGE = 3000 870 CONSTRAINTS_FIELDS.ACTORS.IMAGE.FILE_SIZE.max = 100 * 1024 // 100KB
866 MEMOIZE_TTL.OVERVIEWS_SAMPLE = 3000 871 CONSTRAINTS_FIELDS.VIDEOS.IMAGE.FILE_SIZE.max = 400 * 1024 // 400KB
867 MEMOIZE_TTL.LIVE_ABLE_TO_UPLOAD = 3000
868 OVERVIEWS.VIDEOS.SAMPLE_THRESHOLD = 2
869 872
870 PLUGIN_EXTERNAL_AUTH_TOKEN_LIFETIME = 5000 873 VIEW_LIFETIME.VIEWER_COUNTER = 1000 * 5 // 5 second
874 VIEW_LIFETIME.VIEWER_STATS = 1000 * 5 // 5 second
871 875
872 VIDEO_LIVE.CLEANUP_DELAY = getIntEnv('PEERTUBE_TEST_CONSTANTS_VIDEO_LIVE_CLEANUP_DELAY') ?? 5000 876 VIDEO_LIVE.CLEANUP_DELAY = getIntEnv('PEERTUBE_TEST_CONSTANTS_VIDEO_LIVE_CLEANUP_DELAY') ?? 5000
873 VIDEO_LIVE.SEGMENT_TIME_SECONDS.DEFAULT_LATENCY = 2 877 VIDEO_LIVE.SEGMENT_TIME_SECONDS.DEFAULT_LATENCY = 2
874 VIDEO_LIVE.SEGMENT_TIME_SECONDS.SMALL_LATENCY = 1 878 VIDEO_LIVE.SEGMENT_TIME_SECONDS.SMALL_LATENCY = 1
875 VIDEO_LIVE.EDGE_LIVE_DELAY_SEGMENTS_NOTIFICATION = 1 879 VIDEO_LIVE.EDGE_LIVE_DELAY_SEGMENTS_NOTIFICATION = 1
880 }
876} 881}
877 882
878updateWebserverUrls() 883updateWebserverUrls()
diff --git a/server/initializers/database.ts b/server/initializers/database.ts
index 09786a91f..91286241b 100644
--- a/server/initializers/database.ts
+++ b/server/initializers/database.ts
@@ -8,9 +8,10 @@ import { UserNotificationModel } from '@server/models/user/user-notification'
8import { UserVideoHistoryModel } from '@server/models/user/user-video-history' 8import { UserVideoHistoryModel } from '@server/models/user/user-video-history'
9import { VideoJobInfoModel } from '@server/models/video/video-job-info' 9import { VideoJobInfoModel } from '@server/models/video/video-job-info'
10import { VideoLiveSessionModel } from '@server/models/video/video-live-session' 10import { VideoLiveSessionModel } from '@server/models/video/video-live-session'
11import { VideoSourceModel } from '@server/models/video/video-source'
11import { LocalVideoViewerModel } from '@server/models/view/local-video-viewer' 12import { LocalVideoViewerModel } from '@server/models/view/local-video-viewer'
12import { LocalVideoViewerWatchSectionModel } from '@server/models/view/local-video-viewer-watch-section' 13import { LocalVideoViewerWatchSectionModel } from '@server/models/view/local-video-viewer-watch-section'
13import { isTestInstance } from '../helpers/core-utils' 14import { isTestOrDevInstance } from '../helpers/core-utils'
14import { logger } from '../helpers/logger' 15import { logger } from '../helpers/logger'
15import { AbuseModel } from '../models/abuse/abuse' 16import { AbuseModel } from '../models/abuse/abuse'
16import { AbuseMessageModel } from '../models/abuse/abuse-message' 17import { AbuseMessageModel } from '../models/abuse/abuse-message'
@@ -49,7 +50,6 @@ import { VideoStreamingPlaylistModel } from '../models/video/video-streaming-pla
49import { VideoTagModel } from '../models/video/video-tag' 50import { VideoTagModel } from '../models/video/video-tag'
50import { VideoViewModel } from '../models/view/video-view' 51import { VideoViewModel } from '../models/view/video-view'
51import { CONFIG } from './config' 52import { CONFIG } from './config'
52import { VideoSourceModel } from '@server/models/video/video-source'
53 53
54require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string 54require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string
55 55
@@ -81,13 +81,13 @@ const sequelizeTypescript = new SequelizeTypescript({
81 pool: { 81 pool: {
82 max: poolMax 82 max: poolMax
83 }, 83 },
84 benchmark: isTestInstance(), 84 benchmark: isTestOrDevInstance(),
85 isolationLevel: Transaction.ISOLATION_LEVELS.SERIALIZABLE, 85 isolationLevel: Transaction.ISOLATION_LEVELS.SERIALIZABLE,
86 logging: (message: string, benchmark: number) => { 86 logging: (message: string, benchmark: number) => {
87 if (process.env.NODE_DB_LOG === 'false') return 87 if (process.env.NODE_DB_LOG === 'false') return
88 88
89 let newMessage = 'Executed SQL request' 89 let newMessage = 'Executed SQL request'
90 if (isTestInstance() === true && benchmark !== undefined) { 90 if (isTestOrDevInstance() === true && benchmark !== undefined) {
91 newMessage += ' in ' + benchmark + 'ms' 91 newMessage += ' in ' + benchmark + 'ms'
92 } 92 }
93 93
diff --git a/server/lib/client-html.ts b/server/lib/client-html.ts
index 1e8d03023..899d80c15 100644
--- a/server/lib/client-html.ts
+++ b/server/lib/client-html.ts
@@ -2,6 +2,7 @@ import express from 'express'
2import { readFile } from 'fs-extra' 2import { readFile } from 'fs-extra'
3import { join } from 'path' 3import { join } from 'path'
4import validator from 'validator' 4import validator from 'validator'
5import { isTestOrDevInstance } from '@server/helpers/core-utils'
5import { toCompleteUUID } from '@server/helpers/custom-validators/misc' 6import { toCompleteUUID } from '@server/helpers/custom-validators/misc'
6import { mdToOneLinePlainText } from '@server/helpers/markdown' 7import { mdToOneLinePlainText } from '@server/helpers/markdown'
7import { ActorImageModel } from '@server/models/actor/actor-image' 8import { ActorImageModel } from '@server/models/actor/actor-image'
@@ -30,7 +31,6 @@ import { MAccountActor, MChannelActor } from '../types/models'
30import { getActivityStreamDuration } from './activitypub/activity' 31import { getActivityStreamDuration } from './activitypub/activity'
31import { getBiggestActorImage } from './actor-image' 32import { getBiggestActorImage } from './actor-image'
32import { ServerConfigManager } from './server-config-manager' 33import { ServerConfigManager } from './server-config-manager'
33import { isTestInstance } from '@server/helpers/core-utils'
34 34
35type Tags = { 35type Tags = {
36 ogType: string 36 ogType: string
@@ -234,7 +234,7 @@ class ClientHtml {
234 const path = ClientHtml.getEmbedPath() 234 const path = ClientHtml.getEmbedPath()
235 235
236 // Disable HTML cache in dev mode because webpack can regenerate JS files 236 // Disable HTML cache in dev mode because webpack can regenerate JS files
237 if (!isTestInstance() && ClientHtml.htmlCache[path]) { 237 if (!isTestOrDevInstance() && ClientHtml.htmlCache[path]) {
238 return ClientHtml.htmlCache[path] 238 return ClientHtml.htmlCache[path]
239 } 239 }
240 240
diff --git a/server/lib/emailer.ts b/server/lib/emailer.ts
index edc99057c..42d7650dd 100644
--- a/server/lib/emailer.ts
+++ b/server/lib/emailer.ts
@@ -2,10 +2,10 @@ import { readFileSync } from 'fs-extra'
2import { isArray, merge } from 'lodash' 2import { isArray, merge } from 'lodash'
3import { createTransport, Transporter } from 'nodemailer' 3import { createTransport, Transporter } from 'nodemailer'
4import { join } from 'path' 4import { join } from 'path'
5import { root } from '@shared/core-utils'
5import { EmailPayload } from '@shared/models' 6import { EmailPayload } from '@shared/models'
6import { SendEmailDefaultOptions } from '../../shared/models/server/emailer.model' 7import { SendEmailDefaultOptions } from '../../shared/models/server/emailer.model'
7import { isTestInstance } from '../helpers/core-utils' 8import { isTestOrDevInstance } from '../helpers/core-utils'
8import { root } from '@shared/core-utils'
9import { bunyanLogger, logger } from '../helpers/logger' 9import { bunyanLogger, logger } from '../helpers/logger'
10import { CONFIG, isEmailEnabled } from '../initializers/config' 10import { CONFIG, isEmailEnabled } from '../initializers/config'
11import { WEBSERVER } from '../initializers/constants' 11import { WEBSERVER } from '../initializers/constants'
@@ -29,7 +29,7 @@ class Emailer {
29 this.initialized = true 29 this.initialized = true
30 30
31 if (!isEmailEnabled()) { 31 if (!isEmailEnabled()) {
32 if (!isTestInstance()) { 32 if (!isTestOrDevInstance()) {
33 logger.error('Cannot use SMTP server because of lack of configuration. PeerTube will not be able to send mails!') 33 logger.error('Cannot use SMTP server because of lack of configuration. PeerTube will not be able to send mails!')
34 } 34 }
35 35
diff --git a/server/lib/job-queue/handlers/video-views-stats.ts b/server/lib/job-queue/handlers/video-views-stats.ts
index 689a5a3b4..c9aa218e5 100644
--- a/server/lib/job-queue/handlers/video-views-stats.ts
+++ b/server/lib/job-queue/handlers/video-views-stats.ts
@@ -1,5 +1,5 @@
1import { VideoViewModel } from '@server/models/view/video-view' 1import { VideoViewModel } from '@server/models/view/video-view'
2import { isTestInstance } from '../../../helpers/core-utils' 2import { isTestOrDevInstance } from '../../../helpers/core-utils'
3import { logger } from '../../../helpers/logger' 3import { logger } from '../../../helpers/logger'
4import { VideoModel } from '../../../models/video/video' 4import { VideoModel } from '../../../models/video/video'
5import { Redis } from '../../redis' 5import { Redis } from '../../redis'
@@ -8,7 +8,7 @@ async function processVideosViewsStats () {
8 const lastHour = new Date() 8 const lastHour = new Date()
9 9
10 // In test mode, we run this function multiple times per hour, so we don't want the values of the previous hour 10 // In test mode, we run this function multiple times per hour, so we don't want the values of the previous hour
11 if (!isTestInstance()) lastHour.setHours(lastHour.getHours() - 1) 11 if (!isTestOrDevInstance()) lastHour.setHours(lastHour.getHours() - 1)
12 12
13 const hour = lastHour.getHours() 13 const hour = lastHour.getHours()
14 const startDate = lastHour.setMinutes(0, 0, 0) 14 const startDate = lastHour.setMinutes(0, 0, 0)
diff --git a/server/lib/schedulers/actor-follow-scheduler.ts b/server/lib/schedulers/actor-follow-scheduler.ts
index 560f97f3e..e1c56c135 100644
--- a/server/lib/schedulers/actor-follow-scheduler.ts
+++ b/server/lib/schedulers/actor-follow-scheduler.ts
@@ -1,4 +1,4 @@
1import { isTestInstance } from '../../helpers/core-utils' 1import { isTestOrDevInstance } from '../../helpers/core-utils'
2import { logger } from '../../helpers/logger' 2import { logger } from '../../helpers/logger'
3import { ACTOR_FOLLOW_SCORE, SCHEDULER_INTERVALS_MS } from '../../initializers/constants' 3import { ACTOR_FOLLOW_SCORE, SCHEDULER_INTERVALS_MS } from '../../initializers/constants'
4import { ActorFollowModel } from '../../models/actor/actor-follow' 4import { ActorFollowModel } from '../../models/actor/actor-follow'
@@ -39,7 +39,7 @@ export class ActorFollowScheduler extends AbstractScheduler {
39 } 39 }
40 40
41 private async removeBadActorFollows () { 41 private async removeBadActorFollows () {
42 if (!isTestInstance()) logger.info('Removing bad actor follows (scheduler).') 42 if (!isTestOrDevInstance()) logger.info('Removing bad actor follows (scheduler).')
43 43
44 try { 44 try {
45 await ActorFollowModel.removeBadActorFollows() 45 await ActorFollowModel.removeBadActorFollows()
diff --git a/server/lib/schedulers/remove-old-jobs-scheduler.ts b/server/lib/schedulers/remove-old-jobs-scheduler.ts
index dffef3542..879846999 100644
--- a/server/lib/schedulers/remove-old-jobs-scheduler.ts
+++ b/server/lib/schedulers/remove-old-jobs-scheduler.ts
@@ -1,8 +1,8 @@
1import { isTestInstance } from '../../helpers/core-utils' 1import { isTestOrDevInstance } from '../../helpers/core-utils'
2import { logger } from '../../helpers/logger' 2import { logger } from '../../helpers/logger'
3import { SCHEDULER_INTERVALS_MS } from '../../initializers/constants'
3import { JobQueue } from '../job-queue' 4import { JobQueue } from '../job-queue'
4import { AbstractScheduler } from './abstract-scheduler' 5import { AbstractScheduler } from './abstract-scheduler'
5import { SCHEDULER_INTERVALS_MS } from '../../initializers/constants'
6 6
7export class RemoveOldJobsScheduler extends AbstractScheduler { 7export class RemoveOldJobsScheduler extends AbstractScheduler {
8 8
@@ -15,7 +15,7 @@ export class RemoveOldJobsScheduler extends AbstractScheduler {
15 } 15 }
16 16
17 protected internalExecute () { 17 protected internalExecute () {
18 if (!isTestInstance()) logger.info('Removing old jobs in scheduler.') 18 if (!isTestOrDevInstance()) logger.info('Removing old jobs in scheduler.')
19 19
20 return JobQueue.Instance.removeOldJobs() 20 return JobQueue.Instance.removeOldJobs()
21 } 21 }
diff --git a/server/lib/views/shared/video-viewer-counters.ts b/server/lib/views/shared/video-viewer-counters.ts
index cf3fa5882..f851ce050 100644
--- a/server/lib/views/shared/video-viewer-counters.ts
+++ b/server/lib/views/shared/video-viewer-counters.ts
@@ -1,4 +1,4 @@
1import { isTestInstance } from '@server/helpers/core-utils' 1import { isTestOrDevInstance } from '@server/helpers/core-utils'
2import { logger, loggerTagsFactory } from '@server/helpers/logger' 2import { logger, loggerTagsFactory } from '@server/helpers/logger'
3import { VIEW_LIFETIME } from '@server/initializers/constants' 3import { VIEW_LIFETIME } from '@server/initializers/constants'
4import { sendView } from '@server/lib/activitypub/send/send-view' 4import { sendView } from '@server/lib/activitypub/send/send-view'
@@ -117,7 +117,7 @@ export class VideoViewerCounters {
117 if (this.processingViewerCounters) return 117 if (this.processingViewerCounters) return
118 this.processingViewerCounters = true 118 this.processingViewerCounters = true
119 119
120 if (!isTestInstance()) logger.info('Cleaning video viewers.', lTags()) 120 if (!isTestOrDevInstance()) logger.info('Cleaning video viewers.', lTags())
121 121
122 try { 122 try {
123 for (const videoId of this.viewersPerVideo.keys()) { 123 for (const videoId of this.viewersPerVideo.keys()) {
diff --git a/server/lib/views/shared/video-viewer-stats.ts b/server/lib/views/shared/video-viewer-stats.ts
index a56c20559..542bd51cf 100644
--- a/server/lib/views/shared/video-viewer-stats.ts
+++ b/server/lib/views/shared/video-viewer-stats.ts
@@ -1,5 +1,5 @@
1import { Transaction } from 'sequelize/types' 1import { Transaction } from 'sequelize/types'
2import { isTestInstance } from '@server/helpers/core-utils' 2import { isTestOrDevInstance } from '@server/helpers/core-utils'
3import { GeoIP } from '@server/helpers/geo-ip' 3import { GeoIP } from '@server/helpers/geo-ip'
4import { logger, loggerTagsFactory } from '@server/helpers/logger' 4import { logger, loggerTagsFactory } from '@server/helpers/logger'
5import { MAX_LOCAL_VIEWER_WATCH_SECTIONS, VIEW_LIFETIME } from '@server/initializers/constants' 5import { MAX_LOCAL_VIEWER_WATCH_SECTIONS, VIEW_LIFETIME } from '@server/initializers/constants'
@@ -118,7 +118,7 @@ export class VideoViewerStats {
118 if (this.processingViewersStats) return 118 if (this.processingViewersStats) return
119 this.processingViewersStats = true 119 this.processingViewersStats = true
120 120
121 if (!isTestInstance()) logger.info('Processing viewer statistics.', lTags()) 121 if (!isTestOrDevInstance()) logger.info('Processing viewer statistics.', lTags())
122 122
123 const now = new Date().getTime() 123 const now = new Date().getTime()
124 124
diff --git a/server/middlewares/validators/follows.ts b/server/middlewares/validators/follows.ts
index df4cefe28..86d2d6228 100644
--- a/server/middlewares/validators/follows.ts
+++ b/server/middlewares/validators/follows.ts
@@ -1,12 +1,13 @@
1import express from 'express' 1import express from 'express'
2import { body, param, query } from 'express-validator' 2import { body, param, query } from 'express-validator'
3import { isProdInstance } from '@server/helpers/core-utils'
3import { isEachUniqueHandleValid, isFollowStateValid, isRemoteHandleValid } from '@server/helpers/custom-validators/follows' 4import { isEachUniqueHandleValid, isFollowStateValid, isRemoteHandleValid } from '@server/helpers/custom-validators/follows'
4import { loadActorUrlOrGetFromWebfinger } from '@server/lib/activitypub/actors' 5import { loadActorUrlOrGetFromWebfinger } from '@server/lib/activitypub/actors'
5import { getRemoteNameAndHost } from '@server/lib/activitypub/follow' 6import { getRemoteNameAndHost } from '@server/lib/activitypub/follow'
6import { getServerActor } from '@server/models/application/application' 7import { getServerActor } from '@server/models/application/application'
7import { MActorFollowActorsDefault } from '@server/types/models' 8import { MActorFollowActorsDefault } from '@server/types/models'
9import { ServerFollowCreate } from '@shared/models'
8import { HttpStatusCode } from '../../../shared/models/http/http-error-codes' 10import { HttpStatusCode } from '../../../shared/models/http/http-error-codes'
9import { isTestInstance } from '../../helpers/core-utils'
10import { isActorTypeValid, isValidActorHandle } from '../../helpers/custom-validators/activitypub/actor' 11import { isActorTypeValid, isValidActorHandle } from '../../helpers/custom-validators/activitypub/actor'
11import { isEachUniqueHostValid, isHostValid } from '../../helpers/custom-validators/servers' 12import { isEachUniqueHostValid, isHostValid } from '../../helpers/custom-validators/servers'
12import { logger } from '../../helpers/logger' 13import { logger } from '../../helpers/logger'
@@ -14,7 +15,6 @@ import { WEBSERVER } from '../../initializers/constants'
14import { ActorModel } from '../../models/actor/actor' 15import { ActorModel } from '../../models/actor/actor'
15import { ActorFollowModel } from '../../models/actor/actor-follow' 16import { ActorFollowModel } from '../../models/actor/actor-follow'
16import { areValidationErrors } from './shared' 17import { areValidationErrors } from './shared'
17import { ServerFollowCreate } from '@shared/models'
18 18
19const listFollowsValidator = [ 19const listFollowsValidator = [
20 query('state') 20 query('state')
@@ -42,7 +42,7 @@ const followValidator = [
42 42
43 (req: express.Request, res: express.Response, next: express.NextFunction) => { 43 (req: express.Request, res: express.Response, next: express.NextFunction) => {
44 // Force https if the administrator wants to follow remote actors 44 // Force https if the administrator wants to follow remote actors
45 if (isTestInstance() === false && WEBSERVER.SCHEME === 'http') { 45 if (isProdInstance() && WEBSERVER.SCHEME === 'http') {
46 return res 46 return res
47 .status(HttpStatusCode.INTERNAL_SERVER_ERROR_500) 47 .status(HttpStatusCode.INTERNAL_SERVER_ERROR_500)
48 .json({ 48 .json({
diff --git a/server/middlewares/validators/oembed.ts b/server/middlewares/validators/oembed.ts
index fc1a294e0..8e7b44a86 100644
--- a/server/middlewares/validators/oembed.ts
+++ b/server/middlewares/validators/oembed.ts
@@ -5,7 +5,7 @@ import { loadVideo } from '@server/lib/model-loaders'
5import { VideoPlaylistModel } from '@server/models/video/video-playlist' 5import { VideoPlaylistModel } from '@server/models/video/video-playlist'
6import { VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models' 6import { VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models'
7import { HttpStatusCode } from '../../../shared/models/http/http-error-codes' 7import { HttpStatusCode } from '../../../shared/models/http/http-error-codes'
8import { isTestInstance } from '../../helpers/core-utils' 8import { isTestOrDevInstance } from '../../helpers/core-utils'
9import { isIdOrUUIDValid, isUUIDValid, toCompleteUUID } from '../../helpers/custom-validators/misc' 9import { isIdOrUUIDValid, isUUIDValid, toCompleteUUID } from '../../helpers/custom-validators/misc'
10import { logger } from '../../helpers/logger' 10import { logger } from '../../helpers/logger'
11import { WEBSERVER } from '../../initializers/constants' 11import { WEBSERVER } from '../../initializers/constants'
@@ -34,7 +34,7 @@ const isURLOptions = {
34} 34}
35 35
36// We validate 'localhost', so we don't have the top level domain 36// We validate 'localhost', so we don't have the top level domain
37if (isTestInstance()) { 37if (isTestOrDevInstance()) {
38 isURLOptions.require_tld = false 38 isURLOptions.require_tld = false
39} 39}
40 40
diff --git a/support/doc/plugins/guide.md b/support/doc/plugins/guide.md
index e460f214e..e567e6c1b 100644
--- a/support/doc/plugins/guide.md
+++ b/support/doc/plugins/guide.md
@@ -1036,7 +1036,7 @@ $ npm run setup:cli
1036 * Run PeerTube (you can access to your instance on http://localhost:9000): 1036 * Run PeerTube (you can access to your instance on http://localhost:9000):
1037 1037
1038``` 1038```
1039$ NODE_ENV=test npm start 1039$ NODE_ENV=dev npm start
1040``` 1040```
1041 1041
1042 * Register the instance via the CLI: 1042 * Register the instance via the CLI: