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

# Authentication API

> Better Auth endpoints for login, registration, and session management

## Overview

Concordia uses **Better Auth** for authentication. All endpoints are automatically generated and handled through `/api/auth/[...all]`.

### Base Endpoint

```
POST /api/auth/*
```

All authentication flows use the Better Auth SDK, which provides type-safe client methods.

***

## Authentication Configuration

From `/src/lib/auth/auth.ts:53-133`:

```typescript theme={null}
const sharedConfig = {
  emailAndPassword: {
    enabled: true,
    requireEmailVerification: true,
  },
  session: {
    expiresIn: 60 * 60 * 24 * 7, // 7 days
    updateAge: 60 * 60 * 24, // 1 day
    freshAge: 60 * 10, // 10 minutes
    absoluteTimeout: 60 * 60 * 24 * 7, // 7 days
  },
  rateLimit: {
    enabled: true,
    storage: "database",
    windows: [
      { key: "global_ip", max: 100, window: 60 * 1000 },
      { key: "sign_in", max: 5, window: 15 * 60 * 1000 },
      { key: "sign_up", max: 10, window: 60 * 60 * 1000 },
    ],
  },
};
```

***

## Registration

### Sign Up

<CodeGroup>
  ```typescript Client SDK theme={null}
  import { authClient } from '@/lib/auth-client';

  const { data, error } = await authClient.signUp.email({
    email: 'user@example.com',
    password: 'SecurePass123!',
    name: 'John Doe',
    username: 'johndoe', // Optional
  });
  ```

  ```bash cURL theme={null}
  curl -X POST https://your-domain.com/api/auth/sign-up/email \
    -H "Content-Type: application/json" \
    -d '{
      "email": "user@example.com",
      "password": "SecurePass123!",
      "name": "John Doe",
      "username": "johndoe"
    }'
  ```
</CodeGroup>

### Validation Rules

From `/src/lib/auth/auth.ts:57-64`:

* **Email**: Required, valid email format
* **Password**:
  * Minimum 10 characters
  * At least 1 uppercase letter
  * At least 1 lowercase letter
  * At least 1 digit
  * At least 1 special character
* **Username**: Optional, alphanumeric with hyphens/underscores
* **Name**: Optional

### Post-Signup Actions

From `/src/lib/auth/auth.ts:196-266`, after successful signup:

1. **Profile created** with derived username
2. **Wallet initialized** (balance: 0.00 EUR)
3. **Default role assigned** (`citizen`)
4. **Audit log entry** created
5. **Verification email sent** (if SMTP configured)

### Response

```json theme={null}
{
  "user": {
    "id": "usr_abc123",
    "email": "user@example.com",
    "name": "John Doe",
    "emailVerified": false,
    "createdAt": "2024-03-03T10:00:00Z"
  },
  "session": null // Email verification required
}
```

***

## Email Verification

### Send Verification Email

<CodeGroup>
  ```typescript Client SDK theme={null}
  await authClient.sendVerificationEmail({
    email: 'user@example.com',
  });
  ```

  ```bash cURL theme={null}
  curl -X POST https://your-domain.com/api/auth/send-verification-email \
    -H "Content-Type: application/json" \
    -d '{"email": "user@example.com"}'
  ```
</CodeGroup>

### Verify Email

Users receive a verification link via email:

```
https://your-domain.com/verify-email?token=abc123...
```

The frontend calls:

```typescript theme={null}
await authClient.verifyEmail({
  token: 'abc123...',
});
```

***

## Login

### Sign In with Email/Password

<CodeGroup>
  ```typescript Client SDK theme={null}
  const { data, error } = await authClient.signIn.email({
    email: 'user@example.com',
    password: 'SecurePass123!',
  });
  ```

  ```bash cURL theme={null}
  curl -X POST https://your-domain.com/api/auth/sign-in/email \
    -H "Content-Type: application/json" \
    -d '{
      "email": "user@example.com",
      "password": "SecurePass123!"
    }'
  ```
</CodeGroup>

### Rate Limiting

From `/src/lib/auth/auth.ts:372-389`:

* **Max attempts**: 5 failed logins per email
* **Window**: 15 minutes
* **Error**: `"Too many login attempts"` (HTTP 429)

### Response

```json theme={null}
{
  "user": {
    "id": "usr_abc123",
    "email": "user@example.com",
    "name": "John Doe",
    "emailVerified": true
  },
  "session": {
    "id": "ses_xyz789",
    "userId": "usr_abc123",
    "expiresAt": "2024-03-10T10:00:00Z"
  }
}
```

### Audit Logging

From `/src/lib/auth/auth.ts:290-306`, successful logins are logged:

```typescript theme={null}
await db.insert(auditLog).values({
  action: "login_success",
  userId: session.userId,
  ip: extractedIP,
  userAgent: userAgent,
  data: { sessionId: session.id },
});
```

Failed logins also logged (`login_failed`).

***

## Session Management

### Get Current Session

<CodeGroup>
  ```typescript Client SDK theme={null}
  const { data: session } = await authClient.getSession();
  ```

  ```bash cURL theme={null}
  curl https://your-domain.com/api/auth/get-session \
    -H "Cookie: astro_session=..." \
    # Or with Bearer token:
    -H "Authorization: Bearer <token>"
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "session": {
    "id": "ses_xyz789",
    "userId": "usr_abc123",
    "expiresAt": "2024-03-10T10:00:00Z",
    "activeOrganizationId": "org_123"
  },
  "user": {
    "id": "usr_abc123",
    "email": "user@example.com",
    "name": "John Doe",
    "emailVerified": true
  }
}
```

### Session Configuration

From `/src/lib/auth/auth.ts:93-103`:

<ParamField body="expiresIn" type="number" default="604800">
  Session lifetime (7 days in seconds)
</ParamField>

<ParamField body="updateAge" type="number" default="86400">
  Session refresh interval (1 day)
</ParamField>

<ParamField body="cookieCache.maxAge" type="number" default="300">
  Cookie cache duration (5 minutes)
</ParamField>

<ParamField body="freshAge" type="number" default="600">
  Fresh session window (10 minutes)
</ParamField>

<ParamField body="absoluteTimeout" type="number" default="604800">
  Maximum session lifetime (7 days)
</ParamField>

***

## Logout

### Sign Out

<CodeGroup>
  ```typescript Client SDK theme={null}
  await authClient.signOut();
  ```

  ```bash cURL theme={null}
  curl -X POST https://your-domain.com/api/auth/sign-out \
    -H "Cookie: astro_session=..." \
    -H "Authorization: Bearer <token>" # If using bearer token
  ```
</CodeGroup>

From `/src/lib/auth/auth.ts:338-346`, Bearer tokens are invalidated on logout:

```typescript theme={null}
const origSignOut = (instance.api as any).signOut;
(instance.api as any).signOut = async (opts: any) => {
  const hdr = opts?.headers?.authorization;
  if (hdr && hdr.startsWith('Bearer ')) {
    invalidatedTokens.add(hdr.slice(7)); // Blacklist token
  }
  return await origSignOut(opts);
};
```

***

## Password Reset

### Request Password Reset

<CodeGroup>
  ```typescript Client SDK theme={null}
  await authClient.forgetPassword({
    email: 'user@example.com',
    redirectTo: 'https://your-domain.com/reset-password',
  });
  ```

  ```bash cURL theme={null}
  curl -X POST https://your-domain.com/api/auth/forget-password \
    -H "Content-Type: application/json" \
    -d '{
      "email": "user@example.com",
      "redirectTo": "https://your-domain.com/reset-password"
    }'
  ```
</CodeGroup>

### Email Sent

From `/src/lib/auth/auth.ts:65-76`, users receive an email with reset link:

```html theme={null}
<p>Click the following link to reset your password:</p>
<p><a href="{resetUrl}">{resetUrl}</a></p>
```

### Reset Password

<CodeGroup>
  ```typescript Client SDK theme={null}
  await authClient.resetPassword({
    token: 'reset_token_123',
    password: 'NewSecurePass123!',
  });
  ```

  ```bash cURL theme={null}
  curl -X POST https://your-domain.com/api/auth/reset-password \
    -H "Content-Type: application/json" \
    -d '{
      "token": "reset_token_123",
      "password": "NewSecurePass123!"
    }'
  ```
</CodeGroup>

***

## Organization Authentication

### Set Active Organization

<CodeGroup>
  ```typescript Client SDK theme={null}
  await authClient.organization.setActive({
    organizationId: 'org_123',
  });
  ```

  ```bash cURL theme={null}
  curl -X POST https://your-domain.com/api/auth/organization/set-active \
    -H "Content-Type: application/json" \
    -H "Cookie: astro_session=..." \
    -d '{"organizationId": "org_123"}'
  ```
</CodeGroup>

From `/src/lib/auth/auth.ts:319`, this is mapped to:

```typescript theme={null}
setActive: (payload: any) => (instance.api as any).setActiveOrganization(payload)
```

### List User Organizations

```typescript theme={null}
const { data } = await authClient.organization.list();
```

### Response

```json theme={null}
[
  {
    "id": "org_123",
    "name": "My Organization",
    "slug": "my-org",
    "role": "owner"
  }
]
```

***

## Security Features

### IP Tracking

From `/src/lib/auth/auth.ts:16-23`, IPs are extracted from:

```typescript theme={null}
function extractIP(ctx: any): string | null {
  return (
    ctx?.request?.headers?.get("x-real-ip") ||
    ctx?.request?.headers?.get("x-forwarded-for") ||
    ctx?.request?.headers?.get("cf-connecting-ip") ||
    null
  );
}
```

### Secure Cookies

From `/src/lib/auth/auth.ts:179-183`:

```typescript theme={null}
advanced: {
  useSecureCookies: true,
  cookiePrefix: "astro_",
  crossSubDomainCookies: { enabled: false },
}
```

### CSRF Protection

* CSRF checks enabled by default
* Trusted origins configured via `BETTER_AUTH_URL`

***

## Error Responses

### Common Errors

| Status | Error                 | Description                        |
| ------ | --------------------- | ---------------------------------- |
| 400    | `invalid_input`       | Invalid email/password format      |
| 400    | `weak_password`       | Password doesn't meet requirements |
| 401    | `invalid_credentials` | Wrong email/password               |
| 401    | `email_not_verified`  | Email verification required        |
| 403    | `forbidden`           | Access denied                      |
| 429    | `too_many_requests`   | Rate limit exceeded                |
| 500    | `internal_error`      | Server error                       |

### Example

```json theme={null}
{
  "message": "Invalid credentials",
  "status": "UNAUTHORIZED"
}
```

***

## Related Resources

<CardGroup cols={2}>
  <Card title="API Overview" icon="globe" href="/development/api/overview">
    Rate limiting and authentication basics
  </Card>

  <Card title="Better Auth Docs" icon="arrow-up-right-from-square" href="https://www.better-auth.com/docs">
    Official Better Auth documentation
  </Card>
</CardGroup>
