Sifa professional network frontend (Next.js, React, TailwindCSS)
sifa.id/
1const API_URL = process.env.NEXT_PUBLIC_API_URL ?? 'http://localhost:3100';
2
3export interface AuthSession {
4 did: string;
5 handle: string;
6 displayName?: string;
7 avatar?: string;
8 isNewUser?: boolean;
9}
10
11export type SessionResult =
12 | { status: 'authenticated'; session: AuthSession }
13 | { status: 'unauthenticated' }
14 | { status: 'unavailable' }; // transient error — keep showing cached session
15
16export async function getSession(): Promise<SessionResult> {
17 try {
18 const res = await fetch(`${API_URL}/api/auth/session`, {
19 credentials: 'include',
20 cache: 'no-store',
21 });
22 if (res.status === 503) {
23 return { status: 'unavailable' };
24 }
25 if (!res.ok) {
26 return { status: 'unauthenticated' };
27 }
28 const data = await res.json();
29 if (!data.authenticated || !data.did || !data.handle) {
30 return { status: 'unauthenticated' };
31 }
32 return { status: 'authenticated', session: data };
33 } catch {
34 // Network error (API completely down) — treat as transient
35 return { status: 'unavailable' };
36 }
37}
38
39export function getLoginUrl(): string {
40 return '/login';
41}
42
43export function getOAuthLoginUrl(): string {
44 return `${API_URL}/oauth/login`;
45}
46
47export function getOAuthSignupUrl(): string {
48 return `${API_URL}/oauth/signup`;
49}
50
51export async function logout(): Promise<void> {
52 await fetch(`${API_URL}/oauth/logout`, {
53 method: 'POST',
54 credentials: 'include',
55 });
56}