# React SDK — Authentication

> The useAuth hook — sign up, log in, log out, and read the current user in React. Full authentication API from @aerostack/react.

The `useAuth` hook provides the full authentication API. Import it from `@aerostack/react`.

```tsx

```

## Auth state

```ts
const {
  user,            // User | null
  tokens,          // { accessToken, refreshToken?, expiresAt? } | null
  loading,         // boolean — any auth operation in progress
  error,           // string | null — last error message
  isAuthenticated, // boolean — shorthand for !!tokens?.accessToken
} = useAuth()
```

### `User` type

```ts
interface User {
  id: string
  email: string
  name?: string
  avatar_url?: string
  emailVerified: boolean
  createdAt?: string
  customFields?: Record<string, any>
}
```

---

## Methods

### `signIn(email, password, turnstileToken?)`

Sign in with email and password. Sets `user` and `tokens` on success.

```ts
await signIn('user@example.com', 'password')
// or with Turnstile bot protection:
await signIn('user@example.com', 'password', turnstileToken)
```

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `email` | `string` | Yes | User's email address |
| `password` | `string` | Yes | User's password |
| `turnstileToken` | `string` | No | Cloudflare Turnstile token |

**Returns:** `Promise` — `{ user, accessToken, refreshToken }`

---

### `signUp(email, password, opts?)`

Register a new user. If email verification is enabled, `requiresVerification: true` is returned.

```ts
const result = await signUp('user@example.com', 'password', {
  name: 'Jane Doe',
  customFields: { plan: 'free' },
  turnstileToken: token,
})

if (result.requiresVerification) {
  // Show "check your email" message
}
```

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `email` | `string` | Yes | New user's email |
| `password` | `string` | Yes | New user's password |
| `opts.name` | `string` | No | Display name |
| `opts.customFields` | `Record<string, any>` | No | Custom profile fields |
| `opts.turnstileToken` | `string` | No | Bot protection token |

---

### `signOut()`

Sign out the current user. Invalidates the refresh token server-side and clears local state.

```ts
await signOut()
// user and tokens are now null
```

---

### `sendOTP(identifier, type?)`

Send a one-time code to an email address or phone number.

```ts
await sendOTP('user@example.com', 'email')
await sendOTP('+1234567890', 'phone')
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `identifier` | `string` | — | Email or phone number |
| `type` | `'email' \| 'phone'` | `'email'` | Delivery method |

---

### `verifyOTP(identifier, code, type?)`

Verify the OTP code and sign in. Sets `user` and `tokens` on success.

```ts
await verifyOTP('user@example.com', '123456', 'email')
```

| Parameter | Type | Default |
|-----------|------|---------|
| `identifier` | `string` | — |
| `code` | `string` | — |
| `type` | `'email' \| 'phone'` | `'email'` |

---

### `verifyEmail(token)`

Verify the email address using the token from the verification email link.

```ts
// In your /verify-email page
const token = new URLSearchParams(window.location.search).get('token')
await verifyEmail(token)
```

---

### `resendVerificationEmail(email)`

Resend the email verification link.

```ts
await resendVerificationEmail('user@example.com')
```

---

### `requestPasswordReset(email, turnstileToken?)`

Send a password reset email.

```ts
await requestPasswordReset('user@example.com')
```

---

### `resetPassword(token, newPassword)`

Set a new password using the token from the reset email.

```ts
const token = new URLSearchParams(window.location.search).get('token')
await resetPassword(token, 'newSecurePassword123')
```

---

### `refreshAccessToken(refreshToken)`

Refresh the access token. Called automatically by the SDK on 401 responses, but can also be called manually.

```ts
const newTokens = await refreshAccessToken(tokens.refreshToken)
```

---

### `refreshUser()`

Re-fetch the current user's profile and update local state.

```ts
await refreshUser()
// user state is updated from the server
```

---

### `updateProfile(updates)`

Update the current user's profile. Calls `refreshUser()` automatically.

```ts
await updateProfile({
  name: 'New Name',
  avatar_url: 'https://cdn.example.com/avatar.jpg',
  customFields: { plan: 'pro' },
})
```

| Parameter | Type | Description |
|-----------|------|-------------|
| `name` | `string` | Display name |
| `avatar_url` | `string` | Avatar URL |
| `avatar_image_id` | `string` | Storage image ID (auto-resolves to URL) |
| `customFields` | `Record<string, any>` | Merge into existing custom fields |

---

### `deleteAvatar()`

Remove the current user's avatar.

```ts
await deleteAvatar()
```

---

## Error handling

All methods throw on failure. The error message is also set in `error` state:

```tsx
const { signIn, error, loading } = useAuth()

const handleSubmit = async () => {
  try {
    await signIn(email, password)
  } catch (err) {
    // err.message is the same as error state
    console.error(err.message)
  }
}

// Or use the error state directly:
{error && <p style={{ color: 'red' }}>{error}</p>}
```
