|
1 | | -function getStorage(storage: Storage, key: string): string | null { |
| 1 | +function getStorage(storage: () => Storage, key: string): string | null { |
2 | 2 | try { |
3 | | - return storage.getItem(key); |
| 3 | + return storage().getItem(key); |
4 | 4 | } catch (e) { |
5 | 5 | return null; |
6 | 6 | } |
7 | 7 | } |
8 | 8 |
|
9 | | -function setStorage(storage: Storage, key: string, value: string): boolean { |
| 9 | +function setStorage( |
| 10 | + storage: () => Storage, |
| 11 | + key: string, |
| 12 | + value: string, |
| 13 | +): boolean { |
10 | 14 | try { |
11 | | - storage.setItem(key, value); |
12 | | - return storage.getItem(key) === value; |
| 15 | + storage().setItem(key, value); |
| 16 | + return storage().getItem(key) === value; |
13 | 17 | } catch (e) { |
14 | 18 | return false; |
15 | 19 | } |
16 | 20 | } |
17 | 21 |
|
18 | | -function deleteStorage(storage: Storage, key: string) { |
| 22 | +function deleteStorage(storage: () => Storage, key: string) { |
19 | 23 | try { |
20 | | - storage.removeItem(key); |
| 24 | + storage().removeItem(key); |
21 | 25 | } catch (e) { |
22 | 26 | // ignore |
23 | 27 | } |
@@ -62,30 +66,35 @@ function deleteCookie(key: string) { |
62 | 66 | ); |
63 | 67 | } |
64 | 68 |
|
| 69 | +// accessing these properties can throw SecurityException (e.g. in Safari with 'Block all cookies' enabled), |
| 70 | +// so we provide them as getters, which are called within try...catch blocks on use |
| 71 | +const getLocalStorage = () => window.localStorage; |
| 72 | +const getSessionStorage = () => window.sessionStorage; |
| 73 | + |
65 | 74 | export const storage = { |
66 | 75 | setItem(key: string, value: string): boolean { |
67 | 76 | let any = false; |
68 | 77 | // sessionStorage is best option for security and privacy |
69 | | - if (setStorage(window.sessionStorage, key, value)) { |
| 78 | + if (setStorage(getSessionStorage, key, value)) { |
70 | 79 | any = true; |
71 | 80 | } |
72 | 81 | // if sessionStorage fails for any reason, throw everything at the wall and see what sticks: |
73 | | - any = setStorage(window.localStorage, key, value) || any; // do not short-circuit |
| 82 | + any = setStorage(getLocalStorage, key, value) || any; // do not short-circuit |
74 | 83 | any = setSessionCookie(key, value) || any; |
75 | 84 | return any; |
76 | 85 | }, |
77 | 86 |
|
78 | 87 | getItem(key: string): string | null { |
79 | 88 | return ( |
80 | | - getStorage(window.sessionStorage, key) || |
81 | | - getStorage(window.localStorage, key) || |
| 89 | + getStorage(getSessionStorage, key) || |
| 90 | + getStorage(getLocalStorage, key) || |
82 | 91 | getCookie(key) |
83 | 92 | ); |
84 | 93 | }, |
85 | 94 |
|
86 | 95 | removeItem(key: string) { |
87 | | - deleteStorage(window.sessionStorage, key); |
88 | | - deleteStorage(window.localStorage, key); |
| 96 | + deleteStorage(getSessionStorage, key); |
| 97 | + deleteStorage(getLocalStorage, key); |
89 | 98 | deleteCookie(key); |
90 | 99 | }, |
91 | 100 | }; |
0 commit comments