A social knowledge tool for researchers built on ATProto
1import type { GetProfileResponse } from '@/api-client/ApiClient';
2import { cache } from 'react';
3
4const appUrl = process.env.NEXT_PUBLIC_APP_URL || 'http://127.0.0.1:4000';
5
6// Flag-based approach to prevent concurrent auth requests
7let isRefreshing = false;
8let refreshPromise: Promise<GetProfileResponse | null> | null = null;
9
10export const verifySessionOnClient = cache(
11 async (): Promise<GetProfileResponse | null> => {
12 if (isRefreshing && refreshPromise) {
13 console.log('Auth refresh already in progress, waiting...');
14 return refreshPromise;
15 }
16
17 isRefreshing = true;
18 refreshPromise = (async () => {
19 try {
20 const response = await fetch(`${appUrl}/api/auth/me`, {
21 method: 'GET',
22 credentials: 'include', // HttpOnly cookies sent automatically
23 });
24
25 if (!response.ok) {
26 return null;
27 }
28
29 const { user }: { user: GetProfileResponse } = await response.json();
30
31 return user;
32 } finally {
33 isRefreshing = false;
34 refreshPromise = null;
35 }
36 })();
37
38 return refreshPromise;
39 },
40);