Coffee journaling on ATProto (alpha) alpha.arabica.social
coffee

fix: isAuthed brew display bug

pdewey.com 0a878e1d bc4ac2e9

verified
+46 -4
+3 -1
internal/bff/render.go
··· 120 120 Brews []*BrewListData 121 121 FeedItems []*feed.FeedItem 122 122 IsAuthenticated bool 123 + IsOwnProfile bool 123 124 UserDID string 124 125 UserProfile *UserProfile 125 126 } ··· 275 276 } 276 277 277 278 data := &PageData{ 278 - Brews: brewList, 279 + Brews: brewList, 280 + IsOwnProfile: true, // This endpoint is only used for viewing own brews 279 281 } 280 282 return t.ExecuteTemplate(w, "brew_list_content", data) 281 283 }
+4
internal/handlers/handlers.go
··· 634 634 return 635 635 } 636 636 637 + // Get user DID for cache validation 638 + userDID, _ := atproto.GetAuthenticatedDID(r.Context()) 639 + 637 640 ctx := r.Context() 638 641 639 642 // Fetch all collections in parallel using errgroup ··· 681 684 atproto.LinkBeansToRoasters(beans, roasters) 682 685 683 686 response := map[string]interface{}{ 687 + "did": userDID, 684 688 "beans": beans, 685 689 "roasters": roasters, 686 690 "grinders": grinders,
+1 -1
templates/layout.tmpl
··· 23 23 {{end}} 24 24 <script src="/static/js/sw-register.js"></script> 25 25 </head> 26 - <body class="bg-brown-50 min-h-full flex flex-col"> 26 + <body class="bg-brown-50 min-h-full flex flex-col"{{if .UserDID}} data-user-did="{{.UserDID}}"{{end}}> 27 27 {{template "header" .}} 28 28 <main class="flex-grow container mx-auto px-4 py-8"> 29 29 {{template "content" .}}
+1 -1
templates/partials/header.tmpl
··· 57 57 Settings (coming soon) 58 58 </a> 59 59 <div class="border-t border-brown-100 mt-1 pt-1"> 60 - <form action="/logout" method="POST"> 60 + <form action="/logout" method="POST" onsubmit="if(window.ArabicaCache){window.ArabicaCache.invalidateCache()}"> 61 61 <button type="submit" class="w-full text-left px-4 py-2 text-sm text-brown-700 hover:bg-brown-50 transition-colors"> 62 62 Logout 63 63 </button>
+37 -1
web/static/js/data-cache.js
··· 40 40 41 41 /** 42 42 * Save data to the cache 43 + * Stores the user DID alongside the data for validation 43 44 */ 44 45 function setCache(data) { 45 46 try { 46 47 const cache = { 47 48 version: CACHE_VERSION, 48 49 timestamp: Date.now(), 50 + did: data.did || null, // Store user DID for cache validation 49 51 data: data, 50 52 }; 51 53 localStorage.setItem(CACHE_KEY, JSON.stringify(cache)); 52 54 } catch (e) { 53 55 console.warn("Failed to write cache:", e); 54 56 } 57 + } 58 + 59 + /** 60 + * Get the DID stored in the cache 61 + */ 62 + function getCachedDID() { 63 + const cache = getCache(); 64 + return cache?.did || null; 55 65 } 56 66 57 67 /** ··· 66 76 } 67 77 68 78 /** 69 - * Get cached data if available and valid 79 + * Get the current user's DID from the page 80 + */ 81 + function getCurrentUserDID() { 82 + return document.body?.dataset?.userDid || null; 83 + } 84 + 85 + /** 86 + * Get cached data if available and valid for the current user 70 87 */ 71 88 function getCachedData() { 72 89 const cache = getCache(); 73 90 if (!cache) return null; 74 91 92 + // Validate that cached data belongs to the current user 93 + const currentDID = getCurrentUserDID(); 94 + const cachedDID = cache.did; 95 + 96 + // If we have both DIDs and they don't match, cache is invalid 97 + if (currentDID && cachedDID && currentDID !== cachedDID) { 98 + console.log("Cache belongs to different user, invalidating"); 99 + invalidateCache(); 100 + return null; 101 + } 102 + 75 103 // Return data even if expired - caller can decide to refresh 76 104 return cache.data; 77 105 } ··· 118 146 isRefreshing = true; 119 147 try { 120 148 const data = await fetchFreshData(); 149 + 150 + // Check if user changed (different DID) 151 + const cachedDID = getCachedDID(); 152 + if (cachedDID && data.did && cachedDID !== data.did) { 153 + console.log("User changed, clearing stale cache"); 154 + invalidateCache(); 155 + } 156 + 121 157 setCache(data); 122 158 notifyListeners(data); 123 159 return data;