diff options
author | Chocobozzz <me@florianbigard.com> | 2019-04-10 09:23:18 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2019-04-10 09:23:18 +0200 |
commit | 31b6ddf86652502e0c96d77fa10861ce4af11aa4 (patch) | |
tree | b94402972945699134b2a504af5d551124f0bf54 | |
parent | 22834691abb6e74d31654ffd2ebeaaaa8ef3ac7b (diff) | |
download | PeerTube-31b6ddf86652502e0c96d77fa10861ce4af11aa4.tar.gz PeerTube-31b6ddf86652502e0c96d77fa10861ce4af11aa4.tar.zst PeerTube-31b6ddf86652502e0c96d77fa10861ce4af11aa4.zip |
Add ability to disable tracker
-rw-r--r-- | client/src/app/core/server/server.service.ts | 3 | ||||
-rw-r--r-- | client/src/app/shared/instance/instance-features-table.component.ts | 5 | ||||
-rw-r--r-- | client/src/app/videos/+video-watch/video-watch.component.scss | 1 | ||||
-rw-r--r-- | client/src/app/videos/+video-watch/video-watch.component.ts | 18 | ||||
-rw-r--r-- | client/src/assets/player/utils.ts | 5 | ||||
-rw-r--r-- | client/src/sass/player/peertube-skin.scss | 6 | ||||
-rw-r--r-- | client/src/standalone/videos/embed.ts | 26 | ||||
-rw-r--r-- | config/default.yaml | 10 | ||||
-rw-r--r-- | config/production.yaml.example | 10 | ||||
-rw-r--r-- | server/controllers/api/config.ts | 3 | ||||
-rw-r--r-- | server/controllers/tracker.ts | 23 | ||||
-rw-r--r-- | server/initializers/checker-before-init.ts | 3 | ||||
-rw-r--r-- | server/initializers/constants.ts | 5 | ||||
-rw-r--r-- | server/tests/api/server/tracker.ts | 26 | ||||
-rw-r--r-- | shared/models/server/server-config.model.ts | 4 | ||||
-rw-r--r-- | support/docker/production/config/production.yaml | 4 |
16 files changed, 123 insertions, 29 deletions
diff --git a/client/src/app/core/server/server.service.ts b/client/src/app/core/server/server.service.ts index b0c5d1130..3a8a535fd 100644 --- a/client/src/app/core/server/server.service.ts +++ b/client/src/app/core/server/server.service.ts | |||
@@ -105,6 +105,9 @@ export class ServerService { | |||
105 | enabled: false | 105 | enabled: false |
106 | } | 106 | } |
107 | } | 107 | } |
108 | }, | ||
109 | tracker: { | ||
110 | enabled: true | ||
108 | } | 111 | } |
109 | } | 112 | } |
110 | private videoCategories: Array<VideoConstant<number>> = [] | 113 | private videoCategories: Array<VideoConstant<number>> = [] |
diff --git a/client/src/app/shared/instance/instance-features-table.component.ts b/client/src/app/shared/instance/instance-features-table.component.ts index c0257fd59..72e7c2730 100644 --- a/client/src/app/shared/instance/instance-features-table.component.ts +++ b/client/src/app/shared/instance/instance-features-table.component.ts | |||
@@ -1,7 +1,6 @@ | |||
1 | import { Component, OnInit } from '@angular/core' | 1 | import { Component, OnInit } from '@angular/core' |
2 | import { ServerService } from '@app/core' | 2 | import { ServerService } from '@app/core' |
3 | import { I18n } from '@ngx-translate/i18n-polyfill' | 3 | import { I18n } from '@ngx-translate/i18n-polyfill' |
4 | import { ServerConfig } from '../../../../../shared' | ||
5 | 4 | ||
6 | @Component({ | 5 | @Component({ |
7 | selector: 'my-instance-features-table', | 6 | selector: 'my-instance-features-table', |
@@ -65,6 +64,10 @@ export class InstanceFeaturesTableComponent implements OnInit { | |||
65 | { | 64 | { |
66 | label: this.i18n('Torrent import'), | 65 | label: this.i18n('Torrent import'), |
67 | value: config.import.videos.torrent.enabled | 66 | value: config.import.videos.torrent.enabled |
67 | }, | ||
68 | { | ||
69 | label: this.i18n('P2P enabled'), | ||
70 | value: config.tracker.enabled | ||
68 | } | 71 | } |
69 | ] | 72 | ] |
70 | } | 73 | } |
diff --git a/client/src/app/videos/+video-watch/video-watch.component.scss b/client/src/app/videos/+video-watch/video-watch.component.scss index d61a0bc3e..84b9aed39 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.scss +++ b/client/src/app/videos/+video-watch/video-watch.component.scss | |||
@@ -427,6 +427,7 @@ my-video-comments { | |||
427 | // If the view is not expanded, take into account the menu | 427 | // If the view is not expanded, take into account the menu |
428 | .privacy-concerns { | 428 | .privacy-concerns { |
429 | width: calc(100% - #{$menu-width}); | 429 | width: calc(100% - #{$menu-width}); |
430 | margin-left: -15px; | ||
430 | } | 431 | } |
431 | 432 | ||
432 | @media screen and (max-width: $small-view) { | 433 | @media screen and (max-width: $small-view) { |
diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts index edc546b28..bce652210 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.ts +++ b/client/src/app/videos/+video-watch/video-watch.component.ts | |||
@@ -29,6 +29,7 @@ import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model' | |||
29 | import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' | 29 | import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' |
30 | import { ComponentPagination } from '@app/shared/rest/component-pagination.model' | 30 | import { ComponentPagination } from '@app/shared/rest/component-pagination.model' |
31 | import { Video } from '@app/shared/video/video.model' | 31 | import { Video } from '@app/shared/video/video.model' |
32 | import { isWebRTCDisabled } from '../../../assets/player/utils' | ||
32 | 33 | ||
33 | @Component({ | 34 | @Component({ |
34 | selector: 'my-video-watch', | 35 | selector: 'my-video-watch', |
@@ -71,6 +72,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
71 | private currentTime: number | 72 | private currentTime: number |
72 | private paramsSub: Subscription | 73 | private paramsSub: Subscription |
73 | private queryParamsSub: Subscription | 74 | private queryParamsSub: Subscription |
75 | private configSub: Subscription | ||
74 | 76 | ||
75 | constructor ( | 77 | constructor ( |
76 | private elementRef: ElementRef, | 78 | private elementRef: ElementRef, |
@@ -100,12 +102,16 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
100 | } | 102 | } |
101 | 103 | ||
102 | ngOnInit () { | 104 | ngOnInit () { |
103 | if ( | 105 | this.configSub = this.serverService.configLoaded |
104 | !!((window as any).RTCPeerConnection || (window as any).mozRTCPeerConnection || (window as any).webkitRTCPeerConnection) === false || | 106 | .subscribe(() => { |
105 | peertubeLocalStorage.getItem(VideoWatchComponent.LOCAL_STORAGE_PRIVACY_CONCERN_KEY) === 'true' | 107 | if ( |
106 | ) { | 108 | isWebRTCDisabled() || |
107 | this.hasAlreadyAcceptedPrivacyConcern = true | 109 | this.serverService.getConfig().tracker.enabled === false || |
108 | } | 110 | peertubeLocalStorage.getItem(VideoWatchComponent.LOCAL_STORAGE_PRIVACY_CONCERN_KEY) === 'true' |
111 | ) { | ||
112 | this.hasAlreadyAcceptedPrivacyConcern = true | ||
113 | } | ||
114 | }) | ||
109 | 115 | ||
110 | this.paramsSub = this.route.params.subscribe(routeParams => { | 116 | this.paramsSub = this.route.params.subscribe(routeParams => { |
111 | const videoId = routeParams[ 'videoId' ] | 117 | const videoId = routeParams[ 'videoId' ] |
diff --git a/client/src/assets/player/utils.ts b/client/src/assets/player/utils.ts index 0966027ac..366689962 100644 --- a/client/src/assets/player/utils.ts +++ b/client/src/assets/player/utils.ts | |||
@@ -4,6 +4,10 @@ function toTitleCase (str: string) { | |||
4 | return str.charAt(0).toUpperCase() + str.slice(1) | 4 | return str.charAt(0).toUpperCase() + str.slice(1) |
5 | } | 5 | } |
6 | 6 | ||
7 | function isWebRTCDisabled () { | ||
8 | return !!((window as any).RTCPeerConnection || (window as any).mozRTCPeerConnection || (window as any).webkitRTCPeerConnection) === false | ||
9 | } | ||
10 | |||
7 | // https://github.com/danrevah/ngx-pipes/blob/master/src/pipes/math/bytes.ts | 11 | // https://github.com/danrevah/ngx-pipes/blob/master/src/pipes/math/bytes.ts |
8 | // Don't import all Angular stuff, just copy the code with shame | 12 | // Don't import all Angular stuff, just copy the code with shame |
9 | const dictionaryBytes: Array<{max: number, type: string}> = [ | 13 | const dictionaryBytes: Array<{max: number, type: string}> = [ |
@@ -141,6 +145,7 @@ export { | |||
141 | toTitleCase, | 145 | toTitleCase, |
142 | timeToInt, | 146 | timeToInt, |
143 | secondsToTime, | 147 | secondsToTime, |
148 | isWebRTCDisabled, | ||
144 | buildVideoLink, | 149 | buildVideoLink, |
145 | buildVideoEmbed, | 150 | buildVideoEmbed, |
146 | videoFileMaxByResolution, | 151 | videoFileMaxByResolution, |
diff --git a/client/src/sass/player/peertube-skin.scss b/client/src/sass/player/peertube-skin.scss index a6942001a..e63a2875c 100644 --- a/client/src/sass/player/peertube-skin.scss +++ b/client/src/sass/player/peertube-skin.scss | |||
@@ -21,16 +21,16 @@ | |||
21 | .vjs-dock-description { | 21 | .vjs-dock-description { |
22 | font-size: 11px; | 22 | font-size: 11px; |
23 | 23 | ||
24 | &::before, &::after { | 24 | .text::before, .text::after { |
25 | display: inline-block; | 25 | display: inline-block; |
26 | content: '\1F308'; | 26 | content: '\1F308'; |
27 | } | 27 | } |
28 | 28 | ||
29 | &::before { | 29 | .text::before { |
30 | margin-right: 4px; | 30 | margin-right: 4px; |
31 | } | 31 | } |
32 | 32 | ||
33 | &::after { | 33 | .text::after { |
34 | margin-left: 4px; | 34 | margin-left: 4px; |
35 | transform: scale(-1, 1); | 35 | transform: scale(-1, 1); |
36 | } | 36 | } |
diff --git a/client/src/standalone/videos/embed.ts b/client/src/standalone/videos/embed.ts index 626d55a7c..707f04253 100644 --- a/client/src/standalone/videos/embed.ts +++ b/client/src/standalone/videos/embed.ts | |||
@@ -2,7 +2,7 @@ import './embed.scss' | |||
2 | 2 | ||
3 | import * as Channel from 'jschannel' | 3 | import * as Channel from 'jschannel' |
4 | 4 | ||
5 | import { peertubeTranslate, ResultList, VideoDetails } from '../../../../shared' | 5 | import { peertubeTranslate, ResultList, ServerConfig, VideoDetails } from '../../../../shared' |
6 | import { PeerTubeResolution } from '../player/definitions' | 6 | import { PeerTubeResolution } from '../player/definitions' |
7 | import { VideoJSCaption } from '../../assets/player/peertube-videojs-typings' | 7 | import { VideoJSCaption } from '../../assets/player/peertube-videojs-typings' |
8 | import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model' | 8 | import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model' |
@@ -177,6 +177,10 @@ class PeerTubeEmbed { | |||
177 | return fetch(this.getVideoUrl(videoId) + '/captions') | 177 | return fetch(this.getVideoUrl(videoId) + '/captions') |
178 | } | 178 | } |
179 | 179 | ||
180 | loadConfig (): Promise<Response> { | ||
181 | return fetch('/api/v1/config') | ||
182 | } | ||
183 | |||
180 | removeElement (element: HTMLElement) { | 184 | removeElement (element: HTMLElement) { |
181 | element.parentElement.removeChild(element) | 185 | element.parentElement.removeChild(element) |
182 | } | 186 | } |
@@ -237,10 +241,10 @@ class PeerTubeEmbed { | |||
237 | try { | 241 | try { |
238 | const params = new URL(window.location.toString()).searchParams | 242 | const params = new URL(window.location.toString()).searchParams |
239 | 243 | ||
240 | this.autoplay = this.getParamToggle(params, 'autoplay') | 244 | this.autoplay = this.getParamToggle(params, 'autoplay', false) |
241 | this.controls = this.getParamToggle(params, 'controls') | 245 | this.controls = this.getParamToggle(params, 'controls', true) |
242 | this.muted = this.getParamToggle(params, 'muted') | 246 | this.muted = this.getParamToggle(params, 'muted', false) |
243 | this.loop = this.getParamToggle(params, 'loop') | 247 | this.loop = this.getParamToggle(params, 'loop', false) |
244 | this.enableApi = this.getParamToggle(params, 'api', this.enableApi) | 248 | this.enableApi = this.getParamToggle(params, 'api', this.enableApi) |
245 | 249 | ||
246 | this.scope = this.getParamString(params, 'scope', this.scope) | 250 | this.scope = this.getParamString(params, 'scope', this.scope) |
@@ -258,10 +262,11 @@ class PeerTubeEmbed { | |||
258 | const urlParts = window.location.pathname.split('/') | 262 | const urlParts = window.location.pathname.split('/') |
259 | const videoId = urlParts[ urlParts.length - 1 ] | 263 | const videoId = urlParts[ urlParts.length - 1 ] |
260 | 264 | ||
261 | const [ serverTranslations, videoResponse, captionsResponse ] = await Promise.all([ | 265 | const [ serverTranslations, videoResponse, captionsResponse, configResponse ] = await Promise.all([ |
262 | PeertubePlayerManager.getServerTranslations(window.location.origin, navigator.language), | 266 | PeertubePlayerManager.getServerTranslations(window.location.origin, navigator.language), |
263 | this.loadVideoInfo(videoId), | 267 | this.loadVideoInfo(videoId), |
264 | this.loadVideoCaptions(videoId) | 268 | this.loadVideoCaptions(videoId), |
269 | this.loadConfig() | ||
265 | ]) | 270 | ]) |
266 | 271 | ||
267 | if (!videoResponse.ok) { | 272 | if (!videoResponse.ok) { |
@@ -338,9 +343,14 @@ class PeerTubeEmbed { | |||
338 | window[ 'videojsPlayer' ] = this.player | 343 | window[ 'videojsPlayer' ] = this.player |
339 | 344 | ||
340 | if (this.controls) { | 345 | if (this.controls) { |
346 | const config: ServerConfig = await configResponse.json() | ||
347 | const description = config.tracker.enabled | ||
348 | ? '<span class="text">' + this.player.localize('Uses P2P, others may know your IP is downloading this video.') + '</span>' | ||
349 | : undefined | ||
350 | |||
341 | this.player.dock({ | 351 | this.player.dock({ |
342 | title: videoInfo.name, | 352 | title: videoInfo.name, |
343 | description: this.player.localize('Uses P2P, others may know your IP is downloading this video.') | 353 | description |
344 | }) | 354 | }) |
345 | } | 355 | } |
346 | 356 | ||
diff --git a/config/default.yaml b/config/default.yaml index 0d6e34d86..617159c2c 100644 --- a/config/default.yaml +++ b/config/default.yaml | |||
@@ -101,6 +101,16 @@ csp: | |||
101 | report_only: true # CSP directives are still being tested, so disable the report only mode at your own risk! | 101 | report_only: true # CSP directives are still being tested, so disable the report only mode at your own risk! |
102 | report_uri: | 102 | report_uri: |
103 | 103 | ||
104 | tracker: | ||
105 | # If you disable the tracker, you disable the P2P aspect of PeerTube | ||
106 | enabled: true | ||
107 | # Only handle requests on your videos. | ||
108 | # If you set this to false it means you have a public tracker. | ||
109 | # Then, it is possible that clients overload your instance with external torrents | ||
110 | private: true | ||
111 | # Reject peers that do a lot of announces (could improve privacy of TCP/UDP peers) | ||
112 | reject_too_many_announces: false | ||
113 | |||
104 | cache: | 114 | cache: |
105 | previews: | 115 | previews: |
106 | size: 500 # Max number of previews you want to cache | 116 | size: 500 # Max number of previews you want to cache |
diff --git a/config/production.yaml.example b/config/production.yaml.example index 5029cc25b..dd5c9769b 100644 --- a/config/production.yaml.example +++ b/config/production.yaml.example | |||
@@ -102,6 +102,16 @@ csp: | |||
102 | report_only: true # CSP directives are still being tested, so disable the report only mode at your own risk! | 102 | report_only: true # CSP directives are still being tested, so disable the report only mode at your own risk! |
103 | report_uri: | 103 | report_uri: |
104 | 104 | ||
105 | tracker: | ||
106 | # If you disable the tracker, you disable the P2P aspect of PeerTube | ||
107 | enabled: true | ||
108 | # Only handle requests on your videos. | ||
109 | # If you set this to false it means you have a public tracker. | ||
110 | # Then, it is possible that clients overload your instance with external torrents | ||
111 | private: true | ||
112 | # Reject peers that do a lot of announces (could improve privacy of TCP/UDP peers) | ||
113 | reject_too_many_announces: false | ||
114 | |||
105 | 115 | ||
106 | ############################################################################### | 116 | ############################################################################### |
107 | # | 117 | # |
diff --git a/server/controllers/api/config.ts b/server/controllers/api/config.ts index 5c4f455ee..0d7fc8625 100644 --- a/server/controllers/api/config.ts +++ b/server/controllers/api/config.ts | |||
@@ -136,6 +136,9 @@ async function getConfig (req: express.Request, res: express.Response) { | |||
136 | videos: { | 136 | videos: { |
137 | intervalDays: CONFIG.TRENDING.VIDEOS.INTERVAL_DAYS | 137 | intervalDays: CONFIG.TRENDING.VIDEOS.INTERVAL_DAYS |
138 | } | 138 | } |
139 | }, | ||
140 | tracker: { | ||
141 | enabled: CONFIG.TRACKER.ENABLED | ||
139 | } | 142 | } |
140 | } | 143 | } |
141 | 144 | ||
diff --git a/server/controllers/tracker.ts b/server/controllers/tracker.ts index 8b77d9de7..56a3424a3 100644 --- a/server/controllers/tracker.ts +++ b/server/controllers/tracker.ts | |||
@@ -23,6 +23,10 @@ const trackerServer = new TrackerServer({ | |||
23 | ws: false, | 23 | ws: false, |
24 | dht: false, | 24 | dht: false, |
25 | filter: async function (infoHash, params, cb) { | 25 | filter: async function (infoHash, params, cb) { |
26 | if (CONFIG.TRACKER.ENABLED === false) { | ||
27 | return cb(new Error('Tracker is disabled on this instance.')) | ||
28 | } | ||
29 | |||
26 | let ip: string | 30 | let ip: string |
27 | 31 | ||
28 | if (params.type === 'ws') { | 32 | if (params.type === 'ws') { |
@@ -36,11 +40,13 @@ const trackerServer = new TrackerServer({ | |||
36 | peersIps[ ip ] = peersIps[ ip ] ? peersIps[ ip ] + 1 : 1 | 40 | peersIps[ ip ] = peersIps[ ip ] ? peersIps[ ip ] + 1 : 1 |
37 | peersIpInfoHash[ key ] = peersIpInfoHash[ key ] ? peersIpInfoHash[ key ] + 1 : 1 | 41 | peersIpInfoHash[ key ] = peersIpInfoHash[ key ] ? peersIpInfoHash[ key ] + 1 : 1 |
38 | 42 | ||
39 | if (peersIpInfoHash[ key ] > TRACKER_RATE_LIMITS.ANNOUNCES_PER_IP_PER_INFOHASH) { | 43 | if (CONFIG.TRACKER.REJECT_TOO_MANY_ANNOUNCES && peersIpInfoHash[ key ] > TRACKER_RATE_LIMITS.ANNOUNCES_PER_IP_PER_INFOHASH) { |
40 | return cb(new Error(`Too many requests (${peersIpInfoHash[ key ]} of ip ${ip} for torrent ${infoHash}`)) | 44 | return cb(new Error(`Too many requests (${peersIpInfoHash[ key ]} of ip ${ip} for torrent ${infoHash}`)) |
41 | } | 45 | } |
42 | 46 | ||
43 | try { | 47 | try { |
48 | if (CONFIG.TRACKER.PRIVATE === false) return cb() | ||
49 | |||
44 | const videoFileExists = await VideoFileModel.doesInfohashExist(infoHash) | 50 | const videoFileExists = await VideoFileModel.doesInfohashExist(infoHash) |
45 | if (videoFileExists === true) return cb() | 51 | if (videoFileExists === true) return cb() |
46 | 52 | ||
@@ -55,13 +61,16 @@ const trackerServer = new TrackerServer({ | |||
55 | } | 61 | } |
56 | }) | 62 | }) |
57 | 63 | ||
58 | trackerServer.on('error', function (err) { | 64 | if (CONFIG.TRACKER.ENABLED !== false) { |
59 | logger.error('Error in tracker.', { err }) | ||
60 | }) | ||
61 | 65 | ||
62 | trackerServer.on('warning', function (err) { | 66 | trackerServer.on('error', function (err) { |
63 | logger.warn('Warning in tracker.', { err }) | 67 | logger.error('Error in tracker.', { err }) |
64 | }) | 68 | }) |
69 | |||
70 | trackerServer.on('warning', function (err) { | ||
71 | logger.warn('Warning in tracker.', { err }) | ||
72 | }) | ||
73 | } | ||
65 | 74 | ||
66 | const onHttpRequest = trackerServer.onHttpRequest.bind(trackerServer) | 75 | const onHttpRequest = trackerServer.onHttpRequest.bind(trackerServer) |
67 | trackerRouter.get('/tracker/announce', (req, res) => onHttpRequest(req, res, { action: 'announce' })) | 76 | trackerRouter.get('/tracker/announce', (req, res) => onHttpRequest(req, res, { action: 'announce' })) |
diff --git a/server/initializers/checker-before-init.ts b/server/initializers/checker-before-init.ts index 3095913a3..6b43debfb 100644 --- a/server/initializers/checker-before-init.ts +++ b/server/initializers/checker-before-init.ts | |||
@@ -25,7 +25,8 @@ function checkMissedConfig () { | |||
25 | 'instance.name', 'instance.short_description', 'instance.description', 'instance.terms', 'instance.default_client_route', | 25 | 'instance.name', 'instance.short_description', 'instance.description', 'instance.terms', 'instance.default_client_route', |
26 | 'instance.is_nsfw', 'instance.default_nsfw_policy', 'instance.robots', 'instance.securitytxt', | 26 | 'instance.is_nsfw', 'instance.default_nsfw_policy', 'instance.robots', 'instance.securitytxt', |
27 | 'services.twitter.username', 'services.twitter.whitelisted', | 27 | 'services.twitter.username', 'services.twitter.whitelisted', |
28 | 'followers.instance.enabled', 'followers.instance.manual_approval' | 28 | 'followers.instance.enabled', 'followers.instance.manual_approval', |
29 | 'tracker.enabled', 'tracker.private', 'tracker.reject_too_many_announces' | ||
29 | ] | 30 | ] |
30 | const requiredAlternatives = [ | 31 | const requiredAlternatives = [ |
31 | [ // set | 32 | [ // set |
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 097199f84..3f02572db 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts | |||
@@ -243,6 +243,11 @@ const CONFIG = { | |||
243 | REPORT_ONLY: config.get<boolean>('csp.report_only'), | 243 | REPORT_ONLY: config.get<boolean>('csp.report_only'), |
244 | REPORT_URI: config.get<boolean>('csp.report_uri') | 244 | REPORT_URI: config.get<boolean>('csp.report_uri') |
245 | }, | 245 | }, |
246 | TRACKER: { | ||
247 | ENABLED: config.get<boolean>('tracker.enabled'), | ||
248 | PRIVATE: config.get<boolean>('tracker.private'), | ||
249 | REJECT_TOO_MANY_ANNOUNCES: config.get<boolean>('tracker.reject_too_many_announces') | ||
250 | }, | ||
246 | ADMIN: { | 251 | ADMIN: { |
247 | get EMAIL () { return config.get<string>('admin.email') } | 252 | get EMAIL () { return config.get<string>('admin.email') } |
248 | }, | 253 | }, |
diff --git a/server/tests/api/server/tracker.ts b/server/tests/api/server/tracker.ts index 25ca00029..41803aef1 100644 --- a/server/tests/api/server/tracker.ts +++ b/server/tests/api/server/tracker.ts | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | import * as magnetUtil from 'magnet-uri' | 3 | import * as magnetUtil from 'magnet-uri' |
4 | import 'mocha' | 4 | import 'mocha' |
5 | import { getVideo, killallServers, runServer, ServerInfo, uploadVideo } from '../../../../shared/utils' | 5 | import { getVideo, killallServers, reRunServer, runServer, ServerInfo, uploadVideo } from '../../../../shared/utils' |
6 | import { flushTests, setAccessTokensToServers } from '../../../../shared/utils/index' | 6 | import { flushTests, setAccessTokensToServers } from '../../../../shared/utils/index' |
7 | import { VideoDetails } from '../../../../shared/models/videos' | 7 | import { VideoDetails } from '../../../../shared/models/videos' |
8 | import * as WebTorrent from 'webtorrent' | 8 | import * as WebTorrent from 'webtorrent' |
@@ -34,7 +34,7 @@ describe('Test tracker', function () { | |||
34 | } | 34 | } |
35 | }) | 35 | }) |
36 | 36 | ||
37 | it('Should return an error when adding an incorrect infohash', done => { | 37 | it('Should return an error when adding an incorrect infohash', function (done) { |
38 | this.timeout(10000) | 38 | this.timeout(10000) |
39 | const webtorrent = new WebTorrent() | 39 | const webtorrent = new WebTorrent() |
40 | 40 | ||
@@ -49,7 +49,7 @@ describe('Test tracker', function () { | |||
49 | torrent.on('done', () => done(new Error('No error on infohash'))) | 49 | torrent.on('done', () => done(new Error('No error on infohash'))) |
50 | }) | 50 | }) |
51 | 51 | ||
52 | it('Should succeed with the correct infohash', done => { | 52 | it('Should succeed with the correct infohash', function (done) { |
53 | this.timeout(10000) | 53 | this.timeout(10000) |
54 | const webtorrent = new WebTorrent() | 54 | const webtorrent = new WebTorrent() |
55 | 55 | ||
@@ -64,6 +64,26 @@ describe('Test tracker', function () { | |||
64 | torrent.on('done', done) | 64 | torrent.on('done', done) |
65 | }) | 65 | }) |
66 | 66 | ||
67 | it('Should disable the tracker', function (done) { | ||
68 | this.timeout(20000) | ||
69 | |||
70 | killallServers([ server ]) | ||
71 | reRunServer(server, { tracker: { enabled: false } }) | ||
72 | .then(() => { | ||
73 | const webtorrent = new WebTorrent() | ||
74 | |||
75 | const torrent = webtorrent.add(goodMagnet) | ||
76 | |||
77 | torrent.on('error', done) | ||
78 | torrent.on('warning', warn => { | ||
79 | const message = typeof warn === 'string' ? warn : warn.message | ||
80 | if (message.indexOf('disabled ') !== -1) return done() | ||
81 | }) | ||
82 | |||
83 | torrent.on('done', () => done(new Error('Tracker is enabled'))) | ||
84 | }) | ||
85 | }) | ||
86 | |||
67 | after(async function () { | 87 | after(async function () { |
68 | killallServers([ server ]) | 88 | killallServers([ server ]) |
69 | }) | 89 | }) |
diff --git a/shared/models/server/server-config.model.ts b/shared/models/server/server-config.model.ts index dcc45be8a..d937e9c05 100644 --- a/shared/models/server/server-config.model.ts +++ b/shared/models/server/server-config.model.ts | |||
@@ -97,4 +97,8 @@ export interface ServerConfig { | |||
97 | intervalDays: number | 97 | intervalDays: number |
98 | } | 98 | } |
99 | } | 99 | } |
100 | |||
101 | tracker: { | ||
102 | enabled: boolean | ||
103 | } | ||
100 | } | 104 | } |
diff --git a/support/docker/production/config/production.yaml b/support/docker/production/config/production.yaml index 846c838e8..d585cd73e 100644 --- a/support/docker/production/config/production.yaml +++ b/support/docker/production/config/production.yaml | |||
@@ -46,5 +46,9 @@ storage: | |||
46 | log: | 46 | log: |
47 | level: 'info' # debug/info/warning/error | 47 | level: 'info' # debug/info/warning/error |
48 | 48 | ||
49 | tracker: | ||
50 | enabled: true | ||
51 | reject_too_many_announces: false # false because we have issues with traefik and ws ip/port forwarding | ||
52 | |||
49 | admin: | 53 | admin: |
50 | email: null | 54 | email: null |