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