aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2018-03-01 13:57:29 +0100
committerChocobozzz <me@florianbigard.com>2018-03-01 13:57:29 +0100
commit901637bb87f5eb0518fb7ca69d98b53ed918339e (patch)
treea8e8943fef7a109ba269d33029174cbdf4dde6d2
parenta73c582e5b6f5c52427b38aaf55b3afbead24053 (diff)
downloadPeerTube-901637bb87f5eb0518fb7ca69d98b53ed918339e.tar.gz
PeerTube-901637bb87f5eb0518fb7ca69d98b53ed918339e.tar.zst
PeerTube-901637bb87f5eb0518fb7ca69d98b53ed918339e.zip
Add ability to change the homepage
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html10
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts6
-rw-r--r--client/src/app/app-routing.module.ts10
-rw-r--r--client/src/app/app.component.ts9
-rw-r--r--client/src/app/core/core.module.ts5
-rw-r--r--client/src/app/core/routing/index.ts1
-rw-r--r--client/src/app/core/routing/redirect.service.ts48
-rw-r--r--client/src/app/core/server/server.service.ts1
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.ts13
-rw-r--r--config/default.yaml1
-rw-r--r--config/production.yaml.example1
-rw-r--r--server/controllers/api/config.ts4
-rw-r--r--server/initializers/constants.ts1
-rw-r--r--server/middlewares/validators/config.ts6
-rw-r--r--server/tests/api/check-params/config.ts1
-rw-r--r--server/tests/api/server/config.ts5
-rw-r--r--shared/models/server/custom-config.model.ts1
-rw-r--r--shared/models/server/server-config.model.ts3
18 files changed, 108 insertions, 18 deletions
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
index 18ba7ba06..c7ddaaf01 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
+++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
@@ -37,6 +37,16 @@
37 </div> 37 </div>
38 </div> 38 </div>
39 39
40 <div class="form-group">
41 <label for="instanceDefaultClientRoute">Default client route</label>
42 <div class="peertube-select-container">
43 <select id="instanceDefaultClientRoute" formControlName="instanceDefaultClientRoute">
44 <option value="/videos/trending">Videos Trending</option>
45 <option value="/videos/recently-added">Videos Recently Added</option>
46 </select>
47 </div>
48 </div>
49
40 <div class="inner-form-title">Cache</div> 50 <div class="inner-form-title">Cache</div>
41 51
42 <div class="form-group"> 52 <div class="form-group">
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
index cf93b4060..c38bc326a 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
+++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
@@ -46,6 +46,7 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
46 instanceName: '', 46 instanceName: '',
47 instanceDescription: '', 47 instanceDescription: '',
48 instanceTerms: '', 48 instanceTerms: '',
49 instanceDefaultClientRoute: '',
49 cachePreviewsSize: '', 50 cachePreviewsSize: '',
50 signupLimit: '', 51 signupLimit: '',
51 adminEmail: '', 52 adminEmail: '',
@@ -85,6 +86,7 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
85 instanceName: [ '', INSTANCE_NAME.VALIDATORS ], 86 instanceName: [ '', INSTANCE_NAME.VALIDATORS ],
86 instanceDescription: [ '' ], 87 instanceDescription: [ '' ],
87 instanceTerms: [ '' ], 88 instanceTerms: [ '' ],
89 instanceDefaultClientRoute: [ '' ],
88 cachePreviewsSize: [ '', CACHE_PREVIEWS_SIZE.VALIDATORS ], 90 cachePreviewsSize: [ '', CACHE_PREVIEWS_SIZE.VALIDATORS ],
89 signupEnabled: [ ], 91 signupEnabled: [ ],
90 signupLimit: [ '', SIGNUP_LIMIT.VALIDATORS ], 92 signupLimit: [ '', SIGNUP_LIMIT.VALIDATORS ],
@@ -153,11 +155,12 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
153 if (confirmRes === false) return 155 if (confirmRes === false) return
154 } 156 }
155 157
156 const data = { 158 const data: CustomConfig = {
157 instance: { 159 instance: {
158 name: this.form.value['instanceName'], 160 name: this.form.value['instanceName'],
159 description: this.form.value['instanceDescription'], 161 description: this.form.value['instanceDescription'],
160 terms: this.form.value['instanceTerms'], 162 terms: this.form.value['instanceTerms'],
163 defaultClientRoute: this.form.value['instanceDefaultClientRoute'],
161 customizations: { 164 customizations: {
162 javascript: this.form.value['customizationJavascript'], 165 javascript: this.form.value['customizationJavascript'],
163 css: this.form.value['customizationCSS'] 166 css: this.form.value['customizationCSS']
@@ -213,6 +216,7 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
213 instanceName: this.customConfig.instance.name, 216 instanceName: this.customConfig.instance.name,
214 instanceDescription: this.customConfig.instance.description, 217 instanceDescription: this.customConfig.instance.description,
215 instanceTerms: this.customConfig.instance.terms, 218 instanceTerms: this.customConfig.instance.terms,
219 instanceDefaultClientRoute: this.customConfig.instance.defaultClientRoute,
216 cachePreviewsSize: this.customConfig.cache.previews.size, 220 cachePreviewsSize: this.customConfig.cache.previews.size,
217 signupEnabled: this.customConfig.signup.enabled, 221 signupEnabled: this.customConfig.signup.enabled,
218 signupLimit: this.customConfig.signup.limit, 222 signupLimit: this.customConfig.signup.limit,
diff --git a/client/src/app/app-routing.module.ts b/client/src/app/app-routing.module.ts
index f31b51e23..c8a6b3924 100644
--- a/client/src/app/app-routing.module.ts
+++ b/client/src/app/app-routing.module.ts
@@ -1,15 +1,11 @@
1import { NgModule } from '@angular/core' 1import { NgModule } from '@angular/core'
2import { Routes, RouterModule } from '@angular/router' 2import { Routes, RouterModule } from '@angular/router'
3import { RedirectService } from '@app/core/routing/redirect.service'
3 4
4import { PreloadSelectedModulesList } from './core' 5import { PreloadSelectedModulesList } from './core'
5 6
6const routes: Routes = [ 7const routes: Routes = [
7 { 8 {
8 path: '',
9 redirectTo: '/videos/trending',
10 pathMatch: 'full'
11 },
12 {
13 path: 'admin', 9 path: 'admin',
14 loadChildren: './+admin/admin.module#AdminModule' 10 loadChildren: './+admin/admin.module#AdminModule'
15 } 11 }
@@ -22,7 +18,9 @@ const routes: Routes = [
22 preloadingStrategy: PreloadSelectedModulesList 18 preloadingStrategy: PreloadSelectedModulesList
23 }) 19 })
24 ], 20 ],
25 providers: [ PreloadSelectedModulesList ], 21 providers: [
22 PreloadSelectedModulesList
23 ],
26 exports: [ RouterModule ] 24 exports: [ RouterModule ]
27}) 25})
28export class AppRoutingModule {} 26export class AppRoutingModule {}
diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts
index 25936146c..346e966e5 100644
--- a/client/src/app/app.component.ts
+++ b/client/src/app/app.component.ts
@@ -1,7 +1,7 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { DomSanitizer, SafeHtml } from '@angular/platform-browser' 2import { DomSanitizer, SafeHtml } from '@angular/platform-browser'
3import { GuardsCheckStart, Router } from '@angular/router' 3import { GuardsCheckStart, Router } from '@angular/router'
4import { AuthService, ServerService } from '@app/core' 4import { AuthService, RedirectService, ServerService } from '@app/core'
5import { isInSmallView } from '@app/shared/misc/utils' 5import { isInSmallView } from '@app/shared/misc/utils'
6 6
7@Component({ 7@Component({
@@ -31,7 +31,8 @@ export class AppComponent implements OnInit {
31 private router: Router, 31 private router: Router,
32 private authService: AuthService, 32 private authService: AuthService,
33 private serverService: ServerService, 33 private serverService: ServerService,
34 private domSanitizer: DomSanitizer 34 private domSanitizer: DomSanitizer,
35 private redirectService: RedirectService
35 ) {} 36 ) {}
36 37
37 get serverVersion () { 38 get serverVersion () {
@@ -43,6 +44,10 @@ export class AppComponent implements OnInit {
43 } 44 }
44 45
45 ngOnInit () { 46 ngOnInit () {
47 if (this.router.url === '/') {
48 this.redirectService.redirectToHomepage()
49 }
50
46 this.authService.loadClientCredentials() 51 this.authService.loadClientCredentials()
47 52
48 if (this.authService.isLoggedIn()) { 53 if (this.authService.isLoggedIn()) {
diff --git a/client/src/app/core/core.module.ts b/client/src/app/core/core.module.ts
index 708831965..c2de2084e 100644
--- a/client/src/app/core/core.module.ts
+++ b/client/src/app/core/core.module.ts
@@ -13,7 +13,7 @@ import { ModalModule } from 'ngx-bootstrap/modal'
13import { AuthService } from './auth' 13import { AuthService } from './auth'
14import { ConfirmComponent, ConfirmService } from './confirm' 14import { ConfirmComponent, ConfirmService } from './confirm'
15import { throwIfAlreadyLoaded } from './module-import-guard' 15import { throwIfAlreadyLoaded } from './module-import-guard'
16import { LoginGuard, UserRightGuard } from './routing' 16import { LoginGuard, RedirectService, UserRightGuard } from './routing'
17import { ServerService } from './server' 17import { ServerService } from './server'
18 18
19@NgModule({ 19@NgModule({
@@ -48,7 +48,8 @@ import { ServerService } from './server'
48 ConfirmService, 48 ConfirmService,
49 ServerService, 49 ServerService,
50 LoginGuard, 50 LoginGuard,
51 UserRightGuard 51 UserRightGuard,
52 RedirectService
52 ] 53 ]
53}) 54})
54export class CoreModule { 55export class CoreModule {
diff --git a/client/src/app/core/routing/index.ts b/client/src/app/core/routing/index.ts
index d1b982834..9f0b4eac5 100644
--- a/client/src/app/core/routing/index.ts
+++ b/client/src/app/core/routing/index.ts
@@ -1,3 +1,4 @@
1export * from './login-guard.service' 1export * from './login-guard.service'
2export * from './user-right-guard.service' 2export * from './user-right-guard.service'
3export * from './preload-selected-modules-list' 3export * from './preload-selected-modules-list'
4export * from './redirect.service'
diff --git a/client/src/app/core/routing/redirect.service.ts b/client/src/app/core/routing/redirect.service.ts
new file mode 100644
index 000000000..a0125e0ae
--- /dev/null
+++ b/client/src/app/core/routing/redirect.service.ts
@@ -0,0 +1,48 @@
1import { Injectable } from '@angular/core'
2import { Router } from '@angular/router'
3import { ServerService } from '../server'
4
5@Injectable()
6export class RedirectService {
7 // Default route could change according to the instance configuration
8 static INIT_DEFAULT_ROUTE = '/videos/trending'
9 static DEFAULT_ROUTE = RedirectService.INIT_DEFAULT_ROUTE
10
11 constructor (
12 private router: Router,
13 private serverService: ServerService
14 ) {
15 // The config is first loaded from the cache so try to get the default route
16 const config = this.serverService.getConfig()
17 if (config && config.instance && config.instance.defaultClientRoute) {
18 RedirectService.DEFAULT_ROUTE = config.instance.defaultClientRoute
19 }
20
21 this.serverService.configLoaded
22 .subscribe(() => {
23 const defaultRouteConfig = this.serverService.getConfig().instance.defaultClientRoute
24
25 if (defaultRouteConfig) {
26 RedirectService.DEFAULT_ROUTE = defaultRouteConfig
27 }
28 })
29 }
30
31 redirectToHomepage () {
32 console.log('Redirecting to %s...', RedirectService.DEFAULT_ROUTE)
33
34 this.router.navigate([ RedirectService.DEFAULT_ROUTE ])
35 .catch(() => {
36 console.error(
37 'Cannot navigate to %s, resetting default route to %s.',
38 RedirectService.DEFAULT_ROUTE,
39 RedirectService.INIT_DEFAULT_ROUTE
40 )
41
42 RedirectService.DEFAULT_ROUTE = RedirectService.INIT_DEFAULT_ROUTE
43 return this.router.navigate([ RedirectService.DEFAULT_ROUTE ])
44 })
45
46 }
47
48}
diff --git a/client/src/app/core/server/server.service.ts b/client/src/app/core/server/server.service.ts
index 984738948..2135c3268 100644
--- a/client/src/app/core/server/server.service.ts
+++ b/client/src/app/core/server/server.service.ts
@@ -21,6 +21,7 @@ export class ServerService {
21 private config: ServerConfig = { 21 private config: ServerConfig = {
22 instance: { 22 instance: {
23 name: 'PeerTube', 23 name: 'PeerTube',
24 defaultClientRoute: '',
24 customizations: { 25 customizations: {
25 javascript: '', 26 javascript: '',
26 css: '' 27 css: ''
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 585ab2e00..66ef0399a 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/videos/+video-watch/video-watch.component.ts
@@ -1,9 +1,9 @@
1import { Component, ElementRef, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core' 1import { Component, ElementRef, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { RedirectService } from '@app/core/routing/redirect.service'
3import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component' 4import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component'
4import { MetaService } from '@ngx-meta/core' 5import { MetaService } from '@ngx-meta/core'
5import { NotificationsService } from 'angular2-notifications' 6import { NotificationsService } from 'angular2-notifications'
6import { Observable } from 'rxjs/Observable'
7import { Subscription } from 'rxjs/Subscription' 7import { Subscription } from 'rxjs/Subscription'
8import * as videojs from 'video.js' 8import * as videojs from 'video.js'
9import 'videojs-hotkeys' 9import 'videojs-hotkeys'
@@ -64,7 +64,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
64 private authService: AuthService, 64 private authService: AuthService,
65 private notificationsService: NotificationsService, 65 private notificationsService: NotificationsService,
66 private markdownService: MarkdownService, 66 private markdownService: MarkdownService,
67 private zone: NgZone 67 private zone: NgZone,
68 private redirectService: RedirectService
68 ) {} 69 ) {}
69 70
70 get user () { 71 get user () {
@@ -142,7 +143,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
142 .subscribe( 143 .subscribe(
143 status => { 144 status => {
144 this.notificationsService.success('Success', `Video ${this.video.name} had been blacklisted.`) 145 this.notificationsService.success('Success', `Video ${this.video.name} had been blacklisted.`)
145 this.router.navigate(['/videos/list']) 146 this.redirectService.redirectToHomepage()
146 }, 147 },
147 148
148 error => this.notificationsService.error('Error', error.message) 149 error => this.notificationsService.error('Error', error.message)
@@ -247,7 +248,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
247 this.notificationsService.success('Success', `Video ${this.video.name} deleted.`) 248 this.notificationsService.success('Success', `Video ${this.video.name} deleted.`)
248 249
249 // Go back to the video-list. 250 // Go back to the video-list.
250 this.router.navigate([ '/videos/list' ]) 251 this.redirectService.redirectToHomepage()
251 }, 252 },
252 253
253 error => this.notificationsService.error('Error', error.message) 254 error => this.notificationsService.error('Error', error.message)
@@ -313,7 +314,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
313 'This video contains mature or explicit content. Are you sure you want to watch it?', 314 'This video contains mature or explicit content. Are you sure you want to watch it?',
314 'Mature or explicit content' 315 'Mature or explicit content'
315 ) 316 )
316 if (res === false) return this.router.navigate([ '/videos/list' ]) 317 if (res === false) return this.redirectService.redirectToHomepage()
317 } 318 }
318 319
319 if (!this.hasAlreadyAcceptedPrivacyConcern()) { 320 if (!this.hasAlreadyAcceptedPrivacyConcern()) {
@@ -323,7 +324,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
323 'Privacy concern', 324 'Privacy concern',
324 'I accept!' 325 'I accept!'
325 ) 326 )
326 if (res === false) return this.router.navigate([ '/videos/list' ]) 327 if (res === false) return this.redirectService.redirectToHomepage()
327 } 328 }
328 329
329 this.acceptedPrivacyConcern() 330 this.acceptedPrivacyConcern()
diff --git a/config/default.yaml b/config/default.yaml
index a634be61c..5389f1164 100644
--- a/config/default.yaml
+++ b/config/default.yaml
@@ -74,6 +74,7 @@ instance:
74 name: 'PeerTube' 74 name: 'PeerTube'
75 description: 'Welcome to this PeerTube instance!' # Support markdown 75 description: 'Welcome to this PeerTube instance!' # Support markdown
76 terms: 'No terms for now.' # Support markdown 76 terms: 'No terms for now.' # Support markdown
77 default_client_route: '/videos/trending'
77 customizations: 78 customizations:
78 javascript: '' # Directly your JavaScript code (without <script> tags). Will be eval at runtime 79 javascript: '' # Directly your JavaScript code (without <script> tags). Will be eval at runtime
79 css: '' # Directly your CSS code (without <style> tags). Will be injected at runtime 80 css: '' # Directly your CSS code (without <style> tags). Will be injected at runtime
diff --git a/config/production.yaml.example b/config/production.yaml.example
index e70201668..2f28501b3 100644
--- a/config/production.yaml.example
+++ b/config/production.yaml.example
@@ -87,6 +87,7 @@ instance:
87 name: 'PeerTube' 87 name: 'PeerTube'
88 description: '' # Support markdown 88 description: '' # Support markdown
89 terms: '' # Support markdown 89 terms: '' # Support markdown
90 default_client_route: '/videos/trending'
90 customizations: 91 customizations:
91 javascript: '' # Directly your JavaScript code (without <script> tags). Will be eval at runtime 92 javascript: '' # Directly your JavaScript code (without <script> tags). Will be eval at runtime
92 css: '' # Directly your CSS code (without <style> tags). Will be injected at runtime 93 css: '' # Directly your CSS code (without <style> tags). Will be injected at runtime
diff --git a/server/controllers/api/config.ts b/server/controllers/api/config.ts
index 427125810..a25d7a157 100644
--- a/server/controllers/api/config.ts
+++ b/server/controllers/api/config.ts
@@ -44,6 +44,7 @@ async function getConfig (req: express.Request, res: express.Response, next: exp
44 const json: ServerConfig = { 44 const json: ServerConfig = {
45 instance: { 45 instance: {
46 name: CONFIG.INSTANCE.NAME, 46 name: CONFIG.INSTANCE.NAME,
47 defaultClientRoute: CONFIG.INSTANCE.DEFAULT_CLIENT_ROUTE,
47 customizations: { 48 customizations: {
48 javascript: CONFIG.INSTANCE.CUSTOMIZATIONS.JAVASCRIPT, 49 javascript: CONFIG.INSTANCE.CUSTOMIZATIONS.JAVASCRIPT,
49 css: CONFIG.INSTANCE.CUSTOMIZATIONS.CSS 50 css: CONFIG.INSTANCE.CUSTOMIZATIONS.CSS
@@ -114,7 +115,9 @@ async function updateCustomConfig (req: express.Request, res: express.Response,
114 // Need to change the videoQuota key a little bit 115 // Need to change the videoQuota key a little bit
115 const toUpdateJSON = omit(toUpdate, 'videoQuota') 116 const toUpdateJSON = omit(toUpdate, 'videoQuota')
116 toUpdateJSON.user['video_quota'] = toUpdate.user.videoQuota 117 toUpdateJSON.user['video_quota'] = toUpdate.user.videoQuota
118 toUpdateJSON.instance['default_client_route'] = toUpdate.instance.defaultClientRoute
117 delete toUpdate.user.videoQuota 119 delete toUpdate.user.videoQuota
120 delete toUpdate.instance.defaultClientRoute
118 121
119 await writeFilePromise(CONFIG.CUSTOM_FILE, JSON.stringify(toUpdateJSON, undefined, 2)) 122 await writeFilePromise(CONFIG.CUSTOM_FILE, JSON.stringify(toUpdateJSON, undefined, 2))
120 123
@@ -138,6 +141,7 @@ function customConfig (): CustomConfig {
138 name: CONFIG.INSTANCE.NAME, 141 name: CONFIG.INSTANCE.NAME,
139 description: CONFIG.INSTANCE.DESCRIPTION, 142 description: CONFIG.INSTANCE.DESCRIPTION,
140 terms: CONFIG.INSTANCE.TERMS, 143 terms: CONFIG.INSTANCE.TERMS,
144 defaultClientRoute: CONFIG.INSTANCE.DEFAULT_CLIENT_ROUTE,
141 customizations: { 145 customizations: {
142 css: CONFIG.INSTANCE.CUSTOMIZATIONS.CSS, 146 css: CONFIG.INSTANCE.CUSTOMIZATIONS.CSS,
143 javascript: CONFIG.INSTANCE.CUSTOMIZATIONS.JAVASCRIPT 147 javascript: CONFIG.INSTANCE.CUSTOMIZATIONS.JAVASCRIPT
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts
index 318df48bf..5946bcd11 100644
--- a/server/initializers/constants.ts
+++ b/server/initializers/constants.ts
@@ -159,6 +159,7 @@ const CONFIG = {
159 get NAME () { return config.get<string>('instance.name') }, 159 get NAME () { return config.get<string>('instance.name') },
160 get DESCRIPTION () { return config.get<string>('instance.description') }, 160 get DESCRIPTION () { return config.get<string>('instance.description') },
161 get TERMS () { return config.get<string>('instance.terms') }, 161 get TERMS () { return config.get<string>('instance.terms') },
162 get DEFAULT_CLIENT_ROUTE () { return config.get<string>('instance.default_client_route') },
162 CUSTOMIZATIONS: { 163 CUSTOMIZATIONS: {
163 get JAVASCRIPT () { return config.get<string>('instance.customizations.javascript') }, 164 get JAVASCRIPT () { return config.get<string>('instance.customizations.javascript') },
164 get CSS () { return config.get<string>('instance.customizations.css') } 165 get CSS () { return config.get<string>('instance.customizations.css') }
diff --git a/server/middlewares/validators/config.ts b/server/middlewares/validators/config.ts
index 800aaf107..ee6f6efa4 100644
--- a/server/middlewares/validators/config.ts
+++ b/server/middlewares/validators/config.ts
@@ -5,6 +5,12 @@ import { logger } from '../../helpers/logger'
5import { areValidationErrors } from './utils' 5import { areValidationErrors } from './utils'
6 6
7const customConfigUpdateValidator = [ 7const customConfigUpdateValidator = [
8 body('instance.name').exists().withMessage('Should have a valid instance name'),
9 body('instance.description').exists().withMessage('Should have a valid instance description'),
10 body('instance.terms').exists().withMessage('Should have a valid instance terms'),
11 body('instance.defaultClientRoute').exists().withMessage('Should have a valid instance default client route'),
12 body('instance.customizations.css').exists().withMessage('Should have a valid instance CSS customization'),
13 body('instance.customizations.javascript').exists().withMessage('Should have a valid instance JavaScript customization'),
8 body('cache.previews.size').isInt().withMessage('Should have a valid previews size'), 14 body('cache.previews.size').isInt().withMessage('Should have a valid previews size'),
9 body('signup.enabled').isBoolean().withMessage('Should have a valid signup enabled boolean'), 15 body('signup.enabled').isBoolean().withMessage('Should have a valid signup enabled boolean'),
10 body('signup.limit').isInt().withMessage('Should have a valid signup limit'), 16 body('signup.limit').isInt().withMessage('Should have a valid signup limit'),
diff --git a/server/tests/api/check-params/config.ts b/server/tests/api/check-params/config.ts
index a66e51a6a..ca8239270 100644
--- a/server/tests/api/check-params/config.ts
+++ b/server/tests/api/check-params/config.ts
@@ -18,6 +18,7 @@ describe('Test config API validators', function () {
18 name: 'PeerTube updated', 18 name: 'PeerTube updated',
19 description: 'my super description', 19 description: 'my super description',
20 terms: 'my super terms', 20 terms: 'my super terms',
21 defaultClientRoute: '/videos/recently-added',
21 customizations: { 22 customizations: {
22 javascript: 'alert("coucou")', 23 javascript: 'alert("coucou")',
23 css: 'body { background-color: red; }' 24 css: 'body { background-color: red; }'
diff --git a/server/tests/api/server/config.ts b/server/tests/api/server/config.ts
index 3d90580d8..271a57275 100644
--- a/server/tests/api/server/config.ts
+++ b/server/tests/api/server/config.ts
@@ -54,6 +54,7 @@ describe('Test config', function () {
54 expect(data.instance.name).to.equal('PeerTube') 54 expect(data.instance.name).to.equal('PeerTube')
55 expect(data.instance.description).to.equal('Welcome to this PeerTube instance!') 55 expect(data.instance.description).to.equal('Welcome to this PeerTube instance!')
56 expect(data.instance.terms).to.equal('No terms for now.') 56 expect(data.instance.terms).to.equal('No terms for now.')
57 expect(data.instance.defaultClientRoute).to.equal('/videos/trending')
57 expect(data.instance.customizations.css).to.be.empty 58 expect(data.instance.customizations.css).to.be.empty
58 expect(data.instance.customizations.javascript).to.be.empty 59 expect(data.instance.customizations.javascript).to.be.empty
59 expect(data.cache.previews.size).to.equal(1) 60 expect(data.cache.previews.size).to.equal(1)
@@ -76,6 +77,7 @@ describe('Test config', function () {
76 name: 'PeerTube updated', 77 name: 'PeerTube updated',
77 description: 'my super description', 78 description: 'my super description',
78 terms: 'my super terms', 79 terms: 'my super terms',
80 defaultClientRoute: '/videos/recently-added',
79 customizations: { 81 customizations: {
80 javascript: 'alert("coucou")', 82 javascript: 'alert("coucou")',
81 css: 'body { background-color: red; }' 83 css: 'body { background-color: red; }'
@@ -116,6 +118,7 @@ describe('Test config', function () {
116 expect(data.instance.name).to.equal('PeerTube updated') 118 expect(data.instance.name).to.equal('PeerTube updated')
117 expect(data.instance.description).to.equal('my super description') 119 expect(data.instance.description).to.equal('my super description')
118 expect(data.instance.terms).to.equal('my super terms') 120 expect(data.instance.terms).to.equal('my super terms')
121 expect(data.instance.defaultClientRoute).to.equal('/videos/recently-added')
119 expect(data.instance.customizations.javascript).to.equal('alert("coucou")') 122 expect(data.instance.customizations.javascript).to.equal('alert("coucou")')
120 expect(data.instance.customizations.css).to.equal('body { background-color: red; }') 123 expect(data.instance.customizations.css).to.equal('body { background-color: red; }')
121 expect(data.cache.previews.size).to.equal(2) 124 expect(data.cache.previews.size).to.equal(2)
@@ -145,6 +148,7 @@ describe('Test config', function () {
145 expect(data.instance.name).to.equal('PeerTube updated') 148 expect(data.instance.name).to.equal('PeerTube updated')
146 expect(data.instance.description).to.equal('my super description') 149 expect(data.instance.description).to.equal('my super description')
147 expect(data.instance.terms).to.equal('my super terms') 150 expect(data.instance.terms).to.equal('my super terms')
151 expect(data.instance.defaultClientRoute).to.equal('/videos/recently-added')
148 expect(data.instance.customizations.javascript).to.equal('alert("coucou")') 152 expect(data.instance.customizations.javascript).to.equal('alert("coucou")')
149 expect(data.instance.customizations.css).to.equal('body { background-color: red; }') 153 expect(data.instance.customizations.css).to.equal('body { background-color: red; }')
150 expect(data.cache.previews.size).to.equal(2) 154 expect(data.cache.previews.size).to.equal(2)
@@ -181,6 +185,7 @@ describe('Test config', function () {
181 expect(data.instance.name).to.equal('PeerTube') 185 expect(data.instance.name).to.equal('PeerTube')
182 expect(data.instance.description).to.equal('Welcome to this PeerTube instance!') 186 expect(data.instance.description).to.equal('Welcome to this PeerTube instance!')
183 expect(data.instance.terms).to.equal('No terms for now.') 187 expect(data.instance.terms).to.equal('No terms for now.')
188 expect(data.instance.defaultClientRoute).to.equal('/videos/trending')
184 expect(data.instance.customizations.css).to.be.empty 189 expect(data.instance.customizations.css).to.be.empty
185 expect(data.instance.customizations.javascript).to.be.empty 190 expect(data.instance.customizations.javascript).to.be.empty
186 expect(data.cache.previews.size).to.equal(1) 191 expect(data.cache.previews.size).to.equal(1)
diff --git a/shared/models/server/custom-config.model.ts b/shared/models/server/custom-config.model.ts
index 46d0a86ef..7f3e2df02 100644
--- a/shared/models/server/custom-config.model.ts
+++ b/shared/models/server/custom-config.model.ts
@@ -3,6 +3,7 @@ export interface CustomConfig {
3 name: string 3 name: string
4 description: string 4 description: string
5 terms: string 5 terms: string
6 defaultClientRoute: string
6 customizations: { 7 customizations: {
7 javascript?: string 8 javascript?: string
8 css?: string 9 css?: string
diff --git a/shared/models/server/server-config.model.ts b/shared/models/server/server-config.model.ts
index 004cf6ddb..a30c24eb9 100644
--- a/shared/models/server/server-config.model.ts
+++ b/shared/models/server/server-config.model.ts
@@ -2,7 +2,8 @@ export interface ServerConfig {
2 serverVersion: string 2 serverVersion: string
3 3
4 instance: { 4 instance: {
5 name: string; 5 name: string
6 defaultClientRoute: string
6 customizations: { 7 customizations: {
7 javascript: string 8 javascript: string
8 css: string 9 css: string