diff --git a/index.js b/index.js index cc358ae..8a78445 100644 --- a/index.js +++ b/index.js @@ -20,6 +20,7 @@ import onMessageReceived from "~/notifications/onMessageReceived"; import { createLogger } from "~/lib/logger"; import * as Sentry from "@sentry/react-native"; import AsyncStorage from "@react-native-async-storage/async-storage"; +import { STORAGE_KEYS } from "~/storage/storageKeys"; // setup notification, this have to stay in index.js notifee.onBackgroundEvent(notificationBackgroundEvent); @@ -31,14 +32,16 @@ messaging().setBackgroundMessageHandler(onMessageReceived); registerRootComponent(App); // Constants for persistence -const LAST_SYNC_TIME_KEY = "@geolocation_last_sync_time"; // const FORCE_SYNC_INTERVAL = 24 * 60 * 60 * 1000; -const FORCE_SYNC_INTERVAL = 60 * 60 * 1000; // DEBUGGING +// const FORCE_SYNC_INTERVAL = 60 * 60 * 1000; // DEBUGGING +const FORCE_SYNC_INTERVAL = 5 * 60 * 1000; // DEBUGGING // Helper functions for persisting sync time const getLastSyncTime = async () => { try { - const value = await AsyncStorage.getItem(LAST_SYNC_TIME_KEY); + const value = await AsyncStorage.getItem( + STORAGE_KEYS.GEOLOCATION_LAST_SYNC_TIME, + ); return value ? parseInt(value, 10) : Date.now(); } catch (error) { Sentry.captureException(error, { @@ -50,7 +53,10 @@ const getLastSyncTime = async () => { const setLastSyncTime = async (time) => { try { - await AsyncStorage.setItem(LAST_SYNC_TIME_KEY, time.toString()); + await AsyncStorage.setItem( + STORAGE_KEYS.GEOLOCATION_LAST_SYNC_TIME, + time.toString(), + ); } catch (error) { Sentry.captureException(error, { tags: { module: "headless-task", operation: "set-last-sync-time" }, diff --git a/src/app/index.js b/src/app/index.js index d3fc231..8b2f401 100644 --- a/src/app/index.js +++ b/src/app/index.js @@ -7,8 +7,8 @@ import { createLogger } from "~/lib/logger"; import { SYSTEM_SCOPES } from "~/lib/logger/scopes"; import { authActions, permissionWizardActions } from "~/stores"; -import { secureStore } from "~/lib/memorySecureStore"; -import memoryAsyncStorage from "~/lib/memoryAsyncStorage"; +import { secureStore } from "~/storage/memorySecureStore"; +import memoryAsyncStorage from "~/storage/memoryAsyncStorage"; import "~/lib/mapbox"; import "~/i18n"; diff --git a/src/auth/deviceUuid.js b/src/auth/deviceUuid.js index bc41e2e..997feca 100644 --- a/src/auth/deviceUuid.js +++ b/src/auth/deviceUuid.js @@ -1,4 +1,5 @@ -import { secureStore } from "~/lib/memorySecureStore"; +import { secureStore } from "~/storage/memorySecureStore"; +import { STORAGE_KEYS } from "~/storage/storageKeys"; import uuidGenerator from "react-native-uuid"; import { createLogger } from "~/lib/logger"; import { FEATURE_SCOPES } from "~/lib/logger/scopes"; @@ -21,12 +22,12 @@ async function getDeviceUuid() { // Create a new promise for this generation attempt uuidGenerationPromise = (async () => { try { - let deviceUuid = await secureStore.getItemAsync("deviceUuid"); + let deviceUuid = await secureStore.getItemAsync(STORAGE_KEYS.DEVICE_UUID); if (!deviceUuid) { deviceLogger.info("No device UUID found, generating new one"); deviceUuid = uuidGenerator.v4(); - await secureStore.setItemAsync("deviceUuid", deviceUuid); + await secureStore.setItemAsync(STORAGE_KEYS.DEVICE_UUID, deviceUuid); deviceLogger.info("New device UUID generated and stored", { uuid: deviceUuid.substring(0, 8) + "...", }); diff --git a/src/components/EULA/index.js b/src/components/EULA/index.js index 3f26267..0a7869f 100644 --- a/src/components/EULA/index.js +++ b/src/components/EULA/index.js @@ -1,6 +1,7 @@ import React from "react"; import { View, ScrollView, StyleSheet, Platform } from "react-native"; -import AsyncStorage from "~/lib/memoryAsyncStorage"; +import AsyncStorage from "~/storage/memoryAsyncStorage"; +import { STORAGE_KEYS } from "~/storage/storageKeys"; import Text from "../Text"; @@ -64,14 +65,12 @@ Ce Contrat constitue l'intégralité de l'accord entre vous et nous concernant l Si vous avez des questions concernant ce Contrat, veuillez nous contacter à : Email : contact@alertesecours.fr`; -const EULA_STORAGE_KEY = "@eula_accepted"; - const EULA = ({ onAccept, visible = true }) => { if (!visible || Platform.OS !== "ios") return null; const handleAccept = async () => { try { - await AsyncStorage.setItem(EULA_STORAGE_KEY, "true"); + await AsyncStorage.setItem(STORAGE_KEYS.EULA_ACCEPTED, "true"); onAccept(); } catch (error) { console.error("Error saving EULA acceptance:", error); diff --git a/src/containers/AppLifecycleListener.js b/src/containers/AppLifecycleListener.js index 88bd55b..5c86e7e 100644 --- a/src/containers/AppLifecycleListener.js +++ b/src/containers/AppLifecycleListener.js @@ -11,8 +11,8 @@ import { usePermissionWizardState, useNetworkState, } from "~/stores"; -import { secureStore } from "~/lib/memorySecureStore"; -import memoryAsyncStorage from "~/lib/memoryAsyncStorage"; +import { secureStore } from "~/storage/memorySecureStore"; +import memoryAsyncStorage from "~/storage/memoryAsyncStorage"; import requestPermissionLocationBackground from "~/permissions/requestPermissionLocationBackground"; import requestPermissionLocationForeground from "~/permissions/requestPermissionLocationForeground"; diff --git a/src/env.js b/src/env.js index 3e3ea2c..e894b10 100644 --- a/src/env.js +++ b/src/env.js @@ -1,8 +1,6 @@ import { Platform } from "react-native"; -import { secureStore } from "~/lib/secureStore"; - -// Key for storing staging setting in secureStore -const STAGING_SETTING_KEY = "env.isStaging"; +import { secureStore } from "~/storage/memorySecureStore"; +import { STORAGE_KEYS } from "~/storage/storageKeys"; // Logging configuration const LOG_SCOPES = process.env.APP_LOG_SCOPES; @@ -97,7 +95,7 @@ export const setStaging = async (enabled) => { } // Persist the staging setting - await secureStore.setItemAsync(STAGING_SETTING_KEY, String(enabled)); + await secureStore.setItemAsync(STORAGE_KEYS.ENV_IS_STAGING, String(enabled)); }; // Initialize with default values @@ -106,7 +104,9 @@ const env = { ...envMap }; // Load the staging setting from secureStore export const initializeEnv = async () => { try { - const storedStaging = await secureStore.getItemAsync(STAGING_SETTING_KEY); + const storedStaging = await secureStore.getItemAsync( + STORAGE_KEYS.ENV_IS_STAGING, + ); if (storedStaging !== null) { const isStaging = storedStaging === "true"; if (isStaging) { diff --git a/src/hooks/useEULA.js b/src/hooks/useEULA.js index ae38107..f4d1051 100644 --- a/src/hooks/useEULA.js +++ b/src/hooks/useEULA.js @@ -1,9 +1,8 @@ import { useState, useEffect } from "react"; -import AsyncStorage from "~/lib/memoryAsyncStorage"; +import AsyncStorage from "~/storage/memoryAsyncStorage"; +import { STORAGE_KEYS } from "~/storage/storageKeys"; import { Platform } from "react-native"; -const EULA_STORAGE_KEY = "@eula_accepted"; - export const useEULA = () => { const [eulaAccepted, setEulaAccepted] = useState(true); const [loading, setLoading] = useState(true); @@ -16,7 +15,7 @@ export const useEULA = () => { const checkEULA = async () => { try { - const accepted = await AsyncStorage.getItem(EULA_STORAGE_KEY); + const accepted = await AsyncStorage.getItem(STORAGE_KEYS.EULA_ACCEPTED); setEulaAccepted(!!accepted); } catch (error) { console.error("Error checking EULA status:", error); diff --git a/src/location/emulatorService.js b/src/location/emulatorService.js index f24fbf7..4789231 100644 --- a/src/location/emulatorService.js +++ b/src/location/emulatorService.js @@ -1,10 +1,9 @@ import BackgroundGeolocation from "react-native-background-geolocation"; -import AsyncStorage from "~/lib/memoryAsyncStorage"; +import AsyncStorage from "~/storage/memoryAsyncStorage"; +import { STORAGE_KEYS } from "~/storage/storageKeys"; import { createLogger } from "~/lib/logger"; import { BACKGROUND_SCOPES } from "~/lib/logger/scopes"; -const EMULATOR_MODE_KEY = "emulator_mode_enabled"; - // Global variables let emulatorIntervalId = null; let isEmulatorModeEnabled = false; @@ -18,7 +17,9 @@ const emulatorLogger = createLogger({ // Initialize emulator mode based on stored preference export const initEmulatorMode = async () => { try { - const storedValue = await AsyncStorage.getItem(EMULATOR_MODE_KEY); + const storedValue = await AsyncStorage.getItem( + STORAGE_KEYS.EMULATOR_MODE_ENABLED, + ); emulatorLogger.debug("Initializing emulator mode", { storedValue }); if (storedValue === "true") { @@ -58,7 +59,7 @@ export const enableEmulatorMode = async () => { isEmulatorModeEnabled = true; // Persist the setting - await AsyncStorage.setItem(EMULATOR_MODE_KEY, "true"); + await AsyncStorage.setItem(STORAGE_KEYS.EMULATOR_MODE_ENABLED, "true"); emulatorLogger.debug("Emulator mode setting saved"); } catch (error) { emulatorLogger.error("Failed to enable emulator mode", { @@ -81,7 +82,7 @@ export const disableEmulatorMode = async () => { // Persist the setting try { - await AsyncStorage.setItem(EMULATOR_MODE_KEY, "false"); + await AsyncStorage.setItem(STORAGE_KEYS.EMULATOR_MODE_ENABLED, "false"); emulatorLogger.debug("Emulator mode setting saved"); } catch (error) { emulatorLogger.error("Failed to save emulator mode setting", { diff --git a/src/lib/memoryAsyncStorage.js b/src/storage/memoryAsyncStorage.js similarity index 95% rename from src/lib/memoryAsyncStorage.js rename to src/storage/memoryAsyncStorage.js index 09f3530..984c393 100644 --- a/src/lib/memoryAsyncStorage.js +++ b/src/storage/memoryAsyncStorage.js @@ -1,6 +1,7 @@ import AsyncStorage from "@react-native-async-storage/async-storage"; import { createLogger } from "~/lib/logger"; import { SYSTEM_SCOPES } from "~/lib/logger/scopes"; +import { getAsyncStorageKeys } from "./storageKeys"; const storageLogger = createLogger({ module: SYSTEM_SCOPES.STORAGE, @@ -29,17 +30,8 @@ export const memoryAsyncStorage = { storageLogger.info("Initializing memory async storage"); - // List of known keys that need to be cached - const knownKeys = [ - "@geolocation_last_sync_time", - "@eula_accepted", - "@override_messages", - "@permission_wizard_completed", - "lastUpdateCheckTime", - "@last_known_location", - "eula_accepted", - "emulator_mode_enabled", - ]; + // Get all registered AsyncStorage keys from the registry + const knownKeys = getAsyncStorageKeys(); // Load all known keys into memory for (const key of knownKeys) { diff --git a/src/lib/memorySecureStore.js b/src/storage/memorySecureStore.js similarity index 94% rename from src/lib/memorySecureStore.js rename to src/storage/memorySecureStore.js index ee278e9..c39941b 100644 --- a/src/lib/memorySecureStore.js +++ b/src/storage/memorySecureStore.js @@ -1,6 +1,7 @@ import { secureStore as originalSecureStore } from "./secureStore"; import { createLogger } from "~/lib/logger"; import { SYSTEM_SCOPES } from "~/lib/logger/scopes"; +import { getSecureStoreKeys } from "./storageKeys"; const storageLogger = createLogger({ module: SYSTEM_SCOPES.STORAGE, @@ -29,18 +30,8 @@ export const memorySecureStore = { storageLogger.info("Initializing memory secure store"); - // List of known keys that need to be cached - const knownKeys = [ - "deviceUuid", - "authToken", - "userToken", - "dev.authToken", - "dev.userToken", - "anon.authToken", - "anon.userToken", - "fcmTokenStored", - "fcmTokenStoredDeviceId", - ]; + // Get all registered secure store keys from the registry + const knownKeys = getSecureStoreKeys(); // Load all known keys into memory for (const key of knownKeys) { diff --git a/src/lib/secureStore.js b/src/storage/secureStore.js similarity index 100% rename from src/lib/secureStore.js rename to src/storage/secureStore.js diff --git a/src/storage/storageKeys.js b/src/storage/storageKeys.js new file mode 100644 index 0000000..f616faa --- /dev/null +++ b/src/storage/storageKeys.js @@ -0,0 +1,83 @@ +/** + * Storage Keys Registry + * + * This file maintains a registry of all storage keys used throughout the application. + * By defining keys as constants here, they are automatically included in memory storage + * initialization, eliminating the need for manual maintenance of key lists. + */ + +const secureStoreKeys = new Set(); +const asyncStorageKeys = new Set(); + +/** + * Register a secure store key and return it as a constant + * @param {string} key - The storage key to register for secure store + * @returns {string} The same key, now registered for secure store + */ +export const registerSecureStoreKey = (key) => { + secureStoreKeys.add(key); + return key; +}; + +/** + * Register an AsyncStorage key and return it as a constant + * @param {string} key - The storage key to register for AsyncStorage + * @returns {string} The same key, now registered for AsyncStorage + */ +export const registerAsyncStorageKey = (key) => { + asyncStorageKeys.add(key); + return key; +}; + +/** + * Get all secure store keys + * @returns {string[]} Array of secure store keys + */ +export const getSecureStoreKeys = () => Array.from(secureStoreKeys); + +/** + * Get all AsyncStorage keys + * @returns {string[]} Array of AsyncStorage keys + */ +export const getAsyncStorageKeys = () => Array.from(asyncStorageKeys); + +/** + * Get all registered storage keys (both types) + * @returns {string[]} Array of all registered keys + */ +export const getAllRegisteredKeys = () => [ + ...Array.from(secureStoreKeys), + ...Array.from(asyncStorageKeys), +]; + +/** + * Storage key constants + * All storage keys used throughout the application should be defined here. + */ +export const STORAGE_KEYS = { + // Secure Store Keys - Authentication & Security + DEVICE_UUID: registerSecureStoreKey("deviceUuid"), + AUTH_TOKEN: registerSecureStoreKey("authToken"), + USER_TOKEN: registerSecureStoreKey("userToken"), + DEV_AUTH_TOKEN: registerSecureStoreKey("dev.authToken"), + DEV_USER_TOKEN: registerSecureStoreKey("dev.userToken"), + ANON_AUTH_TOKEN: registerSecureStoreKey("anon.authToken"), + ANON_USER_TOKEN: registerSecureStoreKey("anon.userToken"), + FCM_TOKEN_STORED: registerSecureStoreKey("fcmTokenStored"), + FCM_TOKEN_STORED_DEVICE_ID: registerSecureStoreKey("fcmTokenStoredDeviceId"), + ENV_IS_STAGING: registerSecureStoreKey("env.isStaging"), + + // AsyncStorage Keys - App State & Preferences + GEOLOCATION_LAST_SYNC_TIME: registerAsyncStorageKey( + "@geolocation_last_sync_time", + ), + EULA_ACCEPTED: registerAsyncStorageKey("@eula_accepted"), + OVERRIDE_MESSAGES: registerAsyncStorageKey("@override_messages"), + PERMISSION_WIZARD_COMPLETED: registerAsyncStorageKey( + "@permission_wizard_completed", + ), + LAST_UPDATE_CHECK_TIME: registerAsyncStorageKey("lastUpdateCheckTime"), + LAST_KNOWN_LOCATION: registerAsyncStorageKey("@last_known_location"), + EULA_ACCEPTED_SIMPLE: registerAsyncStorageKey("eula_accepted"), + EMULATOR_MODE_ENABLED: registerAsyncStorageKey("emulator_mode_enabled"), +}; diff --git a/src/stores/aggregatedMessages.js b/src/stores/aggregatedMessages.js index 1bea507..a63be0c 100644 --- a/src/stores/aggregatedMessages.js +++ b/src/stores/aggregatedMessages.js @@ -1,8 +1,7 @@ import { createAtom } from "~/lib/atomic-zustand"; import debounce from "lodash.debounce"; -import AsyncStorage from "~/lib/memoryAsyncStorage"; - -const OVERRIDE_MESSAGES_STORAGE_KEY = "@override_messages"; +import AsyncStorage from "~/storage/memoryAsyncStorage"; +import { STORAGE_KEYS } from "~/storage/storageKeys"; export default createAtom(({ merge, set, get, reset }) => { const overrideMessagesCache = {}; @@ -10,7 +9,7 @@ export default createAtom(({ merge, set, get, reset }) => { const initCache = async () => { try { const storedData = await AsyncStorage.getItem( - OVERRIDE_MESSAGES_STORAGE_KEY, + STORAGE_KEYS.OVERRIDE_MESSAGES, ); const storedMessages = storedData ? JSON.parse(storedData) : {}; Object.entries(storedMessages).forEach(([messageId, data]) => { @@ -24,7 +23,7 @@ export default createAtom(({ merge, set, get, reset }) => { const saveOverrideMessagesToStorage = async () => { try { await AsyncStorage.setItem( - OVERRIDE_MESSAGES_STORAGE_KEY, + STORAGE_KEYS.OVERRIDE_MESSAGES, JSON.stringify(overrideMessagesCache), ); } catch (error) { diff --git a/src/stores/auth.js b/src/stores/auth.js index 4a0e602..1739ac2 100644 --- a/src/stores/auth.js +++ b/src/stores/auth.js @@ -1,4 +1,5 @@ -import { secureStore } from "~/lib/memorySecureStore"; +import { secureStore } from "~/storage/memorySecureStore"; +import { STORAGE_KEYS } from "~/storage/storageKeys"; import jwtDecode from "jwt-decode"; import { createLogger } from "~/lib/logger"; import { FEATURE_SCOPES } from "~/lib/logger/scopes"; @@ -10,13 +11,13 @@ import isExpired from "~/lib/time/isExpired"; import { registerUser, loginUserToken } from "~/auth/actions"; // DEV -// SecureStore.deleteItemAsync("userToken"); -// SecureStore.deleteItemAsync("authToken"); -// SecureStore.deleteItemAsync("dev.userToken"); -// SecureStore.deleteItemAsync("dev.authToken"); -// SecureStore.deleteItemAsync("anon.userToken"); -// SecureStore.deleteItemAsync("anon.authToken"); -// SecureStore.getItemAsync("userToken").then((t) => authLogger.debug("User token", { token: t })); +// SecureStore.deleteItemAsync(STORAGE_KEYS.USER_TOKEN); +// SecureStore.deleteItemAsync(STORAGE_KEYS.AUTH_TOKEN); +// SecureStore.deleteItemAsync(STORAGE_KEYS.DEV_USER_TOKEN); +// SecureStore.deleteItemAsync(STORAGE_KEYS.DEV_AUTH_TOKEN); +// SecureStore.deleteItemAsync(STORAGE_KEYS.ANON_USER_TOKEN); +// SecureStore.deleteItemAsync(STORAGE_KEYS.ANON_AUTH_TOKEN); +// SecureStore.getItemAsync(STORAGE_KEYS.USER_TOKEN).then((t) => authLogger.debug("User token", { token: t })); const authLogger = createLogger({ module: FEATURE_SCOPES.AUTH, @@ -68,7 +69,7 @@ export default createAtom(({ get, merge, getActions }) => { authLogger.info("Attempting to login with auth token"); const { userToken } = await loginUserToken({ authToken }); authLogger.info("Successfully obtained user token"); - await secureStore.setItemAsync("userToken", userToken); + await secureStore.setItemAsync(STORAGE_KEYS.USER_TOKEN, userToken); endLoading({ userToken, }); @@ -81,8 +82,8 @@ export default createAtom(({ get, merge, getActions }) => { "Auth token expired, clearing tokens and reinitializing", ); await Promise.all([ - secureStore.deleteItemAsync("authToken"), - secureStore.deleteItemAsync("userToken"), + secureStore.deleteItemAsync(STORAGE_KEYS.AUTH_TOKEN), + secureStore.deleteItemAsync(STORAGE_KEYS.USER_TOKEN), ]); return init(); } @@ -93,8 +94,8 @@ export default createAtom(({ get, merge, getActions }) => { const init = async () => { authLogger.debug("Initializing auth state"); let { userToken, authToken } = await promiseObject({ - userToken: secureStore.getItemAsync("userToken"), - authToken: secureStore.getItemAsync("authToken"), + userToken: secureStore.getItemAsync(STORAGE_KEYS.USER_TOKEN), + authToken: secureStore.getItemAsync(STORAGE_KEYS.AUTH_TOKEN), }); // await delay(5); // authLogger.debug("Auth tokens", { userToken, authToken }); @@ -121,7 +122,7 @@ export default createAtom(({ get, merge, getActions }) => { const res = await registerUser(); authLogger.info("Successfully registered new user"); authToken = res.authToken; - await secureStore.setItemAsync("authToken", authToken); + await secureStore.setItemAsync(STORAGE_KEYS.AUTH_TOKEN, authToken); } if (!userToken && authToken) { @@ -165,7 +166,7 @@ export default createAtom(({ get, merge, getActions }) => { startLoading(); authLogger.debug("Deleting userToken for refresh"); - await secureStore.deleteItemAsync("userToken"); + await secureStore.deleteItemAsync(STORAGE_KEYS.USER_TOKEN); await init(); return true; @@ -183,7 +184,7 @@ export default createAtom(({ get, merge, getActions }) => { const { onReloadAuthToken: authToken } = get(); if (authToken) { - await secureStore.setItemAsync("authToken", authToken); + await secureStore.setItemAsync(STORAGE_KEYS.AUTH_TOKEN, authToken); await loadUserJWT(authToken); } else { await init(); @@ -204,12 +205,12 @@ export default createAtom(({ get, merge, getActions }) => { if (!isConnected) { // backup anon tokens const [anonAuthToken, anonUserToken] = await Promise.all([ - secureStore.getItemAsync("authToken"), - secureStore.getItemAsync("userToken"), + secureStore.getItemAsync(STORAGE_KEYS.AUTH_TOKEN), + secureStore.getItemAsync(STORAGE_KEYS.USER_TOKEN), ]); await Promise.all([ - secureStore.setItemAsync("anon.authToken", anonAuthToken), - secureStore.setItemAsync("anon.userToken", anonUserToken), + secureStore.setItemAsync(STORAGE_KEYS.ANON_AUTH_TOKEN, anonAuthToken), + secureStore.setItemAsync(STORAGE_KEYS.ANON_USER_TOKEN, anonUserToken), ]); } merge({ onReloadAuthToken: authTokenJwt }); @@ -219,12 +220,12 @@ export default createAtom(({ get, merge, getActions }) => { const impersonate = async ({ authTokenJwt }) => { authLogger.info("Starting impersonation"); const [anonAuthToken, anonUserToken] = await Promise.all([ - secureStore.getItemAsync("authToken"), - secureStore.getItemAsync("userToken"), + secureStore.getItemAsync(STORAGE_KEYS.AUTH_TOKEN), + secureStore.getItemAsync(STORAGE_KEYS.USER_TOKEN), ]); await Promise.all([ - secureStore.setItemAsync("dev.authToken", anonAuthToken), - secureStore.setItemAsync("dev.userToken", anonUserToken), + secureStore.setItemAsync(STORAGE_KEYS.DEV_AUTH_TOKEN, anonAuthToken), + secureStore.setItemAsync(STORAGE_KEYS.DEV_USER_TOKEN, anonUserToken), ]); merge({ onReloadAuthToken: authTokenJwt }); triggerReload(); @@ -234,29 +235,29 @@ export default createAtom(({ get, merge, getActions }) => { authLogger.info("Initiating logout"); const [devAuthToken, devUserToken, anonAuthToken, anonUserToken] = await Promise.all([ - secureStore.getItemAsync("dev.authToken"), - secureStore.getItemAsync("dev.userToken"), - secureStore.getItemAsync("anon.authToken"), - secureStore.getItemAsync("anon.userToken"), + secureStore.getItemAsync(STORAGE_KEYS.DEV_AUTH_TOKEN), + secureStore.getItemAsync(STORAGE_KEYS.DEV_USER_TOKEN), + secureStore.getItemAsync(STORAGE_KEYS.ANON_AUTH_TOKEN), + secureStore.getItemAsync(STORAGE_KEYS.ANON_USER_TOKEN), ]); if (devAuthToken && devUserToken) { await Promise.all([ - secureStore.setItemAsync("authToken", devAuthToken), - secureStore.setItemAsync("userToken", devUserToken), - secureStore.deleteItemAsync("dev.authToken"), - secureStore.deleteItemAsync("dev.userToken"), + secureStore.setItemAsync(STORAGE_KEYS.AUTH_TOKEN, devAuthToken), + secureStore.setItemAsync(STORAGE_KEYS.USER_TOKEN, devUserToken), + secureStore.deleteItemAsync(STORAGE_KEYS.DEV_AUTH_TOKEN), + secureStore.deleteItemAsync(STORAGE_KEYS.DEV_USER_TOKEN), ]); } else if (anonAuthToken && anonUserToken) { await Promise.all([ - secureStore.setItemAsync("authToken", anonAuthToken), - secureStore.setItemAsync("userToken", anonUserToken), - secureStore.deleteItemAsync("anon.authToken"), - secureStore.deleteItemAsync("anon.userToken"), + secureStore.setItemAsync(STORAGE_KEYS.AUTH_TOKEN, anonAuthToken), + secureStore.setItemAsync(STORAGE_KEYS.USER_TOKEN, anonUserToken), + secureStore.deleteItemAsync(STORAGE_KEYS.ANON_AUTH_TOKEN), + secureStore.deleteItemAsync(STORAGE_KEYS.ANON_USER_TOKEN), ]); } else { await Promise.all([ - secureStore.deleteItemAsync("authToken"), - secureStore.deleteItemAsync("userToken"), + secureStore.deleteItemAsync(STORAGE_KEYS.AUTH_TOKEN), + secureStore.deleteItemAsync(STORAGE_KEYS.USER_TOKEN), ]); merge({ userOffMode: true, @@ -282,7 +283,7 @@ export default createAtom(({ get, merge, getActions }) => { try { // Update secure storage - await secureStore.setItemAsync("userToken", userToken); + await secureStore.setItemAsync(STORAGE_KEYS.USER_TOKEN, userToken); // Update in-memory state merge({ userToken }); diff --git a/src/stores/fcm.js b/src/stores/fcm.js index eb57e31..1283dcb 100644 --- a/src/stores/fcm.js +++ b/src/stores/fcm.js @@ -1,5 +1,6 @@ import { createAtom } from "~/lib/atomic-zustand"; -import { secureStore } from "~/lib/secureStore"; +import { secureStore } from "~/storage/memorySecureStore"; +import { STORAGE_KEYS } from "~/storage/storageKeys"; export default createAtom(({ merge, reset }) => { const setFcmToken = (token) => { @@ -9,8 +10,11 @@ export default createAtom(({ merge, reset }) => { }; const setFcmTokenStored = ({ fcmToken, deviceId }) => { - secureStore.setItemAsync("fcmTokenStored", fcmToken); - secureStore.setItemAsync("fcmTokenStoredDeviceId", deviceId.toString()); + secureStore.setItemAsync(STORAGE_KEYS.FCM_TOKEN_STORED, fcmToken); + secureStore.setItemAsync( + STORAGE_KEYS.FCM_TOKEN_STORED_DEVICE_ID, + deviceId.toString(), + ); merge({ fcmTokenStored: fcmToken, deviceId, @@ -18,9 +22,11 @@ export default createAtom(({ merge, reset }) => { }; const init = async () => { - const fcmTokenStored = await secureStore.getItemAsync("fcmTokenStored"); + const fcmTokenStored = await secureStore.getItemAsync( + STORAGE_KEYS.FCM_TOKEN_STORED, + ); const fcmTokenStoredDeviceId = await secureStore.getItemAsync( - "fcmTokenStoredDeviceId", + STORAGE_KEYS.FCM_TOKEN_STORED_DEVICE_ID, ); const deviceId = fcmTokenStoredDeviceId ? parseInt(fcmTokenStoredDeviceId, 10) diff --git a/src/stores/permissionWizard.js b/src/stores/permissionWizard.js index 5f73773..b9199f3 100644 --- a/src/stores/permissionWizard.js +++ b/src/stores/permissionWizard.js @@ -1,12 +1,13 @@ import { createAtom } from "~/lib/atomic-zustand"; -import AsyncStorage from "~/lib/memoryAsyncStorage"; - -const WIZARD_COMPLETED_KEY = "@permission_wizard_completed"; +import AsyncStorage from "~/storage/memoryAsyncStorage"; +import { STORAGE_KEYS } from "~/storage/storageKeys"; export default createAtom(({ set, get }) => { const init = async () => { try { - const wizardCompleted = await AsyncStorage.getItem(WIZARD_COMPLETED_KEY); + const wizardCompleted = await AsyncStorage.getItem( + STORAGE_KEYS.PERMISSION_WIZARD_COMPLETED, + ); if (wizardCompleted === "true") { set("completed", true); } @@ -27,7 +28,10 @@ export default createAtom(({ set, get }) => { setCompleted: (completed) => { set("completed", completed); if (completed) { - AsyncStorage.setItem(WIZARD_COMPLETED_KEY, "true").catch((error) => { + AsyncStorage.setItem( + STORAGE_KEYS.PERMISSION_WIZARD_COMPLETED, + "true", + ).catch((error) => { console.error("Error saving permission wizard status:", error); }); } diff --git a/src/updates/index.js b/src/updates/index.js index 4323563..7f0e42d 100644 --- a/src/updates/index.js +++ b/src/updates/index.js @@ -1,14 +1,13 @@ import { useCallback, useEffect, useState } from "react"; import { Alert } from "react-native"; import * as Updates from "expo-updates"; -import AsyncStorage from "~/lib/memoryAsyncStorage"; +import AsyncStorage from "~/storage/memoryAsyncStorage"; +import { STORAGE_KEYS } from "~/storage/storageKeys"; import useNow from "~/hooks/useNow"; import * as Sentry from "@sentry/react-native"; import env from "~/env"; import { treeActions } from "~/stores"; - -const LAST_UPDATE_CHECK_KEY = "lastUpdateCheckTime"; const UPDATE_CHECK_INTERVAL = 24 * 60 * 60 * 1000; const applyUpdate = async () => { @@ -28,12 +27,17 @@ const checkForUpdate = async () => { return; } try { - const lastCheckString = await AsyncStorage.getItem(LAST_UPDATE_CHECK_KEY); + const lastCheckString = await AsyncStorage.getItem( + STORAGE_KEYS.LAST_UPDATE_CHECK_TIME, + ); const lastCheck = lastCheckString ? new Date(lastCheckString) : null; const nowDate = new Date(); if (!lastCheck || nowDate - lastCheck > UPDATE_CHECK_INTERVAL) { - await AsyncStorage.setItem(LAST_UPDATE_CHECK_KEY, nowDate.toISOString()); + await AsyncStorage.setItem( + STORAGE_KEYS.LAST_UPDATE_CHECK_TIME, + nowDate.toISOString(), + ); const update = await Updates.checkForUpdateAsync(); if (!update.isAvailable) { diff --git a/src/utils/location/storage.js b/src/utils/location/storage.js index 5659658..49d0388 100644 --- a/src/utils/location/storage.js +++ b/src/utils/location/storage.js @@ -1,4 +1,5 @@ -import AsyncStorage from "~/lib/memoryAsyncStorage"; +import AsyncStorage from "~/storage/memoryAsyncStorage"; +import { STORAGE_KEYS } from "~/storage/storageKeys"; import { createLogger } from "~/lib/logger"; import { SYSTEM_SCOPES } from "~/lib/logger/scopes"; @@ -7,8 +8,6 @@ const storageLogger = createLogger({ feature: "location-cache", }); -export const LOCATION_STORAGE_KEY = "@last_known_location"; - /** * Stores location data in AsyncStorage with timestamp * @param {Object} coords - Location coordinates object @@ -36,7 +35,7 @@ export async function storeLocation( }); await AsyncStorage.setItem( - LOCATION_STORAGE_KEY, + STORAGE_KEYS.LAST_KNOWN_LOCATION, JSON.stringify({ coords, timestamp, @@ -58,7 +57,7 @@ export async function storeLocation( export async function getStoredLocation() { try { storageLogger.debug("Retrieving stored location data"); - const stored = await AsyncStorage.getItem(LOCATION_STORAGE_KEY); + const stored = await AsyncStorage.getItem(STORAGE_KEYS.LAST_KNOWN_LOCATION); if (!stored) { storageLogger.debug("No stored location data found");