Fix mobile white screen when localStorage throws on access (#54) #55
@@ -9,6 +9,21 @@
|
||||
export const ACCESS_TOKEN_KEY = "access_token";
|
||||
export const REFRESH_TOKEN_KEY = "refresh_token";
|
||||
|
||||
/**
|
||||
* Browsers can expose localStorage but throw on access (privacy mode / blocked storage).
|
||||
* @returns {Storage|null}
|
||||
*/
|
||||
function getLocalStorageSafe() {
|
||||
try {
|
||||
if (typeof window === "undefined" || !window.localStorage) {
|
||||
return null;
|
||||
}
|
||||
return window.localStorage;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {{ get?: Function, set?: Function, remove?: Function } | undefined}
|
||||
*/
|
||||
@@ -24,10 +39,15 @@ function getPreferencesPlugin() {
|
||||
* @returns {string|null}
|
||||
*/
|
||||
export function getToken(key) {
|
||||
if (typeof localStorage === "undefined") {
|
||||
const storage = getLocalStorageSafe();
|
||||
if (!storage) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return storage.getItem(key);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
return localStorage.getItem(key);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,10 +71,15 @@ export function getRefreshToken() {
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function setTokens(access, refresh) {
|
||||
if (typeof localStorage !== "undefined") {
|
||||
localStorage.setItem(ACCESS_TOKEN_KEY, access);
|
||||
if (refresh != null) {
|
||||
localStorage.setItem(REFRESH_TOKEN_KEY, refresh);
|
||||
const storage = getLocalStorageSafe();
|
||||
if (storage) {
|
||||
try {
|
||||
storage.setItem(ACCESS_TOKEN_KEY, access);
|
||||
if (refresh != null) {
|
||||
storage.setItem(REFRESH_TOKEN_KEY, refresh);
|
||||
}
|
||||
} catch {
|
||||
/* localStorage unavailable */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,9 +100,14 @@ export async function setTokens(access, refresh) {
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function clearTokens() {
|
||||
if (typeof localStorage !== "undefined") {
|
||||
localStorage.removeItem(ACCESS_TOKEN_KEY);
|
||||
localStorage.removeItem(REFRESH_TOKEN_KEY);
|
||||
const storage = getLocalStorageSafe();
|
||||
if (storage) {
|
||||
try {
|
||||
storage.removeItem(ACCESS_TOKEN_KEY);
|
||||
storage.removeItem(REFRESH_TOKEN_KEY);
|
||||
} catch {
|
||||
/* localStorage unavailable */
|
||||
}
|
||||
}
|
||||
|
||||
const Preferences = getPreferencesPlugin();
|
||||
@@ -110,7 +140,8 @@ export async function hydrateTokensFromNativeStorage() {
|
||||
try {
|
||||
const result = await Preferences.get({ key: ACCESS_TOKEN_KEY });
|
||||
if (result?.value) {
|
||||
localStorage.setItem(ACCESS_TOKEN_KEY, result.value);
|
||||
const storage = getLocalStorageSafe();
|
||||
storage?.setItem(ACCESS_TOKEN_KEY, result.value);
|
||||
access = result.value;
|
||||
}
|
||||
} catch {
|
||||
@@ -122,7 +153,8 @@ export async function hydrateTokensFromNativeStorage() {
|
||||
try {
|
||||
const result = await Preferences.get({ key: REFRESH_TOKEN_KEY });
|
||||
if (result?.value) {
|
||||
localStorage.setItem(REFRESH_TOKEN_KEY, result.value);
|
||||
const storage = getLocalStorageSafe();
|
||||
storage?.setItem(REFRESH_TOKEN_KEY, result.value);
|
||||
refresh = result.value;
|
||||
}
|
||||
} catch {
|
||||
|
||||
Reference in New Issue
Block a user