This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

tweaks

+114 -82
+12 -5
app/src/app/api/bluesky/profile/route.ts
··· 13 13 ); 14 14 } 15 15 16 - // Check if handle is provided, use a default otherwise 17 - const userHandle = handle || 'atproto.com'; 18 - 19 16 // Use the PDS endpoint if provided, otherwise use the default 20 17 const apiUrl = pdsEndpoint ? `${pdsEndpoint}/xrpc` : DEFAULT_API_URL; 21 18 22 - // Make the request to the user's PDS 23 - const url = `${apiUrl}/com.atproto.identity.resolveHandle?handle=${encodeURIComponent(userHandle)}`; 19 + // We can resolve either a handle or a DID 20 + let url; 21 + if (handle && handle.startsWith('did:')) { 22 + // If it's a DID, use describeRepo to get details 23 + url = `${apiUrl}/com.atproto.repo.describeRepo?repo=${encodeURIComponent(handle)}`; 24 + console.log('Looking up account info by DID:', handle); 25 + } else { 26 + // Otherwise treat it as a handle to resolve 27 + const userHandle = handle || 'atproto.com'; 28 + url = `${apiUrl}/com.atproto.identity.resolveHandle?handle=${encodeURIComponent(userHandle)}`; 29 + console.log('Looking up account info by handle:', userHandle); 30 + } 24 31 console.log('Making request to:', url); 25 32 26 33 const response = await fetch(url, {
+36 -7
app/src/app/auth/callback/page.tsx
··· 171 171 }); 172 172 173 173 // Extract the DID from the token response 174 - console.log('Token response:', tokenResponse); 175 174 const userDid = tokenResponse.sub; 176 175 console.log('User DID from token:', userDid); 177 176 ··· 185 184 if (parts.length === 3) { 186 185 // Decode the payload (second part) 187 186 const payload = JSON.parse(atob(parts[1])); 188 - console.log('Decoded token payload:', payload); 189 187 190 188 // Extract audience from the decoded token 191 189 if (payload.aud && typeof payload.aud === 'string') { 192 - console.log('Audience from decoded token:', payload.aud); 193 - 194 190 // Update the pdsEndpoint from the decoded token if available 195 191 if (payload.aud.startsWith('did:web:')) { 196 192 // Convert did:web:example.com to https://example.com ··· 212 208 console.error('Failed to extract PDS endpoint from token. This will cause API calls to fail.'); 213 209 } 214 210 215 - // Try to resolve the user's own handle using the DID 216 - let userHandle = profileResponse?.handle || 'unknown'; 211 + // Now that we have the PDS endpoint, try to get the user's handle directly 212 + // First try to use the profileResponse we already have 213 + let userHandle = profileResponse?.handle; 214 + 215 + // If we don't have a handle yet, try to resolve it using the user's DID 216 + if (!userHandle || userHandle === 'unknown' || userHandle === 'unknown_user') { 217 + try { 218 + console.log('Getting user handle from DID...'); 219 + // Try to make a direct call to resolve the handle from the DID 220 + const handleResponse = await getProfile( 221 + tokenResponse.access_token, 222 + keyPair, 223 + dpopNonce, 224 + userDid, // Use the user's DID instead of default 225 + pdsEndpoint 226 + ); 227 + 228 + if (handleResponse && handleResponse.handle) { 229 + userHandle = handleResponse.handle; 230 + console.log('Successfully resolved user handle:', userHandle); 231 + } else { 232 + userHandle = 'unknown'; 233 + } 234 + } catch (error) { 235 + console.error('Failed to resolve user handle:', error); 236 + userHandle = 'unknown'; 237 + } 238 + } 217 239 218 240 // Log the PDS endpoint that will be used 219 241 console.log('Using PDS endpoint for API requests:', pdsEndpoint); ··· 230 252 pdsEndpoint: pdsEndpoint // Store the PDS endpoint for later use 231 253 }); 232 254 233 - // Clear storage 255 + // Clear all auth-related storage items 234 256 clearAuthData('oauth_state'); 235 257 clearAuthData('code_verifier'); 236 258 clearAuthData('key_pair'); 259 + 260 + // Also try to clear any leftover sessionStorage items 261 + try { 262 + sessionStorage.clear(); 263 + } catch (e) { 264 + console.warn('Failed to clear session storage:', e); 265 + } 237 266 238 267 // Redirect to dashboard 239 268 router.push('/dashboard');
+13 -4
app/src/lib/bluesky-api.ts
··· 231 231 const publicKey = await exportJWK(keyPair.publicKey); 232 232 // Use the PDS endpoint if available 233 233 const baseUrl = pdsEndpoint ? `${pdsEndpoint}/xrpc` : 'https://bsky.social/xrpc'; 234 - // Include the handle parameter in the URL for token creation 235 - const endpoint = `${baseUrl}/com.atproto.identity.resolveHandle?handle=${encodeURIComponent(handle)}`; 234 + 235 + // Determine the endpoint based on whether we're looking up a DID or handle 236 + let endpoint; 237 + if (handle && handle.startsWith('did:')) { 238 + // If it's a DID, use the describeRepo endpoint 239 + endpoint = `${baseUrl}/com.atproto.repo.describeRepo?repo=${encodeURIComponent(handle)}`; 240 + console.log('Looking up profile by DID:', handle); 241 + } else { 242 + // Otherwise use resolveHandle for handles 243 + endpoint = `${baseUrl}/com.atproto.identity.resolveHandle?handle=${encodeURIComponent(handle)}`; 244 + console.log('Looking up profile by handle:', handle); 245 + } 236 246 237 247 // Generate the DPoP token with the access token for the ath claim 238 248 const dpopToken = await generateDPoPToken( ··· 315 325 // Generate a DPoP token for the create request 316 326 const publicKey = await exportJWK(keyPair.publicKey); 317 327 318 - console.log('Generating DPoP token for:', endpoint, 'with nonce:', dpopNonce || 'none'); 319 - console.log('Including access token hash (ath) in DPoP token'); 328 + // Generate token with appropriate claims for the request 320 329 321 330 const dpopToken = await generateDPoPToken( 322 331 keyPair.privateKey,
+1 -1
app/src/lib/bluesky-auth.ts
··· 105 105 106 106 // Add access token hash (ath) if access token is provided 107 107 if (accessToken) { 108 - console.log('Adding ath claim to DPoP token'); 108 + // Adding ath claim is required when using access tokens with DPoP 109 109 const tokenHash = await sha256(accessToken); 110 110 payload.ath = arrayBufferToBase64Url(tokenHash); 111 111 }
+52 -65
contextual info for claude/app_errors.md
··· 1 1 Storage access automatically granted for Dynamic State Partitioning “https://bsky.social” on “https://flushing.im”. callback 2 2 GET 3 3 https://flushing.im/favicon.ico 4 - [HTTP/2 404 61ms] 4 + [HTTP/2 404 0ms] 5 5 6 - Callback received state: 9StyI... page-099e80a200860a21.js:1:1095 7 - Stored state: 9StyI... page-099e80a200860a21.js:1:1175 8 - Exchanging code for token... page-099e80a200860a21.js:1:2016 9 - No nonce provided, getting one from API... 481-d3c58c35fd99af50.js:1:8385 10 - Obtained nonce from API: nnKOYi3GWF5VHcaGl3ZfUAQeplTiEeWEi6_FH2BGrLI 481-d3c58c35fd99af50.js:1:8462 11 - Creating DPoP token with nonce: nnKOYi3GWF5VHcaGl3ZfUAQeplTiEeWEi6_FH2BGrLI 481-d3c58c35fd99af50.js:1:8574 12 - Making token request via proxy API 481-d3c58c35fd99af50.js:1:8713 13 - Token request successful 481-d3c58c35fd99af50.js:1:9206 14 - Token audience: undefined page-099e80a200860a21.js:1:2368 15 - Token audience missing or not a string: undefined page-099e80a200860a21.js:1:2626 16 - Getting profile via proxy API 481-d3c58c35fd99af50.js:1:3560 6 + Callback received state: sKbxR... page-a2b4c23153d80106.js:1:993 7 + Stored state: sKbxR... page-a2b4c23153d80106.js:1:1073 8 + Exchanging code for token... page-a2b4c23153d80106.js:1:1914 9 + No nonce provided, getting one from API... 481-38cee1d3cffbeb60.js:1:8815 10 + Obtained nonce from API: jEDudu85YaVxa83p3YzTLY4VYmRv2O6VpyOwSkZtXu8 481-38cee1d3cffbeb60.js:1:8892 11 + Creating DPoP token with nonce: jEDudu85YaVxa83p3YzTLY4VYmRv2O6VpyOwSkZtXu8 481-38cee1d3cffbeb60.js:1:9004 12 + Making token request via proxy API 481-38cee1d3cffbeb60.js:1:9143 13 + Token request successful 481-38cee1d3cffbeb60.js:1:9636 14 + Token audience: undefined page-a2b4c23153d80106.js:1:2266 15 + Token audience missing or not a string: undefined page-a2b4c23153d80106.js:1:2524 16 + Getting profile via proxy API 481-38cee1d3cffbeb60.js:1:3562 17 + Adding ath claim to DPoP token 481-38cee1d3cffbeb60.js:1:6994 17 18 Token response: 18 - Object { access_token: "eyJ0eXAiOiJhdCtqd3QiLCJhbGciOiJFUzI1NksifQ.eyJhdWQiOiJkaWQ6d2ViOmVub2tpLnVzLWVhc3QuaG9zdC5ic2t5Lm5ldHdvcmsiLCJpYXQiOjE3NDEzOTAzMzcsImV4cCI6MTc0MTM5MzkzNywic3ViIjoiZGlkOnBsYzpncTRmbzN1NnRxenpka2psd3pwYjIzdGoiLCJqdGkiOiJ0b2stODAwZjEwZTEzOTEyYjA0MTljOGYyZTc4ZDkzZWRkZjIiLCJjbmYiOnsiamt0IjoiR3lXWnA3cUZOajFiaWttMHhRX1pMTGR4WnhMVTdCNmRqaEZSTU1HR1o0TSJ9LCJjbGllbnRfaWQiOiJodHRwczovL2ZsdXNoaW5nLmltL2NsaWVudC1tZXRhZGF0YS5qc29uIiwic2NvcGUiOiJhdHByb3RvIHRyYW5zaXRpb246Z2VuZXJpYyIsImlzcyI6Imh0dHBzOi8vYnNreS5zb2NpYWwifQ.fIVsf2SJRsaPDCRpaJhYyFsXOpGcvxxutZhqHfLwS97XtMxh63yPZZq26vhC2aHJ_7omR1a6MJjEptDZfvTrVQ", token_type: "DPoP", refresh_token: "ref-2dda4b2d21fbb21df5b02d34f3dafd35ccef542b4a4fce652b3ce1958c7571cd", scope: "atproto transition:generic", expires_in: 3599, sub: "did:plc:gq4fo3u6tqzzdkjlwzpb23tj" } 19 - page-099e80a200860a21.js:1:2883 20 - User DID from token: did:plc:gq4fo3u6tqzzdkjlwzpb23tj page-099e80a200860a21.js:1:2928 19 + Object { access_token: "eyJ0eXAiOiJhdCtqd3QiLCJhbGciOiJFUzI1NksifQ.eyJhdWQiOiJkaWQ6d2ViOmVub2tpLnVzLWVhc3QuaG9zdC5ic2t5Lm5ldHdvcmsiLCJpYXQiOjE3NDEzOTEwMzUsImV4cCI6MTc0MTM5NDYzNSwic3ViIjoiZGlkOnBsYzpncTRmbzN1NnRxenpka2psd3pwYjIzdGoiLCJqdGkiOiJ0b2stMDU0ZTAyMjI4MTcxYTNlMDcyYTNhODQ0Y2I4Njk1YTciLCJjbmYiOnsiamt0IjoiNVltV1k3SE5zM3BGdFVEd1VlaGlpbkxEYXdXR1Z3VXU5dUNEZUxmVURhSSJ9LCJjbGllbnRfaWQiOiJodHRwczovL2ZsdXNoaW5nLmltL2NsaWVudC1tZXRhZGF0YS5qc29uIiwic2NvcGUiOiJhdHByb3RvIHRyYW5zaXRpb246Z2VuZXJpYyIsImlzcyI6Imh0dHBzOi8vYnNreS5zb2NpYWwifQ.k6Z977hSzPqhljN1wje06apxn_uBxZajHWiSCulboe4kxCOrn_iHUd7-ANMXo2YwSGz5rQL-t-KeZv-IKyBzlw", token_type: "DPoP", refresh_token: "ref-d556158ae379dd4dae168f84b27a214c2a8e044d506d95c9f4c5ec8c25dca656", scope: "atproto transition:generic", expires_in: 3599, sub: "did:plc:gq4fo3u6tqzzdkjlwzpb23tj" } 20 + page-a2b4c23153d80106.js:1:2781 21 + User DID from token: did:plc:gq4fo3u6tqzzdkjlwzpb23tj page-a2b4c23153d80106.js:1:2826 21 22 Decoded token payload: 22 - Object { aud: "did:web:enoki.us-east.host.bsky.network", iat: 1741390337, exp: 1741393937, sub: "did:plc:gq4fo3u6tqzzdkjlwzpb23tj", jti: "tok-800f10e13912b0419c8f2e78d93eddf2", cnf: {…}, client_id: "https://flushing.im/client-metadata.json", scope: "atproto transition:generic", iss: "https://bsky.social" } 23 - page-099e80a200860a21.js:1:3078 24 - Audience from decoded token: did:web:enoki.us-east.host.bsky.network page-099e80a200860a21.js:1:3150 25 - Extracted PDS endpoint from decoded token: https://enoki.us-east.host.bsky.network page-099e80a200860a21.js:1:3273 26 - Using PDS endpoint for API requests: https://enoki.us-east.host.bsky.network page-099e80a200860a21.js:1:3533 27 - Saving PDS endpoint to auth context: https://enoki.us-east.host.bsky.network page-099e80a200860a21.js:1:3587 28 - Callback received state: 9StyI... page-099e80a200860a21.js:1:1095 29 - Stored state: undefined... page-099e80a200860a21.js:1:1175 30 - No stored OAuth state found. Session storage may have been cleared. 117-89c59c874aec3528.js:1:4081 23 + Object { aud: "did:web:enoki.us-east.host.bsky.network", iat: 1741391035, exp: 1741394635, sub: "did:plc:gq4fo3u6tqzzdkjlwzpb23tj", jti: "tok-054e02228171a3e072a3a844cb8695a7", cnf: {…}, client_id: "https://flushing.im/client-metadata.json", scope: "atproto transition:generic", iss: "https://bsky.social" } 24 + page-a2b4c23153d80106.js:1:2976 25 + Audience from decoded token: did:web:enoki.us-east.host.bsky.network page-a2b4c23153d80106.js:1:3048 26 + Extracted PDS endpoint from decoded token: https://enoki.us-east.host.bsky.network page-a2b4c23153d80106.js:1:3171 27 + Using PDS endpoint for API requests: https://enoki.us-east.host.bsky.network page-a2b4c23153d80106.js:1:3431 28 + Saving PDS endpoint to auth context: https://enoki.us-east.host.bsky.network page-a2b4c23153d80106.js:1:3485 29 + Callback received state: sKbxR... page-a2b4c23153d80106.js:1:993 30 + Stored state: undefined... page-a2b4c23153d80106.js:1:1073 31 + No stored OAuth state found. Browser storage may have been cleared. 117-9a2b9731dac7965d.js:1:4081 31 32 Submitting status update with DID: did:plc:gq4fo3u6tqzzdkjlwzpb23tj page-1f5ea258c75e5bac.js:1:1200 32 33 Using PDS endpoint: https://enoki.us-east.host.bsky.network page-1f5ea258c75e5bac.js:1:1252 33 - Checking auth with PDS endpoint: https://enoki.us-east.host.bsky.network 481-d3c58c35fd99af50.js:1:2469 34 - Making auth check request to: https://enoki.us-east.host.bsky.network/xrpc/com.atproto.identity.resolveHandle?handle=atproto.com 481-d3c58c35fd99af50.js:1:2709 35 - Auth check successful! 481-d3c58c35fd99af50.js:1:2856 34 + Checking auth with PDS endpoint: https://enoki.us-east.host.bsky.network 481-38cee1d3cffbeb60.js:1:2469 35 + Adding ath claim to DPoP token 481-38cee1d3cffbeb60.js:1:6994 36 + Making auth check request to: https://enoki.us-east.host.bsky.network/xrpc/com.atproto.identity.resolveHandle?handle=atproto.com 481-38cee1d3cffbeb60.js:1:2711 37 + Auth check successful! 481-38cee1d3cffbeb60.js:1:2858 36 38 Authentication verified, creating status... page-1f5ea258c75e5bac.js:1:1662 37 - Creating flushing status (attempt 1/3) with nonce: null 481-d3c58c35fd99af50.js:1:4526 38 - Using PDS endpoint: https://enoki.us-east.host.bsky.network 481-d3c58c35fd99af50.js:1:4608 39 - API endpoint: https://enoki.us-east.host.bsky.network/xrpc/com.atproto.repo.createRecord 481-d3c58c35fd99af50.js:1:4985 40 - Generating DPoP token for: https://enoki.us-east.host.bsky.network/xrpc/com.atproto.repo.createRecord with nonce: none 481-d3c58c35fd99af50.js:1:5050 41 - Sending request to proxy API... 481-d3c58c35fd99af50.js:1:5174 42 - XHRPOST 43 - https://flushing.im/api/bluesky/flushing 44 - [HTTP/2 401 200ms] 45 - 46 - Status creation error: 47 - Object { error: "use_dpop_nonce", nonce: "Cu3Gn9OQuKUyKfqV9bGK0pqqeHPvm-tWhsvc9-6cmkA", originalError: {…} } 48 - 117-89c59c874aec3528.js:1:4081 49 - Received DPoP nonce error, retrying with nonce: Cu3Gn9OQuKUyKfqV9bGK0pqqeHPvm-tWhsvc9-6cmkA 481-d3c58c35fd99af50.js:1:5620 50 - Creating flushing status (attempt 2/3) with nonce: Cu3Gn9OQuKUyKfqV9bGK0pqqeHPvm-tWhsvc9-6cmkA 481-d3c58c35fd99af50.js:1:4526 51 - Using PDS endpoint: https://enoki.us-east.host.bsky.network 481-d3c58c35fd99af50.js:1:4608 52 - API endpoint: https://enoki.us-east.host.bsky.network/xrpc/com.atproto.repo.createRecord 481-d3c58c35fd99af50.js:1:4985 53 - Generating DPoP token for: https://enoki.us-east.host.bsky.network/xrpc/com.atproto.repo.createRecord with nonce: Cu3Gn9OQuKUyKfqV9bGK0pqqeHPvm-tWhsvc9-6cmkA 481-d3c58c35fd99af50.js:1:5050 54 - Sending request to proxy API... 481-d3c58c35fd99af50.js:1:5174 55 - XHRPOST 56 - https://flushing.im/api/bluesky/flushing 57 - [HTTP/2 401 63ms] 58 - 59 - Status creation error: 60 - Object { error: "use_dpop_nonce", nonce: "Cu3Gn9OQuKUyKfqV9bGK0pqqeHPvm-tWhsvc9-6cmkA", originalError: {…} } 61 - 117-89c59c874aec3528.js:1:4081 62 - Received DPoP nonce error, retrying with nonce: Cu3Gn9OQuKUyKfqV9bGK0pqqeHPvm-tWhsvc9-6cmkA 481-d3c58c35fd99af50.js:1:5620 63 - Creating flushing status (attempt 3/3) with nonce: Cu3Gn9OQuKUyKfqV9bGK0pqqeHPvm-tWhsvc9-6cmkA 481-d3c58c35fd99af50.js:1:4526 64 - Using PDS endpoint: https://enoki.us-east.host.bsky.network 481-d3c58c35fd99af50.js:1:4608 65 - API endpoint: https://enoki.us-east.host.bsky.network/xrpc/com.atproto.repo.createRecord 481-d3c58c35fd99af50.js:1:4985 66 - Generating DPoP token for: https://enoki.us-east.host.bsky.network/xrpc/com.atproto.repo.createRecord with nonce: Cu3Gn9OQuKUyKfqV9bGK0pqqeHPvm-tWhsvc9-6cmkA 481-d3c58c35fd99af50.js:1:5050 67 - Sending request to proxy API... 481-d3c58c35fd99af50.js:1:5174 39 + Creating flushing status (attempt 1/3) with nonce: null 481-38cee1d3cffbeb60.js:1:4530 40 + Using PDS endpoint: https://enoki.us-east.host.bsky.network 481-38cee1d3cffbeb60.js:1:4612 41 + API endpoint: https://enoki.us-east.host.bsky.network/xrpc/com.atproto.repo.createRecord 481-38cee1d3cffbeb60.js:1:4989 42 + Generating DPoP token for: https://enoki.us-east.host.bsky.network/xrpc/com.atproto.repo.createRecord with nonce: none 481-38cee1d3cffbeb60.js:1:5054 43 + Including access token hash (ath) in DPoP token 481-38cee1d3cffbeb60.js:1:5122 44 + Adding ath claim to DPoP token 481-38cee1d3cffbeb60.js:1:6994 45 + Sending request to proxy API... 481-38cee1d3cffbeb60.js:1:5243 68 46 XHRPOST 69 47 https://flushing.im/api/bluesky/flushing 70 - [HTTP/2 401 102ms] 48 + [HTTP/2 401 203ms] 71 49 72 50 Status creation error: 73 - Object { error: "use_dpop_nonce", nonce: "Cu3Gn9OQuKUyKfqV9bGK0pqqeHPvm-tWhsvc9-6cmkA", originalError: {…} } 74 - 117-89c59c874aec3528.js:1:4081 75 - Received DPoP nonce error, retrying with nonce: Cu3Gn9OQuKUyKfqV9bGK0pqqeHPvm-tWhsvc9-6cmkA 481-d3c58c35fd99af50.js:1:5620 76 - Failed to update status: Error: Maximum retry attempts reached. Could not create status after 3 attempts. 77 - NextJS 34 78 - 117-89c59c874aec3528.js:1:4081 51 + Object { error: "use_dpop_nonce", nonce: "nceSKdZmf25ZbombMTLHUIw9I0Ss1PobvE6nqZOKAR0", originalError: {…} } 52 + 117-9a2b9731dac7965d.js:1:4081 53 + NextJS 32 54 + Received DPoP nonce error, retrying with nonce: nceSKdZmf25ZbombMTLHUIw9I0Ss1PobvE6nqZOKAR0 481-38cee1d3cffbeb60.js:1:5689 55 + Creating flushing status (attempt 2/3) with nonce: nceSKdZmf25ZbombMTLHUIw9I0Ss1PobvE6nqZOKAR0 481-38cee1d3cffbeb60.js:1:4530 56 + Using PDS endpoint: https://enoki.us-east.host.bsky.network 481-38cee1d3cffbeb60.js:1:4612 57 + API endpoint: https://enoki.us-east.host.bsky.network/xrpc/com.atproto.repo.createRecord 481-38cee1d3cffbeb60.js:1:4989 58 + Generating DPoP token for: https://enoki.us-east.host.bsky.network/xrpc/com.atproto.repo.createRecord with nonce: nceSKdZmf25ZbombMTLHUIw9I0Ss1PobvE6nqZOKAR0 481-38cee1d3cffbeb60.js:1:5054 59 + Including access token hash (ath) in DPoP token 481-38cee1d3cffbeb60.js:1:5122 60 + Adding ath claim to DPoP token 481-38cee1d3cffbeb60.js:1:6994 61 + Sending request to proxy API... 481-38cee1d3cffbeb60.js:1:5243 62 + Status update successful! 481-38cee1d3cffbeb60.js:1:5492 63 + Status update result: 64 + Object { uri: "at://did:plc:gq4fo3u6tqzzdkjlwzpb23tj/im.flushing.right.now/3ljt6tf5x4l2h", cid: "bafyreihsj6n5u72js5zfibc56ng2qpmglrljmjfx7aabyr3sogwwx5jm4q", commit: {…}, validationStatus: "unknown" } 65 + page-1f5ea258c75e5bac.js:1:1763