From 06d40b8e59a35269912b0d57a5a11100939d40b1 Mon Sep 17 00:00:00 2001 From: Jeet Debnath Date: Mon, 9 Mar 2026 12:19:55 +0530 Subject: [PATCH] removed IDToken encrption --- backend/__pycache__/main.cpython-312.pyc | Bin 2409 -> 2409 bytes .../ENCRYPTION_IMPLEMENTATION.md | 0 LIBSODIUM_FIX.md => docs/LIBSODIUM_FIX.md | 0 {backend => docs}/MIGRATION_GUIDE.md | 0 {backend => docs}/REFACTORING_SUMMARY.md | 0 {backend => docs}/SCHEMA.md | 0 project-context.md => docs/project-context.md | 0 src/App.css | 194 +++++++----------- src/contexts/AuthContext.tsx | 15 +- src/index.css | 33 +++ src/lib/crypto.ts | 5 +- src/pages/HistoryPage.tsx | 4 +- 12 files changed, 120 insertions(+), 131 deletions(-) rename ENCRYPTION_IMPLEMENTATION.md => docs/ENCRYPTION_IMPLEMENTATION.md (100%) rename LIBSODIUM_FIX.md => docs/LIBSODIUM_FIX.md (100%) rename {backend => docs}/MIGRATION_GUIDE.md (100%) rename {backend => docs}/REFACTORING_SUMMARY.md (100%) rename {backend => docs}/SCHEMA.md (100%) rename project-context.md => docs/project-context.md (100%) diff --git a/backend/__pycache__/main.cpython-312.pyc b/backend/__pycache__/main.cpython-312.pyc index bd9dfe1807d4480796edabbee434a3f280eaa64e..ff90522dd9d1f4bff2a258c62133fc1d47345ccd 100644 GIT binary patch delta 20 acmaDU^iqiXG%qg~0}u$OuiMBS#|Z#EodrAq delta 20 acmaDU^iqiXG%qg~0}y!sU%rt$juQYvk_H6; diff --git a/ENCRYPTION_IMPLEMENTATION.md b/docs/ENCRYPTION_IMPLEMENTATION.md similarity index 100% rename from ENCRYPTION_IMPLEMENTATION.md rename to docs/ENCRYPTION_IMPLEMENTATION.md diff --git a/LIBSODIUM_FIX.md b/docs/LIBSODIUM_FIX.md similarity index 100% rename from LIBSODIUM_FIX.md rename to docs/LIBSODIUM_FIX.md diff --git a/backend/MIGRATION_GUIDE.md b/docs/MIGRATION_GUIDE.md similarity index 100% rename from backend/MIGRATION_GUIDE.md rename to docs/MIGRATION_GUIDE.md diff --git a/backend/REFACTORING_SUMMARY.md b/docs/REFACTORING_SUMMARY.md similarity index 100% rename from backend/REFACTORING_SUMMARY.md rename to docs/REFACTORING_SUMMARY.md diff --git a/backend/SCHEMA.md b/docs/SCHEMA.md similarity index 100% rename from backend/SCHEMA.md rename to docs/SCHEMA.md diff --git a/project-context.md b/docs/project-context.md similarity index 100% rename from project-context.md rename to docs/project-context.md diff --git a/src/App.css b/src/App.css index 48bbe95..0c90178 100644 --- a/src/App.css +++ b/src/App.css @@ -22,13 +22,13 @@ justify-content: center; gap: 1rem; background: #eef6ee; - color: #6b9a6b; + color: #9ca3af; } .protected-route__spinner { width: 28px; height: 28px; - border: 3px solid #bbf7d0; + border: 3px solid #e5e7eb; border-top-color: #22c55e; border-radius: 50%; animation: spin 0.7s linear infinite; @@ -48,7 +48,7 @@ display: flex; align-items: center; justify-content: center; - background: linear-gradient(160deg, #eef6ee 0%, #d1fae5 50%, #bbf7d0 100%); + background: linear-gradient(160deg, #eef6ee 0%, #dcfce7 100%); padding: 1.5rem; overflow: hidden; } @@ -64,7 +64,7 @@ .login-page__spinner { width: 28px; height: 28px; - border: 3px solid #bbf7d0; + border: 3px solid #e5e7eb; border-top-color: #22c55e; border-radius: 50%; animation: spin 0.7s linear infinite; @@ -75,9 +75,7 @@ padding: 2rem; border-radius: 20px; border-top: 4px solid #22c55e; - box-shadow: - 0 8px 32px rgba(34, 197, 94, 0.12), - 0 2px 8px rgba(0, 0, 0, 0.06); + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08); width: 100%; max-width: 360px; text-align: center; @@ -130,7 +128,7 @@ font-weight: 500; color: #3c4043; background: #fff; - border: 1px solid #d1e7d1; + border: 1px solid #dadce0; border-radius: 10px; cursor: pointer; transition: @@ -140,9 +138,8 @@ } .google-sign-in-btn:hover:not(:disabled) { - background: #f0fdf4; - box-shadow: 0 1px 6px rgba(34, 197, 94, 0.15); - border-color: #22c55e; + background: #f8f9fa; + box-shadow: 0 1px 6px rgba(0, 0, 0, 0.1); } .google-sign-in-btn:disabled { opacity: 0.7; @@ -204,10 +201,7 @@ background: #fff; border-radius: 20px; padding: 1.625rem 1.5rem; - box-shadow: - 0 2px 16px rgba(34, 197, 94, 0.1), - 0 1px 4px rgba(0, 0, 0, 0.04); - border: 1px solid rgba(34, 197, 94, 0.08); + box-shadow: 0 2px 12px rgba(0, 0, 0, 0.07); flex: 1; min-height: 0; display: flex; @@ -250,19 +244,16 @@ color: #374151; background: transparent; border: none; - border-bottom: 1px solid #d1e7d1; + border-bottom: 1px solid #e0f0e0; outline: none; - transition: - border-color 0.2s, - box-shadow 0.2s; + transition: border-color 0.2s; } .journal-title-input::placeholder { - color: #9ec49e; + color: #c4bfb5; } .journal-title-input:focus { border-bottom-color: #22c55e; - box-shadow: 0 1px 0 0 rgba(34, 197, 94, 0.3); } .journal-entry-textarea { @@ -278,11 +269,11 @@ border: none; outline: none; resize: none; - caret-color: #22c55e; + caret-color: #374151; } .journal-entry-textarea::placeholder { - color: #9ec49e; + color: #c4bfb5; font-style: italic; } @@ -334,8 +325,8 @@ -webkit-tap-highlight-color: transparent; } .journal-icon-btn:hover { - color: #22c55e; - background: rgba(34, 197, 94, 0.08); + color: #6b7280; + background: rgba(0, 0, 0, 0.05); } /* ============================ @@ -345,7 +336,7 @@ flex-shrink: 0; position: relative; /* NOT fixed — lives in the flex column */ background: rgba(255, 255, 255, 0.96); - border-top: 1px solid rgba(34, 197, 94, 0.12); + border-top: 1px solid rgba(0, 0, 0, 0.07); padding: 8px 12px 12px; display: flex; align-items: center; @@ -387,8 +378,7 @@ } .bottom-nav-btn:hover { - color: #22c55e; - background: rgba(34, 197, 94, 0.06); + color: #6b7280; } .bottom-nav-btn-active { @@ -441,16 +431,15 @@ align-items: center; justify-content: center; background: #fff; - border: 1px solid #d1e7d1; + border: 1px solid #e5e7eb; border-radius: 50%; cursor: pointer; color: #6b7280; transition: all 0.2s ease; } .history-search-btn:hover { - background: #f0fdf4; - color: #22c55e; - border-color: #22c55e; + background: #f9fafb; + color: #374151; } /* scrollable content area for history */ @@ -471,10 +460,7 @@ background: #fff; border-radius: 18px; padding: 1.125rem 1rem; - box-shadow: - 0 2px 12px rgba(34, 197, 94, 0.08), - 0 1px 4px rgba(0, 0, 0, 0.03); - border: 1px solid rgba(34, 197, 94, 0.08); + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06); margin-bottom: 1.125rem; } @@ -512,8 +498,8 @@ transition: all 0.15s ease; } .calendar-nav-btn:hover { - background: #f0fdf4; - color: #22c55e; + background: #f3f4f6; + color: #374151; } .calendar-grid { @@ -607,9 +593,7 @@ padding: 1rem 1rem 1rem 0.875rem; border-radius: 14px; border-left: 4px solid #22c55e; - box-shadow: - 0 2px 8px rgba(34, 197, 94, 0.08), - 0 1px 3px rgba(0, 0, 0, 0.04); + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05); cursor: pointer; transition: all 0.2s ease; text-align: left; @@ -617,10 +601,7 @@ } .entry-card:hover { transform: translateY(-2px); - box-shadow: - 0 6px 20px rgba(34, 197, 94, 0.15), - 0 2px 6px rgba(0, 0, 0, 0.05); - border-left-color: #16a34a; + box-shadow: 0 5px 16px rgba(0, 0, 0, 0.09); } .entry-header { @@ -713,10 +694,7 @@ background: #fff; border-radius: 18px; padding: 1rem 1.125rem; - box-shadow: - 0 2px 12px rgba(34, 197, 94, 0.08), - 0 1px 4px rgba(0, 0, 0, 0.03); - border: 1px solid rgba(34, 197, 94, 0.08); + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06); } .settings-avatar { @@ -736,7 +714,7 @@ width: 100%; height: 100%; border-radius: 50%; - background: linear-gradient(135deg, #86efac 0%, #22c55e 100%); + background: linear-gradient(135deg, #f9a8d4 0%, #f472b6 100%); display: flex; align-items: center; justify-content: center; @@ -788,10 +766,7 @@ .settings-card { background: #fff; border-radius: 18px; - box-shadow: - 0 2px 12px rgba(34, 197, 94, 0.08), - 0 1px 4px rgba(0, 0, 0, 0.03); - border: 1px solid rgba(34, 197, 94, 0.06); + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06); overflow: hidden; } @@ -811,7 +786,7 @@ transition: background 0.15s ease; } .settings-item-button:hover { - background: #f0fdf4; + background: #f9fafb; } .settings-item-icon { @@ -868,7 +843,7 @@ .settings-divider { height: 1px; - background: #e0f2e0; + background: #f3f4f6; margin: 0 1.125rem; } @@ -939,7 +914,7 @@ } .settings-theme-dot-beige { - background: #eef6ee; + background: #f5f0e8; } .settings-theme-dot-dark { background: #1a1a1a; @@ -951,11 +926,6 @@ opacity: 0.6; cursor: not-allowed; } -.settings-theme-dot-active { - border-color: #22c55e; - box-shadow: 0 0 0 2px #22c55e; - transform: scale(1.1); -} /* Clear Data */ .settings-clear-btn { @@ -997,7 +967,7 @@ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05); } .settings-signout-btn:hover { - background: #f0fdf4; + background: #f9fafb; color: #374151; } @@ -1059,10 +1029,7 @@ max-height: 85vh; overflow-y: auto; padding: 1.25rem 1.25rem calc(1.25rem + env(safe-area-inset-bottom)); - box-shadow: - 0 -4px 32px rgba(34, 197, 94, 0.12), - 0 -1px 8px rgba(0, 0, 0, 0.06); - border-top: 3px solid #22c55e; + box-shadow: 0 -4px 32px rgba(0, 0, 0, 0.12); animation: modalSlideUp 0.25s ease; -webkit-overflow-scrolling: touch; } @@ -1105,7 +1072,7 @@ height: var(--touch-min); border: none; border-radius: 50%; - background: #f0fdf4; + background: #f3f4f6; color: #6b7280; cursor: pointer; transition: @@ -1114,8 +1081,8 @@ flex-shrink: 0; } .entry-modal-close:hover { - background: #dcfce7; - color: #16a34a; + background: #e5e7eb; + color: #374151; } /* Title */ @@ -1229,94 +1196,84 @@ inset: 0; z-index: 2000; background: rgba(0, 0, 0, 0.5); - backdrop-filter: blur(4px); - -webkit-backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; padding: 1.5rem; - animation: modalFadeIn 0.2s ease; + animation: fadeIn 0.15s ease; } .confirm-modal { background: #fff; border-radius: 20px; - padding: 1.75rem 1.5rem; + padding: 1.75rem; + max-width: 380px; width: 100%; - max-width: 340px; - box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15); + box-shadow: 0 12px 40px rgba(0, 0, 0, 0.18); text-align: center; animation: modalScaleIn 0.2s ease; } .confirm-modal-icon { - font-size: 2.5rem; + font-size: 2.25rem; margin-bottom: 0.75rem; } .confirm-modal-title { - margin: 0 0 0.5rem; font-size: 1.25rem; font-weight: 700; - color: #dc2626; - font-family: "Sniglet", system-ui; + color: #ef4444; + margin: 0 0 0.5rem; } .confirm-modal-desc { - margin: 0 0 1rem; - font-size: 0.8125rem; - line-height: 1.5; + font-size: 0.85rem; color: #6b7280; + margin: 0 0 1rem; + line-height: 1.5; } .confirm-modal-label { - margin: 0 0 0.5rem; - font-size: 0.75rem; + font-size: 0.8rem; font-weight: 600; color: #374151; text-align: left; + margin: 0 0 0.375rem; } .confirm-modal-input { width: 100%; padding: 0.625rem 0.75rem; - font-size: 0.875rem; - font-family: "Sniglet", system-ui; - border: 1.5px solid #e5e7eb; + font-size: 0.9rem; + font-family: inherit; + border: 1.5px solid #d1d5db; border-radius: 10px; outline: none; - transition: border-color 0.2s; + transition: border-color 0.15s; margin-bottom: 1rem; - color: #1a1a1a; - background: #f9fafb; } .confirm-modal-input:focus { - border-color: #dc2626; - background: #fff; -} - -.confirm-modal-input::placeholder { - color: #c4c4c4; + border-color: #ef4444; } .confirm-modal-actions { display: flex; - gap: 0.625rem; + gap: 0.75rem; } .confirm-modal-cancel { flex: 1; - padding: 0.625rem; - font-size: 0.875rem; - font-weight: 600; - font-family: "Sniglet", system-ui; - color: #6b7280; - background: #f3f4f6; + padding: 0.65rem; border: none; - border-radius: 10px; + border-radius: 12px; + font-size: 0.9rem; + font-weight: 600; + font-family: inherit; + background: #f3f4f6; + color: #374151; cursor: pointer; - transition: background 0.2s; + transition: background 0.15s; } .confirm-modal-cancel:hover:not(:disabled) { @@ -1325,20 +1282,22 @@ .confirm-modal-delete { flex: 1; - padding: 0.625rem; - font-size: 0.875rem; - font-weight: 600; - font-family: "Sniglet", system-ui; - color: #fff; - background: #dc2626; + padding: 0.65rem; border: none; - border-radius: 10px; + border-radius: 12px; + font-size: 0.9rem; + font-weight: 600; + font-family: inherit; + background: #ef4444; + color: #fff; cursor: pointer; - transition: background 0.2s; + transition: + background 0.15s, + opacity 0.15s; } .confirm-modal-delete:hover:not(:disabled) { - background: #b91c1c; + background: #dc2626; } .confirm-modal-delete:disabled { @@ -1767,8 +1726,3 @@ border-color: rgba(74, 222, 128, 0.3); box-shadow: 0 1px 8px rgba(74, 222, 128, 0.1); } - -/* -- Success/error message inline -- */ -[data-theme="dark"] .settings-container [style*="backgroundColor"] { - /* Handled inline but these override for common patterns */ -} diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx index 4ab804e..d3bdeb6 100644 --- a/src/contexts/AuthContext.tsx +++ b/src/contexts/AuthContext.tsx @@ -47,10 +47,9 @@ export function AuthProvider({ children }: { children: ReactNode }) { const [loading, setLoading] = useState(true) // Initialize encryption keys on login - async function initializeEncryption(authUser: User, token: string) { + async function initializeEncryption(authUser: User) { try { const firebaseUID = authUser.uid - const firebaseIDToken = token // Get or create salt let salt = getSalt() @@ -59,8 +58,8 @@ export function AuthProvider({ children }: { children: ReactNode }) { saveSalt(salt) } - // Derive master key from Firebase credentials - const derivedKey = await deriveSecretKey(firebaseUID, firebaseIDToken, salt) + // Derive master key from Firebase UID (stable across sessions) + const derivedKey = await deriveSecretKey(firebaseUID, salt) // Check if device key exists let deviceKey = await getDeviceKey() @@ -110,13 +109,16 @@ export function AuthProvider({ children }: { children: ReactNode }) { const email = authUser.email! // Initialize encryption before syncing user - await initializeEncryption(authUser, token) + await initializeEncryption(authUser) // Try to get existing user try { + console.log('[Auth] Fetching user by email:', email) const existingUser = await getUserByEmail(email, token) as { id: string } + console.log('[Auth] Found existing user:', existingUser.id) setUserId(existingUser.id) } catch (error) { + console.warn('[Auth] User not found, registering...', error) // User doesn't exist, register them const newUser = await registerUser( { @@ -126,10 +128,11 @@ export function AuthProvider({ children }: { children: ReactNode }) { }, token ) as { id: string } + console.log('[Auth] Registered new user:', newUser.id) setUserId(newUser.id) } } catch (error) { - console.error('Error syncing user with database:', error) + console.error('[Auth] Error syncing user with database:', error) throw error } } diff --git a/src/index.css b/src/index.css index 300dc60..7efa0f6 100644 --- a/src/index.css +++ b/src/index.css @@ -95,3 +95,36 @@ button:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; } + +/* ── Dark theme root overrides ────────────────────────── */ +[data-theme="dark"] { + --color-primary: #4ade80; + --color-primary-hover: #22c55e; + --color-bg-soft: #0f0f0f; + --color-surface: #1a1a1a; + --color-accent-light: rgba(74, 222, 128, 0.12); + --color-text: #e8f5e8; + --color-text-muted: #7a8a7a; + --color-border: rgba(74, 222, 128, 0.12); + + color: var(--color-text); + background-color: var(--color-bg-soft); + caret-color: #4ade80; +} + +[data-theme="dark"] body { + background: #0a0a0a; +} + +@media (min-width: 600px) { + [data-theme="dark"] body { + background: #111; + } + + [data-theme="dark"] #root { + box-shadow: + 0 24px 80px rgba(0, 0, 0, 0.6), + 0 4px 16px rgba(0, 0, 0, 0.4), + 0 0 0 1px rgba(74, 222, 128, 0.08); + } +} diff --git a/src/lib/crypto.ts b/src/lib/crypto.ts index c9b0813..538de78 100644 --- a/src/lib/crypto.ts +++ b/src/lib/crypto.ts @@ -20,12 +20,11 @@ import { getSodium } from '../utils/sodium' */ export async function deriveSecretKey( firebaseUID: string, - firebaseIDToken: string, salt: string ): Promise { // Use native Web Crypto API for key derivation (PBKDF2) - // This is more reliable than libsodium's Argon2i - const password = `${firebaseUID}:${firebaseIDToken}` + // Derives from UID only — stable across sessions + const password = firebaseUID const encoding = new TextEncoder() const passwordBuffer = encoding.encode(password) const saltBuffer = encoding.encode(salt) diff --git a/src/pages/HistoryPage.tsx b/src/pages/HistoryPage.tsx index e676ac2..c9c4a55 100644 --- a/src/pages/HistoryPage.tsx +++ b/src/pages/HistoryPage.tsx @@ -180,12 +180,12 @@ export default function HistoryPage() {

History

Your past reflections

- {/* */} +