aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2018-03-23 14:26:20 +0100
committerChocobozzz <me@florianbigard.com>2018-03-23 14:26:20 +0100
commit0bd78bf30b2ae159791bdc90d17ed18e0327f621 (patch)
treee8f69cef499a99c51deeea39f7197b7ff93a80a2
parent9c673970f66fe91c665e1e3905fa768f57e11a18 (diff)
downloadPeerTube-0bd78bf30b2ae159791bdc90d17ed18e0327f621.tar.gz
PeerTube-0bd78bf30b2ae159791bdc90d17ed18e0327f621.tar.zst
PeerTube-0bd78bf30b2ae159791bdc90d17ed18e0327f621.zip
Proxify local storage and handle if it is unavailable
-rw-r--r--client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts8
-rw-r--r--client/src/app/core/auth/auth-user.model.ts59
-rw-r--r--client/src/app/core/server/server.service.ts5
-rw-r--r--client/src/app/shared/misc/peertube-local-storage.ts70
-rw-r--r--client/src/app/shared/rest/rest-table.ts5
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.ts8
6 files changed, 116 insertions, 39 deletions
diff --git a/client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts b/client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts
index e3f317e6d..ad2f05c6b 100644
--- a/client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts
+++ b/client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts
@@ -1,12 +1,12 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage'
2import { NotificationsService } from 'angular2-notifications' 3import { NotificationsService } from 'angular2-notifications'
3import { SortMeta } from 'primeng/primeng' 4import { SortMeta } from 'primeng/primeng'
4import { Job } from '../../../../../../shared/index' 5import { Job } from '../../../../../../shared/index'
5import { JobState } from '../../../../../../shared/models' 6import { JobState } from '../../../../../../shared/models'
6import { RestPagination, RestTable } from '../../../shared' 7import { RestPagination, RestTable } from '../../../shared'
7import { viewportHeight } from '../../../shared/misc/utils'
8import { JobService } from '../shared'
9import { RestExtractor } from '../../../shared/rest/rest-extractor.service' 8import { RestExtractor } from '../../../shared/rest/rest-extractor.service'
9import { JobService } from '../shared'
10 10
11@Component({ 11@Component({
12 selector: 'my-jobs-list', 12 selector: 'my-jobs-list',
@@ -56,12 +56,12 @@ export class JobsListComponent extends RestTable implements OnInit {
56 } 56 }
57 57
58 private loadJobState () { 58 private loadJobState () {
59 const result = localStorage.getItem(JobsListComponent.JOB_STATE_LOCAL_STORAGE_STATE) 59 const result = peertubeLocalStorage.getItem(JobsListComponent.JOB_STATE_LOCAL_STORAGE_STATE)
60 60
61 if (result) this.jobState = result as JobState 61 if (result) this.jobState = result as JobState
62 } 62 }
63 63
64 private saveJobState () { 64 private saveJobState () {
65 localStorage.setItem(JobsListComponent.JOB_STATE_LOCAL_STORAGE_STATE, this.jobState) 65 peertubeLocalStorage.setItem(JobsListComponent.JOB_STATE_LOCAL_STORAGE_STATE, this.jobState)
66 } 66 }
67} 67}
diff --git a/client/src/app/core/auth/auth-user.model.ts b/client/src/app/core/auth/auth-user.model.ts
index 9ad275392..366eea110 100644
--- a/client/src/app/core/auth/auth-user.model.ts
+++ b/client/src/app/core/auth/auth-user.model.ts
@@ -1,7 +1,8 @@
1import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage'
2import { UserRight } from '../../../../../shared/models/users/user-right.enum'
1// Do not use the barrel (dependency loop) 3// Do not use the barrel (dependency loop)
2import { hasUserRight, UserRole } from '../../../../../shared/models/users/user-role' 4import { hasUserRight, UserRole } from '../../../../../shared/models/users/user-role'
3import { User, UserConstructorHash } from '../../shared/users/user.model' 5import { User, UserConstructorHash } from '../../shared/users/user.model'
4import { UserRight } from '../../../../../shared/models/users/user-right.enum'
5 6
6export type TokenOptions = { 7export type TokenOptions = {
7 accessToken: string 8 accessToken: string
@@ -22,9 +23,9 @@ class Tokens {
22 tokenType: string 23 tokenType: string
23 24
24 static load () { 25 static load () {
25 const accessTokenLocalStorage = localStorage.getItem(this.KEYS.ACCESS_TOKEN) 26 const accessTokenLocalStorage = peertubeLocalStorage.getItem(this.KEYS.ACCESS_TOKEN)
26 const refreshTokenLocalStorage = localStorage.getItem(this.KEYS.REFRESH_TOKEN) 27 const refreshTokenLocalStorage = peertubeLocalStorage.getItem(this.KEYS.REFRESH_TOKEN)
27 const tokenTypeLocalStorage = localStorage.getItem(this.KEYS.TOKEN_TYPE) 28 const tokenTypeLocalStorage = peertubeLocalStorage.getItem(this.KEYS.TOKEN_TYPE)
28 29
29 if (accessTokenLocalStorage && refreshTokenLocalStorage && tokenTypeLocalStorage) { 30 if (accessTokenLocalStorage && refreshTokenLocalStorage && tokenTypeLocalStorage) {
30 return new Tokens({ 31 return new Tokens({
@@ -38,9 +39,9 @@ class Tokens {
38 } 39 }
39 40
40 static flush () { 41 static flush () {
41 localStorage.removeItem(this.KEYS.ACCESS_TOKEN) 42 peertubeLocalStorage.removeItem(this.KEYS.ACCESS_TOKEN)
42 localStorage.removeItem(this.KEYS.REFRESH_TOKEN) 43 peertubeLocalStorage.removeItem(this.KEYS.REFRESH_TOKEN)
43 localStorage.removeItem(this.KEYS.TOKEN_TYPE) 44 peertubeLocalStorage.removeItem(this.KEYS.TOKEN_TYPE)
44 } 45 }
45 46
46 constructor (hash?: TokenOptions) { 47 constructor (hash?: TokenOptions) {
@@ -57,9 +58,9 @@ class Tokens {
57 } 58 }
58 59
59 save () { 60 save () {
60 localStorage.setItem(Tokens.KEYS.ACCESS_TOKEN, this.accessToken) 61 peertubeLocalStorage.setItem(Tokens.KEYS.ACCESS_TOKEN, this.accessToken)
61 localStorage.setItem(Tokens.KEYS.REFRESH_TOKEN, this.refreshToken) 62 peertubeLocalStorage.setItem(Tokens.KEYS.REFRESH_TOKEN, this.refreshToken)
62 localStorage.setItem(Tokens.KEYS.TOKEN_TYPE, this.tokenType) 63 peertubeLocalStorage.setItem(Tokens.KEYS.TOKEN_TYPE, this.tokenType)
63 } 64 }
64} 65}
65 66
@@ -76,16 +77,16 @@ export class AuthUser extends User {
76 tokens: Tokens 77 tokens: Tokens
77 78
78 static load () { 79 static load () {
79 const usernameLocalStorage = localStorage.getItem(this.KEYS.USERNAME) 80 const usernameLocalStorage = peertubeLocalStorage.getItem(this.KEYS.USERNAME)
80 if (usernameLocalStorage) { 81 if (usernameLocalStorage) {
81 return new AuthUser( 82 return new AuthUser(
82 { 83 {
83 id: parseInt(localStorage.getItem(this.KEYS.ID), 10), 84 id: parseInt(peertubeLocalStorage.getItem(this.KEYS.ID), 10),
84 username: localStorage.getItem(this.KEYS.USERNAME), 85 username: peertubeLocalStorage.getItem(this.KEYS.USERNAME),
85 email: localStorage.getItem(this.KEYS.EMAIL), 86 email: peertubeLocalStorage.getItem(this.KEYS.EMAIL),
86 role: parseInt(localStorage.getItem(this.KEYS.ROLE), 10) as UserRole, 87 role: parseInt(peertubeLocalStorage.getItem(this.KEYS.ROLE), 10) as UserRole,
87 displayNSFW: localStorage.getItem(this.KEYS.DISPLAY_NSFW) === 'true', 88 displayNSFW: peertubeLocalStorage.getItem(this.KEYS.DISPLAY_NSFW) === 'true',
88 autoPlayVideo: localStorage.getItem(this.KEYS.AUTO_PLAY_VIDEO) === 'true' 89 autoPlayVideo: peertubeLocalStorage.getItem(this.KEYS.AUTO_PLAY_VIDEO) === 'true'
89 }, 90 },
90 Tokens.load() 91 Tokens.load()
91 ) 92 )
@@ -95,12 +96,12 @@ export class AuthUser extends User {
95 } 96 }
96 97
97 static flush () { 98 static flush () {
98 localStorage.removeItem(this.KEYS.USERNAME) 99 peertubeLocalStorage.removeItem(this.KEYS.USERNAME)
99 localStorage.removeItem(this.KEYS.ID) 100 peertubeLocalStorage.removeItem(this.KEYS.ID)
100 localStorage.removeItem(this.KEYS.ROLE) 101 peertubeLocalStorage.removeItem(this.KEYS.ROLE)
101 localStorage.removeItem(this.KEYS.DISPLAY_NSFW) 102 peertubeLocalStorage.removeItem(this.KEYS.DISPLAY_NSFW)
102 localStorage.removeItem(this.KEYS.AUTO_PLAY_VIDEO) 103 peertubeLocalStorage.removeItem(this.KEYS.AUTO_PLAY_VIDEO)
103 localStorage.removeItem(this.KEYS.EMAIL) 104 peertubeLocalStorage.removeItem(this.KEYS.EMAIL)
104 Tokens.flush() 105 Tokens.flush()
105 } 106 }
106 107
@@ -131,12 +132,12 @@ export class AuthUser extends User {
131 } 132 }
132 133
133 save () { 134 save () {
134 localStorage.setItem(AuthUser.KEYS.ID, this.id.toString()) 135 peertubeLocalStorage.setItem(AuthUser.KEYS.ID, this.id.toString())
135 localStorage.setItem(AuthUser.KEYS.USERNAME, this.username) 136 peertubeLocalStorage.setItem(AuthUser.KEYS.USERNAME, this.username)
136 localStorage.setItem(AuthUser.KEYS.EMAIL, this.email) 137 peertubeLocalStorage.setItem(AuthUser.KEYS.EMAIL, this.email)
137 localStorage.setItem(AuthUser.KEYS.ROLE, this.role.toString()) 138 peertubeLocalStorage.setItem(AuthUser.KEYS.ROLE, this.role.toString())
138 localStorage.setItem(AuthUser.KEYS.DISPLAY_NSFW, JSON.stringify(this.displayNSFW)) 139 peertubeLocalStorage.setItem(AuthUser.KEYS.DISPLAY_NSFW, JSON.stringify(this.displayNSFW))
139 localStorage.setItem(AuthUser.KEYS.AUTO_PLAY_VIDEO, JSON.stringify(this.autoPlayVideo)) 140 peertubeLocalStorage.setItem(AuthUser.KEYS.AUTO_PLAY_VIDEO, JSON.stringify(this.autoPlayVideo))
140 this.tokens.save() 141 this.tokens.save()
141 } 142 }
142} 143}
diff --git a/client/src/app/core/server/server.service.ts b/client/src/app/core/server/server.service.ts
index 0b63ef5be..206ec7bcd 100644
--- a/client/src/app/core/server/server.service.ts
+++ b/client/src/app/core/server/server.service.ts
@@ -1,5 +1,6 @@
1import { HttpClient } from '@angular/common/http' 1import { HttpClient } from '@angular/common/http'
2import { Injectable } from '@angular/core' 2import { Injectable } from '@angular/core'
3import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage'
3import 'rxjs/add/operator/do' 4import 'rxjs/add/operator/do'
4import { ReplaySubject } from 'rxjs/ReplaySubject' 5import { ReplaySubject } from 'rxjs/ReplaySubject'
5import { ServerConfig } from '../../../../../shared' 6import { ServerConfig } from '../../../../../shared'
@@ -140,11 +141,11 @@ export class ServerService {
140 } 141 }
141 142
142 private saveConfigLocally (config: ServerConfig) { 143 private saveConfigLocally (config: ServerConfig) {
143 localStorage.setItem(ServerService.CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config)) 144 peertubeLocalStorage.setItem(ServerService.CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config))
144 } 145 }
145 146
146 private loadConfigLocally () { 147 private loadConfigLocally () {
147 const configString = localStorage.getItem(ServerService.CONFIG_LOCAL_STORAGE_KEY) 148 const configString = peertubeLocalStorage.getItem(ServerService.CONFIG_LOCAL_STORAGE_KEY)
148 149
149 if (configString) { 150 if (configString) {
150 try { 151 try {
diff --git a/client/src/app/shared/misc/peertube-local-storage.ts b/client/src/app/shared/misc/peertube-local-storage.ts
new file mode 100644
index 000000000..ad761c82f
--- /dev/null
+++ b/client/src/app/shared/misc/peertube-local-storage.ts
@@ -0,0 +1,70 @@
1// Thanks: https://github.com/capaj/localstorage-polyfill
2
3const valuesMap = new Map()
4
5class MemoryStorage {
6 [key: string]: any
7 [index: number]: string
8
9 getItem (key) {
10 const stringKey = String(key)
11 if (valuesMap.has(key)) {
12 return String(valuesMap.get(stringKey))
13 }
14
15 return null
16 }
17
18 setItem (key, val) {
19 valuesMap.set(String(key), String(val))
20 }
21
22 removeItem (key) {
23 valuesMap.delete(key)
24 }
25
26 clear () {
27 valuesMap.clear()
28 }
29
30 key (i: any) {
31 if (arguments.length === 0) {
32 throw new TypeError('Failed to execute "key" on "Storage": 1 argument required, but only 0 present.')
33 }
34
35 const arr = Array.from(valuesMap.keys())
36 return arr[i]
37 }
38
39 get length () {
40 return valuesMap.size
41 }
42}
43
44let peertubeLocalStorage: Storage
45try {
46 peertubeLocalStorage = localStorage
47} catch (err) {
48 const instance = new MemoryStorage()
49
50 peertubeLocalStorage = new Proxy(instance, {
51 set: function (obj, prop, value) {
52 if (MemoryStorage.prototype.hasOwnProperty(prop)) {
53 instance[prop] = value
54 } else {
55 instance.setItem(prop, value)
56 }
57 return true
58 },
59 get: function (target, name) {
60 if (MemoryStorage.prototype.hasOwnProperty(name)) {
61 return instance[name]
62 }
63 if (valuesMap.has(name)) {
64 return instance.getItem(name)
65 }
66 }
67 })
68}
69
70export { peertubeLocalStorage }
diff --git a/client/src/app/shared/rest/rest-table.ts b/client/src/app/shared/rest/rest-table.ts
index 165fc4e45..fe1a91d2d 100644
--- a/client/src/app/shared/rest/rest-table.ts
+++ b/client/src/app/shared/rest/rest-table.ts
@@ -1,3 +1,4 @@
1import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage'
1import { LazyLoadEvent } from 'primeng/components/common/lazyloadevent' 2import { LazyLoadEvent } from 'primeng/components/common/lazyloadevent'
2import { SortMeta } from 'primeng/components/common/sortmeta' 3import { SortMeta } from 'primeng/components/common/sortmeta'
3 4
@@ -15,7 +16,7 @@ export abstract class RestTable {
15 protected abstract loadData (): void 16 protected abstract loadData (): void
16 17
17 loadSort () { 18 loadSort () {
18 const result = localStorage.getItem(this.sortLocalStorageKey) 19 const result = peertubeLocalStorage.getItem(this.sortLocalStorageKey)
19 20
20 if (result) { 21 if (result) {
21 try { 22 try {
@@ -42,7 +43,7 @@ export abstract class RestTable {
42 } 43 }
43 44
44 saveSort () { 45 saveSort () {
45 localStorage.setItem(this.sortLocalStorageKey, JSON.stringify(this.sort)) 46 peertubeLocalStorage.setItem(this.sortLocalStorageKey, JSON.stringify(this.sort))
46 } 47 }
47 48
48} 49}
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 b60e58fb0..fda69efab 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/videos/+video-watch/video-watch.component.ts
@@ -1,6 +1,7 @@
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 { RedirectService } from '@app/core/routing/redirect.service'
4import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage'
4import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component' 5import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component'
5import { MetaService } from '@ngx-meta/core' 6import { MetaService } from '@ngx-meta/core'
6import { NotificationsService } from 'angular2-notifications' 7import { NotificationsService } from 'angular2-notifications'
@@ -75,7 +76,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
75 } 76 }
76 77
77 ngOnInit () { 78 ngOnInit () {
78 if (WebTorrent.WEBRTC_SUPPORT === false || localStorage.getItem(VideoWatchComponent.LOCAL_STORAGE_PRIVACY_CONCERN_KEY) === 'true') { 79 if (
80 WebTorrent.WEBRTC_SUPPORT === false ||
81 peertubeLocalStorage.getItem(VideoWatchComponent.LOCAL_STORAGE_PRIVACY_CONCERN_KEY) === 'true'
82 ) {
79 this.hasAlreadyAcceptedPrivacyConcern = true 83 this.hasAlreadyAcceptedPrivacyConcern = true
80 } 84 }
81 85
@@ -262,7 +266,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
262 } 266 }
263 267
264 acceptedPrivacyConcern () { 268 acceptedPrivacyConcern () {
265 localStorage.setItem(VideoWatchComponent.LOCAL_STORAGE_PRIVACY_CONCERN_KEY, 'true') 269 peertubeLocalStorage.setItem(VideoWatchComponent.LOCAL_STORAGE_PRIVACY_CONCERN_KEY, 'true')
266 this.hasAlreadyAcceptedPrivacyConcern = true 270 this.hasAlreadyAcceptedPrivacyConcern = true
267 } 271 }
268 272