phase 1-6 implemented

This commit is contained in:
dimitar committed 2026-03-10 04:14:03 +01:00
1 parent 22c274bb83
commit 2c4927478a
73 files changed
+9702 -2354

No files matched your search

+54 -43
View File
@@ -3,39 +3,56 @@ import { Stack } from "expo-router";
import * as SecureStore from "expo-secure-store";
import { View, Text } from "react-native";
import { useEffect, useState } from "react";
import { validateEnv } from "../utils/env";
import log from "../utils/logger";
console.log("========================================");
console.log("🚀 _layout.tsx loaded at:", new Date().toISOString());
console.log(
"📦 EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY:",
process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY,
);
console.log("========================================");
// Validate environment variables on app startup
try {
const env = validateEnv();
log.info("Environment validation passed", {
appName: env.EXPO_PUBLIC_APP_NAME,
apiUrl: env.EXPO_PUBLIC_API_URL,
});
} catch (error) {
log.error("Environment validation failed", error);
// In development, show the error but allow app to continue
// In production, this will crash the app (as it should)
if (!__DEV__) {
throw error;
}
}
// Token cache for Clerk
const tokenCache = {
async getToken(key: string) {
try {
const value = await SecureStore.getItemAsync(key);
console.log(`[TokenCache] Getting key: ${key}, exists: ${!!value}`);
if (value && value.length > 50) {
console.log(`[TokenCache] Value preview: ${value.substring(0, 50)}...`);
}
log.debug("Getting token from cache", {
key,
exists: !!value,
preview:
value && value.length > 50
? value.substring(0, 50) + "..."
: undefined,
});
return value;
} catch (err) {
console.error("Error getting token:", err);
log.error("Failed to get token from cache", err, { key });
return null;
}
},
async saveToken(key: string, value: string) {
try {
console.log(`[TokenCache] Saving key: ${key}`);
if (value && value.length > 50) {
console.log(`[TokenCache] Value preview: ${value.substring(0, 50)}...`);
}
log.debug("Saving token to cache", {
key,
preview:
value && value.length > 50
? value.substring(0, 50) + "..."
: undefined,
});
return SecureStore.setItemAsync(key, value);
} catch (err) {
console.error("Error saving token:", err);
log.error("Failed to save token to cache", err, { key });
}
},
};
@@ -44,18 +61,17 @@ export default function RootLayout() {
const publishableKey = process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY;
const [cacheCleared, setCacheCleared] = useState(false);
console.log(
"🔑 [RootLayout] Component rendering with publishableKey:",
publishableKey,
);
log.debug("RootLayout rendering", {
hasPublishableKey: !!publishableKey,
});
// TEMPORARY: Clear Clerk cache on app start to fix instance mismatch
useEffect(() => {
console.log("⚡ [RootLayout] useEffect triggered - starting cache cleanup");
log.debug("Starting cache cleanup");
const clearOldClerkCache = async () => {
try {
console.log("🔍 [RootLayout] Checking for old Clerk tokens...");
log.debug("Checking for old Clerk tokens");
const keysToCheck = [
"__clerk_client_jwt",
@@ -70,34 +86,30 @@ export default function RootLayout() {
try {
const value = await SecureStore.getItemAsync(key);
if (value) {
console.log(`📌 [RootLayout] Found token at ${key}`);
console.log(
`📝 [RootLayout] Token preview: ${value.substring(0, 80)}...`,
);
log.debug("Found token", {
key,
preview: value.substring(0, 80) + "...",
});
// Check if it's from the old instance
if (value.includes("pleasing-pheasant-20")) {
console.log(`🗑️ [RootLayout] DELETING old token from ${key}`);
log.debug("Deleting old token", { key });
await SecureStore.deleteItemAsync(key);
} else if (value.includes("needed-elephant-64")) {
console.log(
`✅ [RootLayout] Token is from correct instance (needed-elephant-64)`,
);
log.debug("Token is from correct instance");
} else {
console.log(
`⚠️ [RootLayout] Token doesn't match known instances`,
);
log.warn("Token doesn't match known instances", { key });
}
}
} catch (e) {
console.log(`❌ [RootLayout] Error checking key ${key}:`, e);
log.error("Error checking token key", e, { key });
}
}
console.log("✅ [RootLayout] Old token cleanup complete");
log.info("Old token cleanup complete");
setCacheCleared(true);
} catch (error) {
console.error("❌ [RootLayout] Error clearing old cache:", error);
log.error("Error clearing old cache", error);
setCacheCleared(true); // Continue anyway
}
};
@@ -106,7 +118,7 @@ export default function RootLayout() {
}, []);
if (!publishableKey) {
console.log("❌ [RootLayout] No publishable key found!");
log.error("No Clerk publishable key found");
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Missing Clerk Publishable Key</Text>
@@ -120,7 +132,7 @@ export default function RootLayout() {
}
if (!cacheCleared) {
console.log("⏳ [RootLayout] Waiting for cache to clear...");
log.debug("Waiting for cache to clear");
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Clearing old authentication cache...</Text>
@@ -131,10 +143,9 @@ export default function RootLayout() {
);
}
console.log(
"🚀 [RootLayout] Rendering ClerkProvider with key:",
publishableKey?.substring(0, 20) + "...",
);
log.debug("Rendering ClerkProvider", {
keyPreview: publishableKey?.substring(0, 20) + "...",
});
return (
<ClerkProvider tokenCache={tokenCache} publishableKey={publishableKey}>