ATlast — you'll never need to find your favorites on another platform again. Find your favs in the ATmosphere.
atproto

attempt to fix not fully logging out...i don't think it worked

authored by byarielm.fyi and committed by byarielm.fyi 0f99926f b551dec6

verified
Changed files
+63 -94
dist
netlify
functions
+30 -14
dist/index.html
··· 1 - <!DOCTYPE html> 2 - <html lang="en"> 3 - <head> 4 - <meta charset="UTF-8" /> 5 - <link rel="icon" type="image/svg+xml" href="/vite.svg" /> 6 - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 - <title>ATLast: Sync Your TikTok Follows → ATmosphere (Skylight, Bluesky, etc.)</title> 8 - <script type="module" crossorigin src="/assets/index-8vZ0WHUG.js"></script> 9 - <link rel="stylesheet" crossorigin href="/assets/index-Bs4vTtm8.css"> 10 - </head> 11 - <body> 12 - <div id="root"></div> 13 - </body> 14 - </html> 1 + <!doctype html> 2 + <html lang="en"> 3 + <head> 4 + <meta charset="UTF-8" /> 5 + <link rel="manifest" href="/site.webmanifest" /> 6 + <link 7 + rel="apple-touch-icon" 8 + sizes="180x180" 9 + href="/apple-touch-icon.png" 10 + /> 11 + <link 12 + rel="icon" 13 + type="image/x-icon" 14 + sizes="32x32" 15 + href="/favicon.ico" 16 + /> 17 + <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> 18 + 19 + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 20 + <title> 21 + ATLast: Sync Your TikTok Follows → ATmosphere (Skylight, Bluesky, 22 + etc.) 23 + </title> 24 + <script type="module" crossorigin src="/assets/index-Dx_AzG_Q.js"></script> 25 + <link rel="stylesheet" crossorigin href="/assets/index-C69tQ_4S.css"> 26 + </head> 27 + <body> 28 + <div id="root"></div> 29 + </body> 30 + </html>
+4
netlify/functions/logout.ts
··· 27 27 console.log("[logout] Session ID from cookie:", sessionId); 28 28 29 29 if (sessionId) { 30 + // Get the DID before deleting 31 + const userSession = await userSessions.get(sessionId); 32 + const did = userSession?.did; 33 + 30 34 // Delete session from database 31 35 await userSessions.del(sessionId); 32 36 console.log("[logout] Deleted session from database");
+14 -67
netlify/functions/session.ts
··· 16 16 return key; 17 17 } 18 18 19 - // ENHANCED: Two-tier cache system 20 - // Tier 1: In-memory cache for profile data (lives for function instance) 19 + // In-memory cache for profile 21 20 const profileCache = new Map<string, { data: any; timestamp: number }>(); 22 21 const PROFILE_CACHE_TTL = 5 * 60 * 1000; // 5 minutes 23 - 24 - // Tier 2: Session metadata cache (DID -> basic info, faster than full OAuth restore) 25 - const sessionMetadataCache = new Map< 26 - string, 27 - { 28 - did: string; 29 - lastSeen: number; 30 - profileFetchNeeded: boolean; 31 - } 32 - >(); 33 22 34 23 export const handler: Handler = async ( 35 24 event: HandlerEvent, ··· 49 38 }; 50 39 } 51 40 52 - // OPTIMIZATION: Check session metadata cache first (avoids DB query) 53 - const cachedMetadata = sessionMetadataCache.get(sessionId); 54 - const now = Date.now(); 41 + // Check database for session 42 + const userSession = await userSessions.get(sessionId); 55 43 56 - let did: string; 44 + if (!userSession) { 45 + return { 46 + statusCode: 401, 47 + headers: { "Content-Type": "application/json" }, 48 + body: JSON.stringify({ error: "Invalid or expired session" }), 49 + }; 50 + } 57 51 58 - if (cachedMetadata && now - cachedMetadata.lastSeen < 60000) { 59 - // Session seen within last minute, trust the cache 60 - did = cachedMetadata.did; 61 - console.log("Session metadata from cache"); 62 - } else { 63 - // Need to verify session from database 64 - const userSession = await userSessions.get(sessionId); 65 - if (!userSession) { 66 - // Clear stale cache entry 67 - sessionMetadataCache.delete(sessionId); 68 - return { 69 - statusCode: 401, 70 - headers: { "Content-Type": "application/json" }, 71 - body: JSON.stringify({ error: "Invalid or expired session" }), 72 - }; 73 - } 52 + const did = userSession.did; 53 + const now = Date.now(); 74 54 75 - did = userSession.did; 76 - 77 - // Update session metadata cache 78 - sessionMetadataCache.set(sessionId, { 79 - did, 80 - lastSeen: now, 81 - profileFetchNeeded: true, 82 - }); 83 - 84 - // Cleanup: Remove old session metadata entries 85 - if (sessionMetadataCache.size > 200) { 86 - for (const [sid, meta] of sessionMetadataCache.entries()) { 87 - if (now - meta.lastSeen > 300000) { 88 - // 5 minutes 89 - sessionMetadataCache.delete(sid); 90 - } 91 - } 92 - } 93 - } 94 - 95 - // Check profile cache (Tier 1) 55 + // Check profile cache 96 56 const cached = profileCache.get(did); 97 57 if (cached && now - cached.timestamp < PROFILE_CACHE_TTL) { 98 58 console.log("Returning cached profile for", did); 99 - 100 - // Update session metadata last seen 101 - const meta = sessionMetadataCache.get(sessionId); 102 - if (meta) { 103 - meta.lastSeen = now; 104 - } 105 59 106 60 return { 107 61 statusCode: 200, ··· 181 135 description: profile.data.description, 182 136 }; 183 137 184 - // Cache the profile data (Tier 1) 138 + // Cache the profile data 185 139 profileCache.set(did, { 186 140 data: profileData, 187 141 timestamp: now, 188 142 }); 189 - 190 - // Update session metadata (Tier 2) 191 - const meta = sessionMetadataCache.get(sessionId); 192 - if (meta) { 193 - meta.lastSeen = now; 194 - meta.profileFetchNeeded = false; 195 - } 196 143 197 144 // Clean up old profile cache entries 198 145 if (profileCache.size > 100) {
+14 -13
package-lock.json
··· 30 30 "@types/react-dom": "^19.1.9", 31 31 "@vitejs/plugin-react": "^4.2.1", 32 32 "autoprefixer": "^10.4.21", 33 + "baseline-browser-mapping": "^2.8.31", 33 34 "gh-pages": "^6.3.0", 34 35 "postcss": "^8.5.6", 35 36 "tailwindcss": "^3.4.0", ··· 3408 3409 "license": "MIT" 3409 3410 }, 3410 3411 "node_modules/baseline-browser-mapping": { 3411 - "version": "2.8.7", 3412 - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.7.tgz", 3413 - "integrity": "sha512-bxxN2M3a4d1CRoQC//IqsR5XrLh0IJ8TCv2x6Y9N0nckNz/rTjZB3//GGscZziZOxmjP55rzxg/ze7usFI9FqQ==", 3412 + "version": "2.8.31", 3413 + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.31.tgz", 3414 + "integrity": "sha512-a28v2eWrrRWPpJSzxc+mKwm0ZtVx/G8SepdQZDArnXYU/XS+IF6mp8aB/4E+hH1tyGCoDo3KlUCdlSxGDsRkAw==", 3414 3415 "dev": true, 3415 3416 "license": "Apache-2.0", 3416 3417 "bin": { ··· 4944 4945 } 4945 4946 }, 4946 4947 "node_modules/glob": { 4947 - "version": "10.4.5", 4948 - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", 4949 - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", 4948 + "version": "10.5.0", 4949 + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", 4950 + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", 4950 4951 "license": "ISC", 4951 4952 "dependencies": { 4952 4953 "foreground-child": "^3.1.0", ··· 7266 7267 } 7267 7268 }, 7268 7269 "node_modules/tar": { 7269 - "version": "7.5.1", 7270 - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.1.tgz", 7271 - "integrity": "sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==", 7272 - "license": "ISC", 7270 + "version": "7.5.2", 7271 + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.2.tgz", 7272 + "integrity": "sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==", 7273 + "license": "BlueOak-1.0.0", 7273 7274 "dependencies": { 7274 7275 "@isaacs/fs-minipass": "^4.0.0", 7275 7276 "chownr": "^3.0.0", ··· 7628 7629 } 7629 7630 }, 7630 7631 "node_modules/vite": { 7631 - "version": "5.4.20", 7632 - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.20.tgz", 7633 - "integrity": "sha512-j3lYzGC3P+B5Yfy/pfKNgVEg4+UtcIJcVRt2cDjIOmhLourAqPqf8P7acgxeiSgUB7E3p2P8/3gNIgDLpwzs4g==", 7632 + "version": "5.4.21", 7633 + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", 7634 + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", 7634 7635 "dev": true, 7635 7636 "license": "MIT", 7636 7637 "peer": true,
+1
package.json
··· 34 34 "@types/react-dom": "^19.1.9", 35 35 "@vitejs/plugin-react": "^4.2.1", 36 36 "autoprefixer": "^10.4.21", 37 + "baseline-browser-mapping": "^2.8.31", 37 38 "gh-pages": "^6.3.0", 38 39 "postcss": "^8.5.6", 39 40 "tailwindcss": "^3.4.0",