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