Manav Rathi 261a7f278b
Fix
2024-09-06 19:58:13 +05:30

101 lines
3.3 KiB
TypeScript

import { getKV, removeKV, setKV } from "@/base/kv";
import log from "@/base/log";
export enum LS_KEYS {
USER = "user",
KEY_ATTRIBUTES = "keyAttributes",
ORIGINAL_KEY_ATTRIBUTES = "originalKeyAttributes",
SUBSCRIPTION = "subscription",
FAMILY_DATA = "familyData",
IS_FIRST_LOGIN = "isFirstLogin",
JUST_SIGNED_UP = "justSignedUp",
SHOW_BACK_BUTTON = "showBackButton",
EXPORT = "export",
// LOGS = "logs",
USER_DETAILS = "userDetails",
COLLECTION_SORT_BY = "collectionSortBy",
THEME = "theme",
// Moved to the new wrapper @/base/local-storage
// LOCALE = 'locale',
MAP_ENABLED = "mapEnabled",
SRP_SETUP_ATTRIBUTES = "srpSetupAttributes",
SRP_ATTRIBUTES = "srpAttributes",
CF_PROXY_DISABLED = "cfProxyDisabled",
REFERRAL_SOURCE = "referralSource",
}
export const setData = (key: LS_KEYS, value: object) =>
localStorage.setItem(key, JSON.stringify(value));
export const removeData = (key: LS_KEYS) => localStorage.removeItem(key);
export const getData = (key: LS_KEYS) => {
try {
if (
typeof localStorage === "undefined" ||
typeof key === "undefined" ||
typeof localStorage.getItem(key) === "undefined" ||
localStorage.getItem(key) === "undefined"
) {
return null;
}
const data = localStorage.getItem(key);
return data && JSON.parse(data);
} catch (e) {
log.error(`Failed to Parse JSON for key ${key}`, e);
}
};
// TODO: Migrate this to `local-user.ts`, with (a) more precise optionality
// indication of the constituent fields, (b) moving any fields that need to be
// accessed from web workers to KV DB.
//
// Creating a new function here to act as a funnel point.
export const setLSUser = async (user: object) => {
await migrateKVToken(user);
setData(LS_KEYS.USER, user);
};
/**
* Update the "token" KV with the token (if any) for the given {@link user}.
*
* This is an internal implementation details of {@link setLSUser} and doesn't
* need to exposed conceptually. For now though, we need to call this externally
* at an early point in the app startup to also copy over the token into KV DB
* for existing users.
*
* This was added 1 July 2024, can be removed after a while and this code
* inlined into `setLSUser` (tag: Migration).
*/
export const migrateKVToken = async (user: unknown) => {
// Throw an error if the data is in local storage but not in IndexedDB. This
// is a pre-cursor to inlining this code.
// TODO(REL): Remove this sanity check after a few days.
const oldLSUser = getData(LS_KEYS.USER);
const wasMissing =
oldLSUser &&
typeof oldLSUser == "object" &&
"token" in oldLSUser &&
typeof oldLSUser.token == "string" &&
!(await getKV("token"));
user &&
typeof user == "object" &&
"id" in user &&
typeof user.id == "number"
? await setKV("userID", user.id)
: await removeKV("userID");
user &&
typeof user == "object" &&
"token" in user &&
typeof user.token == "string"
? await setKV("token", user.token)
: await removeKV("token");
if (wasMissing)
throw new Error(
"The user's token was present in local storage but not in IndexedDB",
);
};