]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/core/users/user-local-storage.service.ts
Merge branch 'release/5.0.0' into develop
[github/Chocobozzz/PeerTube.git] / client / src / app / core / users / user-local-storage.service.ts
1
2 import { filter, throttleTime } from 'rxjs'
3 import { Injectable } from '@angular/core'
4 import { AuthService, AuthStatus } from '@app/core/auth'
5 import { getBoolOrDefault } from '@root-helpers/local-storage-utils'
6 import { logger } from '@root-helpers/logger'
7 import { UserLocalStorageKeys, OAuthUserTokens } from '@root-helpers/users'
8 import { UserRole, UserUpdateMe } from '@shared/models'
9 import { NSFWPolicyType } from '@shared/models/videos'
10 import { ServerService } from '../server'
11 import { LocalStorageService } from '../wrappers/storage.service'
12
13 @Injectable()
14 export class UserLocalStorageService {
15
16 constructor (
17 private authService: AuthService,
18 private server: ServerService,
19 private localStorageService: LocalStorageService
20 ) {
21 this.authService.userInformationLoaded.subscribe({
22 next: () => {
23 const user = this.authService.getUser()
24
25 this.setLoggedInUser(user)
26 this.setUserInfo(user)
27 this.setTokens(user.oauthTokens)
28 }
29 })
30
31 this.authService.loginChangedSource
32 .pipe(filter(status => status === AuthStatus.LoggedOut))
33 .subscribe({
34 next: () => {
35 this.flushLoggedInUser()
36 this.flushUserInfo()
37 this.flushTokens()
38 }
39 })
40
41 this.authService.tokensRefreshed
42 .subscribe({
43 next: () => {
44 const user = this.authService.getUser()
45
46 this.setTokens(user.oauthTokens)
47 }
48 })
49 }
50
51 // ---------------------------------------------------------------------------
52
53 getLoggedInUser () {
54 const usernameLocalStorage = this.localStorageService.getItem(UserLocalStorageKeys.USERNAME)
55
56 if (!usernameLocalStorage) return undefined
57
58 return {
59 id: parseInt(this.localStorageService.getItem(UserLocalStorageKeys.ID), 10),
60 username: this.localStorageService.getItem(UserLocalStorageKeys.USERNAME),
61 email: this.localStorageService.getItem(UserLocalStorageKeys.EMAIL),
62 role: {
63 id: parseInt(this.localStorageService.getItem(UserLocalStorageKeys.ROLE), 10) as UserRole,
64 label: ''
65 },
66
67 ...this.getUserInfo()
68 }
69 }
70
71 setLoggedInUser (user: {
72 id: number
73 username: string
74 email: string
75 role: {
76 id: UserRole
77 }
78 }) {
79 this.localStorageService.setItem(UserLocalStorageKeys.ID, user.id.toString())
80 this.localStorageService.setItem(UserLocalStorageKeys.USERNAME, user.username)
81 this.localStorageService.setItem(UserLocalStorageKeys.EMAIL, user.email)
82 this.localStorageService.setItem(UserLocalStorageKeys.ROLE, user.role.id.toString())
83 }
84
85 flushLoggedInUser () {
86 this.localStorageService.removeItem(UserLocalStorageKeys.ID)
87 this.localStorageService.removeItem(UserLocalStorageKeys.USERNAME)
88 this.localStorageService.removeItem(UserLocalStorageKeys.EMAIL)
89 this.localStorageService.removeItem(UserLocalStorageKeys.ROLE)
90 }
91
92 // ---------------------------------------------------------------------------
93
94 getUserInfo () {
95 let videoLanguages: string[]
96
97 try {
98 const languagesString = this.localStorageService.getItem(UserLocalStorageKeys.VIDEO_LANGUAGES)
99 videoLanguages = languagesString && languagesString !== 'undefined'
100 ? JSON.parse(languagesString)
101 : null
102 } catch (err) {
103 videoLanguages = null
104 logger.error('Cannot parse desired video languages from localStorage.', err)
105 }
106
107 const htmlConfig = this.server.getHTMLConfig()
108
109 const defaultNSFWPolicy = htmlConfig.instance.defaultNSFWPolicy
110 const defaultP2PEnabled = htmlConfig.defaults.p2p.webapp.enabled
111
112 return {
113 nsfwPolicy: this.localStorageService.getItem<NSFWPolicyType>(UserLocalStorageKeys.NSFW_POLICY) || defaultNSFWPolicy,
114 p2pEnabled: getBoolOrDefault(this.localStorageService.getItem(UserLocalStorageKeys.P2P_ENABLED), defaultP2PEnabled),
115 theme: this.localStorageService.getItem(UserLocalStorageKeys.THEME) || 'instance-default',
116 videoLanguages,
117
118 autoPlayVideo: getBoolOrDefault(this.localStorageService.getItem(UserLocalStorageKeys.AUTO_PLAY_VIDEO), true),
119 autoPlayNextVideo: getBoolOrDefault(this.localStorageService.getItem(UserLocalStorageKeys.AUTO_PLAY_NEXT_VIDEO), false),
120 autoPlayNextVideoPlaylist: getBoolOrDefault(this.localStorageService.getItem(UserLocalStorageKeys.AUTO_PLAY_VIDEO_PLAYLIST), true)
121 }
122 }
123
124 setUserInfo (profile: UserUpdateMe) {
125 const localStorageKeys: { [ id in keyof UserUpdateMe ]: string } = {
126 nsfwPolicy: UserLocalStorageKeys.NSFW_POLICY,
127 p2pEnabled: UserLocalStorageKeys.P2P_ENABLED,
128 autoPlayVideo: UserLocalStorageKeys.AUTO_PLAY_VIDEO,
129 autoPlayNextVideo: UserLocalStorageKeys.AUTO_PLAY_NEXT_VIDEO,
130 autoPlayNextVideoPlaylist: UserLocalStorageKeys.AUTO_PLAY_VIDEO_PLAYLIST,
131 theme: UserLocalStorageKeys.THEME,
132 videoLanguages: UserLocalStorageKeys.VIDEO_LANGUAGES
133 }
134
135 const obj = Object.keys(localStorageKeys)
136 .filter(key => key in profile)
137 .map(key => ([ localStorageKeys[key], profile[key] ]))
138
139 for (const [ key, value ] of obj) {
140 try {
141 if (value === undefined) {
142 this.localStorageService.removeItem(key)
143 continue
144 }
145
146 const localStorageValue = typeof value === 'string'
147 ? value
148 : JSON.stringify(value)
149
150 this.localStorageService.setItem(key, localStorageValue)
151 } catch (err) {
152 logger.error(`Cannot set ${key}->${value} in localStorage. Likely due to a value impossible to stringify.`, err)
153 }
154 }
155 }
156
157 flushUserInfo () {
158 this.localStorageService.removeItem(UserLocalStorageKeys.NSFW_POLICY)
159 this.localStorageService.removeItem(UserLocalStorageKeys.P2P_ENABLED)
160 this.localStorageService.removeItem(UserLocalStorageKeys.AUTO_PLAY_VIDEO)
161 this.localStorageService.removeItem(UserLocalStorageKeys.AUTO_PLAY_VIDEO_PLAYLIST)
162 this.localStorageService.removeItem(UserLocalStorageKeys.THEME)
163 this.localStorageService.removeItem(UserLocalStorageKeys.VIDEO_LANGUAGES)
164 }
165
166 listenUserInfoChange () {
167 return this.localStorageService.watch([
168 UserLocalStorageKeys.NSFW_POLICY,
169 UserLocalStorageKeys.P2P_ENABLED,
170 UserLocalStorageKeys.AUTO_PLAY_VIDEO,
171 UserLocalStorageKeys.AUTO_PLAY_VIDEO_PLAYLIST,
172 UserLocalStorageKeys.THEME,
173 UserLocalStorageKeys.VIDEO_LANGUAGES
174 ]).pipe(
175 throttleTime(200),
176 filter(() => this.authService.isLoggedIn() !== true)
177 )
178 }
179
180 // ---------------------------------------------------------------------------
181
182 getTokens () {
183 return OAuthUserTokens.getUserTokens(this.localStorageService)
184 }
185
186 setTokens (tokens: OAuthUserTokens) {
187 OAuthUserTokens.saveToLocalStorage(this.localStorageService, tokens)
188 }
189
190 flushTokens () {
191 OAuthUserTokens.flushLocalStorage(this.localStorageService)
192 }
193 }