]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/core/routing/redirect.service.ts
db4b3501862f6986efd036fa09473d028d966ab1
[github/Chocobozzz/PeerTube.git] / client / src / app / core / routing / redirect.service.ts
1 import * as debug from 'debug'
2 import { Injectable } from '@angular/core'
3 import { NavigationCancel, NavigationEnd, Router } from '@angular/router'
4 import { ServerService } from '../server'
5 import { SessionStorageService } from '../wrappers/storage.service'
6
7 const logger = debug('peertube:router:RedirectService')
8
9 @Injectable()
10 export class RedirectService {
11 private static SESSION_STORAGE_LATEST_SESSION_URL_KEY = 'redirect-latest-session-url'
12
13 // Default route could change according to the instance configuration
14 static INIT_DEFAULT_ROUTE = '/videos/trending'
15 static INIT_DEFAULT_TRENDING_ALGORITHM = 'most-viewed'
16
17 private previousUrl: string
18 private currentUrl: string
19
20 private latestSessionUrl: string
21
22 private redirectingToHomepage = false
23 private defaultTrendingAlgorithm = RedirectService.INIT_DEFAULT_TRENDING_ALGORITHM
24 private defaultRoute = RedirectService.INIT_DEFAULT_ROUTE
25
26 constructor (
27 private router: Router,
28 private serverService: ServerService,
29 private storage: SessionStorageService
30 ) {
31 // The config is first loaded from the cache so try to get the default route
32 const config = this.serverService.getHTMLConfig()
33 if (config?.instance?.defaultClientRoute) {
34 this.defaultRoute = config.instance.defaultClientRoute
35 }
36 if (config?.trending?.videos?.algorithms?.default) {
37 this.defaultTrendingAlgorithm = config.trending.videos.algorithms.default
38 }
39
40 this.latestSessionUrl = this.storage.getItem(RedirectService.SESSION_STORAGE_LATEST_SESSION_URL_KEY)
41 this.storage.removeItem(RedirectService.SESSION_STORAGE_LATEST_SESSION_URL_KEY)
42
43 logger('Loaded latest session URL %s', this.latestSessionUrl)
44
45 // Track previous url
46 this.currentUrl = this.router.url
47 router.events.subscribe(event => {
48 if (event instanceof NavigationEnd || event instanceof NavigationCancel) {
49 if (event.url === '/404') return
50
51 this.previousUrl = this.currentUrl
52 this.currentUrl = event.url
53
54 logger('Previous URL is %s, current URL is %s', this.previousUrl, this.currentUrl)
55 logger('Setting %s as latest URL in session storage.', this.currentUrl)
56
57 this.storage.setItem(RedirectService.SESSION_STORAGE_LATEST_SESSION_URL_KEY, this.currentUrl)
58 }
59 })
60 }
61
62 getDefaultRoute () {
63 return this.defaultRoute
64 }
65
66 getDefaultTrendingAlgorithm () {
67 return this.defaultTrendingAlgorithm
68 }
69
70 redirectToLatestSessionRoute () {
71 return this.doRedirect(this.latestSessionUrl)
72 }
73
74 redirectToPreviousRoute (fallbackRoute?: string) {
75 return this.doRedirect(this.previousUrl, fallbackRoute)
76 }
77
78 getPreviousUrl () {
79 return this.previousUrl
80 }
81
82 redirectToHomepage (skipLocationChange = false) {
83 if (this.redirectingToHomepage) return
84
85 this.redirectingToHomepage = true
86
87 console.log('Redirecting to %s...', this.defaultRoute)
88
89 this.router.navigateByUrl(this.defaultRoute, { skipLocationChange })
90 .then(() => this.redirectingToHomepage = false)
91 .catch(() => {
92 this.redirectingToHomepage = false
93
94 console.error(
95 'Cannot navigate to %s, resetting default route to %s.',
96 this.defaultRoute,
97 RedirectService.INIT_DEFAULT_ROUTE
98 )
99
100 this.defaultRoute = RedirectService.INIT_DEFAULT_ROUTE
101 return this.router.navigateByUrl(this.defaultRoute, { skipLocationChange })
102 })
103
104 }
105
106 private doRedirect (redirectUrl: string, fallbackRoute?: string) {
107 logger('Redirecting on %s', redirectUrl)
108
109 if (this.isValidRedirection(redirectUrl)) {
110 return this.router.navigateByUrl(redirectUrl)
111 }
112
113 logger('%s is not a valid redirection, try fallback route %s', redirectUrl, fallbackRoute)
114 if (fallbackRoute) {
115 return this.router.navigateByUrl(fallbackRoute)
116 }
117
118 logger('There was no fallback route, redirecting to homepage')
119 return this.redirectToHomepage()
120 }
121
122 private isValidRedirection (redirectUrl: string) {
123 const exceptions = [
124 '/verify-account',
125 '/reset-password',
126 '/login'
127 ]
128
129 if (!redirectUrl || redirectUrl === '/') return false
130
131 return exceptions.every(e => !redirectUrl.startsWith(e))
132 }
133 }