refactor: storage
This commit is contained in:
parent
a83d423c77
commit
27ead01714
18 changed files with 203 additions and 118 deletions
14
index.js
14
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" },
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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) + "...",
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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";
|
||||
|
|
12
src/env.js
12
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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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", {
|
||||
|
|
|
@ -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) {
|
|
@ -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) {
|
83
src/storage/storageKeys.js
Normal file
83
src/storage/storageKeys.js
Normal file
|
@ -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"),
|
||||
};
|
|
@ -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) {
|
||||
|
|
|
@ -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 });
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Add table
Reference in a new issue