Skip to content

Commit

Permalink
Use localForage instead of localStorage in most cases
Browse files Browse the repository at this point in the history
  • Loading branch information
robknight committed Jan 24, 2025
1 parent 79efcda commit e2d3125
Show file tree
Hide file tree
Showing 14 changed files with 130 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function PrivacyNoticeModal(): JSX.Element {
});
} else {
// Persist to local storage and sync this later
savePrivacyNoticeAgreed(LATEST_PRIVACY_NOTICE);
await savePrivacyNoticeAgreed(LATEST_PRIVACY_NOTICE);
dispatch({
type: "handle-agreed-privacy-notice",
version: LATEST_PRIVACY_NOTICE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const NewUpdatedTermsScreen = (): JSX.Element => {
});
} else {
// Persist to local storage and sync this later
savePrivacyNoticeAgreed(LATEST_PRIVACY_NOTICE);
await savePrivacyNoticeAgreed(LATEST_PRIVACY_NOTICE);
dispatch({
type: "handle-agreed-privacy-notice",
version: LATEST_PRIVACY_NOTICE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const ChangePasswordModal = (): JSX.Element | null => {
try {
let currentEncryptionKey: HexString;
if (!hasSetupPassword) {
currentEncryptionKey = loadEncryptionKey() as string;
currentEncryptionKey = (await loadEncryptionKey()) as string;
} else {
const saltResult = await requestPasswordSalt(
appConfig.zupassServer,
Expand Down
1 change: 1 addition & 0 deletions apps/passport-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"handlebars": "^4.7.7",
"isomorphic-timers-promises": "^1.0.1",
"js-sha256": "^0.11.0",
"localforage": "^1.10.0",
"lodash": "^4.17.21",
"nanoevents": "^9.0.0",
"pretty-ms": "^8.0.0",
Expand Down
25 changes: 16 additions & 9 deletions apps/passport-client/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { LocalStorageNotAccessibleScreen } from "../components/screens/LocalStor
import { MissingScreen } from "../components/screens/MissingScreen";
import { NoWASMScreen } from "../components/screens/NoWASMScreen";
// import { RemoveEmailScreen } from "../components/screens/RemoveEmailScreen";
import * as localForage from "localforage";
import styled from "styled-components";
import { ProveScreen } from "../components/screens/ProveScreen/ProveScreen";
import { PodboxScannedTicketScreen } from "../components/screens/ScannedTicketScreens/PodboxScannedTicketScreen/PodboxScannedTicketScreen";
Expand Down Expand Up @@ -87,13 +88,15 @@ if (typeof window !== "undefined") {
const params = new URLSearchParams(window.location.search);
if (params.has("forceNewSession")) {
localStorage.clear();
const newParams = new URLSearchParams(window.location.search);
newParams.delete("forceNewSession");
const newSearch = newParams.toString();
const newPath = `${window.location.pathname}${
newSearch ? `?${newSearch}` : ""
}${window.location.hash}`;
window.location.replace(newPath);
localForage.clear().then(() => {
const newParams = new URLSearchParams(window.location.search);
newParams.delete("forceNewSession");
const newSearch = newParams.toString();
const newPath = `${window.location.pathname}${
newSearch ? `?${newSearch}` : ""
}${window.location.hash}`;
window.location.replace(newPath);
});
}
}

Expand Down Expand Up @@ -301,7 +304,9 @@ const AppStateProvider: React.FC<AppStateProviderProps> = ({

const update = useCallback(
(diff: Partial<AppState>): void => {
setState(Object.assign(state, diff));
if (Object.keys(diff).length > 0) {
setState(Object.assign(state, diff));
}

// In a React class component, the `setState` method has a second
// parameter, which is a callback function that React will invoke when
Expand All @@ -324,7 +329,9 @@ const AppStateProvider: React.FC<AppStateProviderProps> = ({
// object directly. It will then emit an event, which is what the rest of
// the app uses to work around the fact that it also can't track changes
// to the state object.
setLastDiff(diff);
if (Object.keys(diff).length > 0) {
setLastDiff(diff);
}
},
[state]
);
Expand Down
3 changes: 2 additions & 1 deletion apps/passport-client/src/appHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,8 @@ export function useHasSetupPassword(): boolean {
export function useLaserScannerKeystrokeInput(): string {
const [typedText, setTypedText] = useState("");
const nav = useNavigate();
const usingLaserScanner = loadUsingLaserScanner();
const [usingLaserScanner, setUsingLaserScanner] = useState(false);
loadUsingLaserScanner().then((value) => setUsingLaserScanner(value));

useEffect(() => {
function handleKeyDown(event: KeyboardEvent): void {
Expand Down
11 changes: 6 additions & 5 deletions apps/passport-client/src/backgroundJobs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,9 @@ export function useBackgroundJobs(): void {
};

setupBroadcastChannel(dispatch);
setupUsingLaserScanning();
startBackgroundJobs();
setupUsingLaserScanning().then(() => {
startBackgroundJobs();
});

return () => {
closeBroadcastChannel();
Expand All @@ -143,13 +144,13 @@ export function useBackgroundJobs(): void {
* on the scan screen so the laser scanner can be used. This flag will be
* exclusively used on the Devconnect laser scanning devices.
*/
function setupUsingLaserScanning(): void {
async function setupUsingLaserScanning(): Promise<void> {
const queryParams = new URLSearchParams(window.location.search.slice(1));
const laserQueryParam = queryParams.get("laser");
if (laserQueryParam === "true") {
saveUsingLaserScanner(true);
await saveUsingLaserScanner(true);
} else if (laserQueryParam === "false") {
// We may want to use this to forcibly make this state false
saveUsingLaserScanner(false);
await saveUsingLaserScanner(false);
}
}
34 changes: 18 additions & 16 deletions apps/passport-client/src/dispatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
} from "@pcd/semaphore-identity-pcd";
import { assertUnreachable, sleep } from "@pcd/util";
import { Identity } from "@semaphore-protocol/identity";
import * as localForage from "localforage";
import _ from "lodash";
import { createContext } from "react";
import { appConfig } from "./appConfig";
Expand Down Expand Up @@ -417,7 +418,7 @@ async function oneClickLogin(

const crypto = await PCDCrypto.newInstance();
const encryptionKey = crypto.generateRandomKey();
saveEncryptionKey(encryptionKey);
await saveEncryptionKey(encryptionKey);

update({
encryptionKey
Expand Down Expand Up @@ -445,7 +446,7 @@ async function oneClickLogin(

// User has encryption key
if (oneClickLoginResult.value.encryptionKey) {
saveEncryptionKey(oneClickLoginResult.value.encryptionKey);
await saveEncryptionKey(oneClickLoginResult.value.encryptionKey);
update({
encryptionKey: oneClickLoginResult.value.encryptionKey
});
Expand Down Expand Up @@ -514,7 +515,7 @@ async function createNewUserSkipPassword(

const crypto = await PCDCrypto.newInstance();
const encryptionKey = crypto.generateRandomKey();
saveEncryptionKey(encryptionKey);
await saveEncryptionKey(encryptionKey);

update({
encryptionKey
Expand Down Expand Up @@ -560,7 +561,7 @@ async function createNewUserWithPassword(
const { salt: newSalt, key: encryptionKey } =
crypto.generateSaltAndEncryptionKey(password);

saveEncryptionKey(encryptionKey);
await saveEncryptionKey(encryptionKey);

update({
encryptionKey
Expand Down Expand Up @@ -732,7 +733,7 @@ async function setSelf(
return;
}

saveSelf(self); // Save to local storage.
await saveSelf(self); // Save to local storage.
update({ self }); // Update in-memory state.
}

Expand All @@ -754,6 +755,7 @@ async function resetPassport(
commitment: state.self?.commitment
});
// Clear saved state.
await localForage.clear();
window.localStorage.clear();
// Clear in-memory state
update({
Expand Down Expand Up @@ -907,13 +909,13 @@ async function loadAfterLogin(
console.log(`[SYNC] saving state at login: revision ${storage.revision}`);
await savePCDs(pcds);
await saveSubscriptions(subscriptions);
savePersistentSyncStatus({
await savePersistentSyncStatus({
serverStorageRevision: storage.revision,
serverStorageHash: storageHash
});
saveEncryptionKey(encryptionKey);
saveSelf(self);
saveIdentity(identityPCD.claim.identityV3);
await saveEncryptionKey(encryptionKey);
await saveSelf(self);
await saveIdentity(identityPCD.claim.identityV3);

update({
encryptionKey,
Expand All @@ -939,8 +941,8 @@ async function loadAfterLogin(

// Update `self` and `encryptionKey` in-memory fields from their saved values in localStorage
async function handlePasswordChangeOnOtherTab(update: ZuUpdate): Promise<void> {
const self = loadSelf();
const encryptionKey = loadEncryptionKey();
const self = await loadSelf();
const encryptionKey = await loadEncryptionKey();
return update({
self,
encryptionKey,
Expand All @@ -961,8 +963,8 @@ async function saveNewPasswordAndBroadcast(
): Promise<void> {
if (state.self) {
const newSelf = { ...state.self, salt: newSalt };
saveSelf(newSelf);
saveEncryptionKey(newEncryptionKey);
await saveSelf(newSelf);
await saveEncryptionKey(newEncryptionKey);
notifyPasswordChangeToOtherTabs();
update({
encryptionKey: newEncryptionKey,
Expand Down Expand Up @@ -1061,7 +1063,7 @@ async function doSync(
console.log("[SYNC] no user available to sync");
return undefined;
}
if (!loadEncryptionKey()) {
if (!(await loadEncryptionKey())) {
console.log("[SYNC] no encryption key, can't sync");
return undefined;
}
Expand Down Expand Up @@ -1415,7 +1417,7 @@ async function handleAgreedPrivacyNotice(
version: number
): Promise<void> {
if (state.self) {
saveSelf({ ...state.self, terms_agreed: version });
await saveSelf({ ...state.self, terms_agreed: version });
window.location.hash = "#/";
}
}
Expand All @@ -1427,7 +1429,7 @@ async function handleAgreedPrivacyNotice(
* un-dismissable modal.
*/
async function promptToAgreePrivacyNotice(state: AppState): Promise<void> {
const cachedTerms = loadPrivacyNoticeAgreed();
const cachedTerms = await loadPrivacyNoticeAgreed();
if (cachedTerms === LATEST_PRIVACY_NOTICE) {
// sync to server
await agreeTerms(
Expand Down
12 changes: 6 additions & 6 deletions apps/passport-client/src/loadInitialState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,26 @@ import { AppState } from "./state";
import { validateAndLogInitialAppState } from "./validateState";

export async function loadInitialState(): Promise<AppState> {
let identityV3 = loadIdentity();
let identityV3 = await loadIdentity();

if (!identityV3) {
console.log("Generating a new Semaphore identity...");
identityV3 = new Identity();
saveIdentity(identityV3);
await saveIdentity(identityV3);
}

const self = loadSelf();
const self = await loadSelf();

const pcds = await loadPCDs(self);

const encryptionKey = loadEncryptionKey();
const encryptionKey = await loadEncryptionKey();
const subscriptions = await loadSubscriptions();

const modal = { modalType: "none" } as AppState["modal"];

const credentialCache = createStorageBackedCredentialCache();

const persistentSyncStatus = loadPersistentSyncStatus();
const persistentSyncStatus = await loadPersistentSyncStatus();

const state: AppState = {
self,
Expand Down Expand Up @@ -100,7 +100,7 @@ export async function loadInitialState(): Promise<AppState> {

if (newSelfResponse.success) {
state.self = newSelfResponse.value;
saveSelf(newSelfResponse.value);
await saveSelf(newSelfResponse.value);
} else {
// proceed to the next step anyway, since we don't have any other option
}
Expand Down
Loading

0 comments on commit e2d3125

Please sign in to comment.