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

# Authentication

> Secure your API requests with authentication

## Overview

FoN uses three distinct authentication mechanisms, depending on the endpoint you're calling. Most endpoints rely on a session cookie, a small set of token-management endpoints accept a JWT Bearer token, and uploads via the v1 API accept a long-lived API token.

| Mechanism                         | How it's sent                       | Used by                                                                                            |
| --------------------------------- | ----------------------------------- | -------------------------------------------------------------------------------------------------- |
| **Session Cookie** (`auth-token`) | `Cookie: auth-token=<jwt>`          | Almost everything: voting, tags, profile, uploads (non-v1), MFA, password management, logout, etc. |
| **JWT Bearer Token**              | `Authorization: Bearer <jwt>`       | Only `/api/auth/tokens`, `/api/auth/tokens/generate`, and `/api/auth/tokens/{id}`                  |
| **API Token**                     | `Authorization: Bearer <api_token>` | Only `/api/v1/upload`                                                                              |

## Authentication Methods

### Session Cookies

When you log in (or complete an OAuth flow), the API sets a secure HTTP-only cookie named `auth-token` containing a JWT, valid for 24 hours. This cookie is automatically sent by browsers with subsequent requests, and is what the vast majority of endpoints check via `getCookie(event, 'auth-token')`.

<Note>
  Session cookies are automatically managed by the browser. For non-browser clients (scripts, curl, etc.), you can authenticate the same way by sending the JWT from the login response as a cookie: `Cookie: auth-token=YOUR_JWT_TOKEN`.
</Note>

#### Log In

```bash theme={null}
curl -X POST https://fucksornot.com/api/auth \
  -H "Content-Type: application/json" \
  -d '{
    "action": "login",
    "email": "you@example.com",
    "password": "your_password"
  }'
```

**Response:**

```json theme={null}
{
  "user": {
    "id": "uuid",
    "username": "yourname",
    "email": "you@example.com"
  },
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "mfaRequired": false
}
```

#### Use the Session Cookie

Send the `token` value from the login response as the `auth-token` cookie on subsequent requests to session-based endpoints:

```bash theme={null}
curl https://fucksornot.com/api/profile \
  -H "Cookie: auth-token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
```

### JWT Bearer Tokens

The same JWT returned from login can also be passed as a Bearer token, but only for the token-management endpoints (`/api/auth/tokens`, `/api/auth/tokens/generate`, and `/api/auth/tokens/{id}`). These endpoints are how you generate and manage long-lived API tokens.

```bash theme={null}
curl https://fucksornot.com/api/auth/tokens \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
```

### API Tokens

API tokens are long-lived, raw 64-character hex strings designed for programmatic access. They're ideal for scripts, bots, and integrations, and are accepted only by `/api/v1/upload`.

#### Generate a Token

```bash theme={null}
curl -X POST https://fucksornot.com/api/auth/tokens/generate \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Upload Script"}'
```

**Response:**

```json theme={null}
{
  "id": "token-uuid",
  "token": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2",
  "name": "Upload Script",
  "expiresAt": "2026-01-24T00:00:00Z"
}
```

<Warning>
  Store your API token securely. It's only displayed once and cannot be retrieved later.
</Warning>

#### Use the Token

```bash theme={null}
curl -X POST https://fucksornot.com/api/v1/upload \
  -H "Authorization: Bearer a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2" \
  -F "upload_type=image" \
  -F "description=My upload" \
  -F "file=@image.jpg"
```

#### Revoke a Token

```bash theme={null}
curl -X DELETE https://fucksornot.com/api/auth/tokens/TOKEN_ID \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
```

### OAuth

FoN supports OAuth authentication with:

* Google
* Apple
* Meta (Facebook)

OAuth flows are handled through the web interface. After successful OAuth authentication, a session is established with a JWT token.

## Multi-Factor Authentication (MFA)

For enhanced security, enable MFA on your account.

### Setup MFA

```bash theme={null}
curl -X POST https://fucksornot.com/api/auth/mfa/setup \
  -H "Cookie: auth-token=YOUR_JWT_TOKEN"
```

**Response:**

```json theme={null}
{
  "qrCode": "data:image/png;base64,...",
  "secret": "JBSWY3DPEHPK3PXP",
  "otpauthUrl": "otpauth://totp/FoN:you@example.com?secret=JBSWY3DPEHPK3PXP&issuer=FoN",
  "backupCodes": [
    "A1B2-C3D4-E5F6-A7B8",
    "B2C3-D4E5-F6A7-B8C9",
    "C3D4-E5F6-A7B8-C9D0",
    "D4E5-F6A7-B8C9-D0E1",
    "E5F6-A7B8-C9D0-E1F2",
    "F6A7-B8C9-D0E1-F2A3",
    "A7B8-C9D0-E1F2-A3B4",
    "B8C9-D0E1-F2A3-B4C5",
    "C9D0-E1F2-A3B4-C5D6",
    "D0E1-F2A3-B4C5-D6E7"
  ]
}
```

<Steps>
  <Step title="Scan QR Code">
    Use an authenticator app (Google Authenticator, Authy, etc.) to scan the QR code
  </Step>

  <Step title="Verify Setup">
    Enter a code from your authenticator to verify setup:

    ```bash theme={null}
    curl -X POST https://fucksornot.com/api/auth/mfa/verify \
      -H "Cookie: auth-token=YOUR_JWT_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"mfaCode": "123456"}'
    ```
  </Step>

  <Step title="Save Backup Codes">
    Store your 10 backup codes securely. Each can be used once if you lose access to your authenticator.
  </Step>
</Steps>

### Login with MFA

When MFA is enabled, include the code in your login request:

```bash theme={null}
curl -X POST https://fucksornot.com/api/auth \
  -H "Content-Type: application/json" \
  -d '{
    "action": "login",
    "email": "you@example.com",
    "password": "your_password",
    "mfaCode": "123456"
  }'
```

## Password Management

### Change Password

This endpoint authenticates via the `auth-token` session cookie:

```bash theme={null}
curl -X POST https://fucksornot.com/api/auth/change-password \
  -H "Cookie: auth-token=YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "currentPassword": "old_password",
    "newPassword": "new_password",
    "confirmPassword": "new_password",
    "mfaCode": "123456"
  }'
```

### Reset Password

Request a password reset email:

```bash theme={null}
curl -X POST https://fucksornot.com/api/auth/forgot-password \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com"}'
```

Use the reset token from the email:

```bash theme={null}
curl -X POST https://fucksornot.com/api/auth/reset-password \
  -H "Content-Type: application/json" \
  -d '{
    "token": "reset_token_from_email",
    "password": "new_password",
    "mfaCode": "123456"
  }'
```

**Response:**

```json theme={null}
{
  "message": "Password has been reset successfully. You can now log in with your new password."
}
```

<Note>
  The `mfaCode` field is only required if MFA is enabled on the account.
</Note>

## Security Best Practices

<AccordionGroup>
  <Accordion title="Use API tokens for automation">
    API tokens are designed for programmatic access and can be revoked individually without affecting your main account.
  </Accordion>

  <Accordion title="Enable MFA">
    Multi-factor authentication adds an extra layer of security to your account.
  </Accordion>

  <Accordion title="Rotate tokens regularly">
    Periodically generate new API tokens and revoke old ones.
  </Accordion>

  <Accordion title="Never commit tokens to version control">
    Use environment variables or secret management tools to store tokens.
  </Accordion>
</AccordionGroup>
