> ## Documentation Index
> Fetch the complete documentation index at: https://usegately.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Session Management

> Manage user sessions and authentication state

The Gately SDK handles session management automatically, including storage, refresh, and state synchronization.

## Check Authentication

```javascript theme={null}
// Check if user is logged in
if (gately.isAuthenticated()) {
  console.log('User is logged in')
}
```

## Get Current User

```javascript theme={null}
const user = gately.getUser()

if (user) {
  console.log('Email:', user.email)
  console.log('Name:', user.full_name)
  console.log('Plan:', user.plan_id)
}
```

### User Object

```typescript theme={null}
interface User {
  id: string
  email: string
  full_name: string | null
  avatar_url: string | null
  plan_id: string
  status: 'active' | 'inactive' | 'pending'
  metadata: Record<string, any>
  created_at: string
  last_login_at: string | null
}
```

## Get Session

```javascript theme={null}
const session = gately.getSession()

if (session) {
  console.log('Access token:', session.access_token)
  console.log('Expires at:', new Date(session.expires_at))
}
```

### Session Object

```typescript theme={null}
interface Session {
  access_token: string
  refresh_token: string
  expires_at: number  // Unix timestamp in milliseconds
  user: User
}
```

## Listen for Auth Changes

```javascript theme={null}
gately.onAuthStateChange((user, session) => {
  if (user) {
    console.log('User logged in:', user.email)
    // Update UI, redirect, etc.
  } else {
    console.log('User logged out')
    // Clear UI, redirect to login, etc.
  }
})
```

### React Hook

```jsx theme={null}
import { useAuth } from '@gately/sdk'

function AuthStatus() {
  const { user, isAuthenticated, isLoading } = useAuth()

  if (isLoading) {
    return <Spinner />
  }

  if (!isAuthenticated) {
    return <Link to="/login">Log In</Link>
  }

  return <span>Welcome, {user.email}</span>
}
```

## Refresh Session

Sessions are automatically refreshed before expiry. You can also manually refresh:

```javascript theme={null}
const session = await gately.fetchSession()

if (session) {
  console.log('Session refreshed')
} else {
  console.log('Session expired, user logged out')
}
```

## Session Storage

Sessions are stored in:

1. **localStorage**: `gately_session_{projectId}`
2. **Cookies**: `gately_auth_token`, `gately_project_id`

### Why Both?

* localStorage: Primary storage, survives page reloads
* Cookies: Enables cross-origin requests (e.g., Framer fetch)

## Session Expiry

| Token         | Expiry |
| ------------- | ------ |
| Access Token  | 1 hour |
| Refresh Token | 7 days |

When the access token expires:

1. SDK automatically uses refresh token
2. New access token is obtained
3. Session is updated in storage

When the refresh token expires:

1. User is logged out
2. Session is cleared
3. Auth state callbacks are triggered

## Auto Refresh

Auto refresh is enabled by default:

```javascript theme={null}
const gately = new GatelyClient('project-id', {
  autoRefresh: true  // Default
})
```

The SDK refreshes the session 5 minutes before expiry.

To disable:

```javascript theme={null}
const gately = new GatelyClient('project-id', {
  autoRefresh: false
})
```

## Logout

```javascript theme={null}
await gately.logout()
```

This will:

1. Call the logout API endpoint
2. Clear localStorage
3. Clear cookies
4. Trigger auth state callbacks
5. Handle redirect (if configured)

## Session Persistence

Sessions persist across:

* Page reloads
* Browser tabs (same origin)
* Browser restarts (until expiry)

Sessions do NOT persist across:

* Different browsers
* Incognito/private mode
* Cleared browser data

## Multiple Tabs

The SDK handles multiple tabs gracefully:

```javascript theme={null}
// Tab 1: User logs out
await gately.logout()

// Tab 2: Detects logout via storage event
// Auth state callback is triggered
```

## Server-Side Rendering

For SSR frameworks (Next.js, etc.):

```javascript theme={null}
// Check if running in browser
if (typeof window !== 'undefined') {
  const user = gately.getUser()
}

// Or use the hook (handles SSR automatically)
const { user, isLoading } = useAuth()
```

## Security Considerations

<AccordionGroup>
  <Accordion title="Token Storage">
    Tokens are stored in localStorage and cookies. For high-security applications, consider additional measures like HTTP-only cookies (requires server-side setup).
  </Accordion>

  <Accordion title="XSS Protection">
    Never expose tokens in URLs or log them to console in production.
  </Accordion>

  <Accordion title="CSRF Protection">
    The SDK uses SameSite cookies and validates the origin of requests.
  </Accordion>
</AccordionGroup>

## Debugging

Enable debug mode to see session operations:

```javascript theme={null}
// In browser console
localStorage.setItem('gately_debug', 'true')
location.reload()
```

This logs:

* Session save/restore operations
* Token refresh attempts
* Auth state changes
