> For the complete documentation index, see [llms.txt](https://trident-cas.sabn.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://trident-cas.sabn.xyz/api/profile.md).

# Profile

### Overview

This document provides API documentation for the profile routes.. These routes handle user profile management, notifications, vault operations, and user settings.

**Base Path**: `/profile`

**Authentication**: The user must be logged in to access protected endpoints.

***

### Endpoints

#### 1. GET `/profile/notifications`

Get all notifications for the authenticated user.

**Authentication**: Required

**Response**

Returns an array of notification objects.

```typescript
Array<{
    title: string;
    message: string;
    date: number;
}>;
```

**Success Response (200)**:

```json
[
    {
        "title": "Welcome",
        "message": "Welcome to Buzzed Casino!",
        "date": 1703001234567
    }
]
```

**Error Responses**:

* `401 Unauthorized`: User is not authenticated
* `400 Bad Request`: User not found
* `500 Internal Server Error`: Server error

***

#### 2. DELETE `/profile/notifications`

Clear all notifications for the authenticated user.

**Authentication**: Required

**Response**

**Success Response (200)**:

```json
{
    "success": true
}
```

**Error Responses**:

* `401 Unauthorized`: User is not authenticated
* `400 Bad Request`: User not found
* `500 Internal Server Error`: Server error

***

#### 3. GET `/profile/user/:id`

Get public user data by Steam ID.

**Authentication**: Not required (public endpoint)

**Parameters**

* `id` (path parameter): Steam ID of the user

**Response**

**Success Response (200)**:

```json
{
    "status": true,
    "user": {
        "steamid": "76561198123456789",
        "username": "PlayerName",
        "avatar": "https://avatars.steamstatic.com/...",
        "experience": 5000,
        "level": 5,
        "registerDate": 1703001234567
    }
}
```

**Error Responses**:

* `404 Not Found`: User not found

```json
{
    "status": false,
    "error": "User not found"
}
```

* `500 Internal Server Error`: Server error

***

#### 4. POST `/profile/vault/lock`

Lock coins in the vault with a deadline. This moves coins from the user's balance to their vault balance and sets a lock deadline.

**Authentication**: Required

**Request Body**

```json
{
    "amount": 1000,
    "deadline": 1703001234567
}
```

* `amount` (number, required): Amount of coins to lock (must be positive)
* `deadline` (number, required): Unix timestamp in milliseconds when the vault will unlock (must be in the future)

**Response**

**Success Response (200)**:

```json
{
    "success": true
}
```

**Error Responses**:

* `401 Unauthorized`: User is not authenticated
* `400 Bad Request`: Invalid parameters

```json
{
    "error": "Amount and deadline are required"
}
// or
{
    "error": "Invalid amount"
}
// or
{
    "error": "Invalid deadline"
}
```

* `500 Internal Server Error`: Server error

***

#### 5. POST `/profile/vault/unlock`

Unlock coins from the vault. This moves coins from the vault balance back to the user's regular balance.

**Authentication**: Required

**Request Body**

No body required.

**Response**

**Success Response (200)**:

```json
{
    "success": true
}
```

**Error Responses**:

* `401 Unauthorized`: User is not authenticated
* `400 Bad Request`: Cannot unlock vault

```json
{
    "error": "User not found"
}
// or
{
    "error": "Vault is empty"
}
// or
{
    "error": "Vault is still locked"
}
```

* `500 Internal Server Error`: Server error

***

#### 6. PUT `/profile/trade-url`

Set or update the user's Steam trade URL.

**Authentication**: Required

**Request Body**

```json
{
    "url": "https://steamcommunity.com/tradeoffer/new/?partner=123456789&token=ABCDEFGH"
}
```

* `url` (string, required): Steam trade URL (must start with `https://steamcommunity.com/tradeoffer/new/?partner`)

**Response**

**Success Response (200)**:

```json
{
    "success": true
}
```

**Error Responses**:

* `401 Unauthorized`: User is not authenticated
* `400 Bad Request`: Invalid trade URL

```json
{
    "error": "Trade URL is required"
}
// or
{
    "error": "Invalid trade URL"
}
```

* `500 Internal Server Error`: Server error

***

#### 7. POST `/profile/avatar`

Upload a user profile picture.

**Authentication**: Required

**Request Body (multipart/form-data)**

* `avatar` (file, required): Image file (JPEG, PNG, WEBP, GIF, max 2MB)

**Response**

**Success Response (200)**:

```json
{
    "success": true,
    "avatarUrl": "https://api.example.com/uploads/avatars/uuid-1234.png"
}
```

**Error Responses**:

* `400 Bad Request`: File size exceeds limit, invalid file type, or no file uploaded
* `401 Unauthorized`: User is not authenticated
* `500 Internal Server Error`: Server error

***

#### 8. PUT `/profile/client-seed`

Update provably-fair client seed.

**Authentication**: Required

**Request Body**

```json
{
    "clientSeed": "my-new-seed-123"
}
```

* `clientSeed` (string, required): Alphanumeric string with dashes/underscores, 4-64 characters.

**Response**

**Success Response (200)**:

```json
{
    "success": true
}
```

**Error Responses**:

* `400 Bad Request`: Validation error on `clientSeed`
* `401 Unauthorized`: User is not authenticated
* `500 Internal Server Error`: Server error

***

#### 9. GET `/profile/details`

Get personal info and shipping address.

**Authentication**: Required

**Response**

**Success Response (200)**:

```json
{
    "success": true,
    "data": {
        "username": "Player123",
        "firstName": "John",
        "lastName": "Doe",
        "phone": "+1234567890",
        "shippingAddress": {
            "addressLine1": "123 Main St",
            "addressLine2": "Apt 4B",
            "city": "New York",
            "zipCode": "10001",
            "state": "NY",
            "country": "USA"
        }
    }
}
```

**Error Responses**:

* `401 Unauthorized`: User is not authenticated
* `500 Internal Server Error`: Server error

***

#### 10. PUT `/profile/details`

Update personal info and shipping address.

**Authentication**: Required

**Request Body**

All fields are optional.

```json
{
    "username": "NewPlayer123",
    "firstName": "John",
    "lastName": "Doe",
    "phone": "+1234567890",
    "shippingAddress": {
        "addressLine1": "123 Main St",
        "addressLine2": "Apt 4B",
        "city": "New York",
        "zipCode": "10001",
        "state": "NY",
        "country": "USA"
    }
}
```

**Response**

**Success Response (200)**:

```json
{
    "success": true
}
```

**Error Responses**:

* `400 Bad Request`: Validation errors or username already taken
* `401 Unauthorized`: User is not authenticated
* `500 Internal Server Error`: Server error

***

#### 11. GET `/profile/2fa/status`

Get the current two-factor authentication (2FA) status.

**Authentication**: Required

**Response**

**Success Response (200)**:

```json
{
    "success": true,
    "enabled": false
}
```

**Error Responses**:

* `401 Unauthorized`: User is not authenticated
* `500 Internal Server Error`: Server error

***

#### 12. POST `/profile/2fa/setup`

Generate a 2FA secret and a QR code for initial setup.

**Authentication**: Required

**Response**

**Success Response (200)**:

```json
{
    "success": true,
    "secret": "JBSWY3DPEHPK3PXP",
    "qrCode": "data:image/png;base64,..."
}
```

**Error Responses**:

* `400 Bad Request`: 2FA is already enabled
* `401 Unauthorized`: User is not authenticated
* `500 Internal Server Error`: Server error

***

#### 13. POST `/profile/2fa/enable`

Enable 2FA by verifying the setup code.

**Authentication**: Required

**Request Body**

```json
{
    "code": "123456"
}
```

* `code` (string, required): The 6-digit code generated by the authenticator app.

**Response**

**Success Response (200)**:

```json
{
    "success": true,
    "message": "2FA enabled successfully"
}
```

**Error Responses**:

* `400 Bad Request`: Invalid verification code or setup not initiated
* `401 Unauthorized`: User is not authenticated
* `500 Internal Server Error`: Server error

***

#### 14. POST `/profile/2fa/disable`

Disable 2FA using a verification code.

**Authentication**: Required

**Request Body**

```json
{
    "code": "123456"
}
```

* `code` (string, required): The 6-digit code generated by the authenticator app.

**Response**

**Success Response (200)**:

```json
{
    "success": true,
    "message": "2FA disabled successfully"
}
```

**Error Responses**:

* `400 Bad Request`: Invalid verification code or 2FA is not enabled
* `401 Unauthorized`: User is not authenticated
* `500 Internal Server Error`: Server error

***

### Usage Examples

#### Frontend Integration

**Get Notifications**

```javascript
const getNotifications = async () => {
    try {
        const response = await fetch("http://localhost:4000/profile/notifications", {
            method: "GET",
            headers: { "Authorization": `Bearer ${token}` }
        });

        if (!response.ok) {
            throw new Error("Failed to fetch notifications");
        }

        const notifications = await response.json();
        return notifications;
    } catch (error) {
        console.error("Error fetching notifications:", error);
        return [];
    }
};
```

**Clear Notifications**

```javascript
const clearNotifications = async () => {
    try {
        const response = await fetch("http://localhost:4000/profile/notifications", {
            method: "DELETE",
            credentials: "include",
        });

        if (!response.ok) {
            throw new Error("Failed to clear notifications");
        }

        const result = await response.json();
        return result.success;
    } catch (error) {
        console.error("Error clearing notifications:", error);
        return false;
    }
};
```

**Get Public User**

```javascript
const getPublicUser = async steamId => {
    try {
        const response = await fetch(`http://localhost:4000/profile/user/${steamId}`, {
            method: "GET",
        });

        if (!response.ok) {
            throw new Error("Failed to fetch user");
        }

        const result = await response.json();
        return result;
    } catch (error) {
        console.error("Error fetching user:", error);
        return { status: false, error: "User not found" };
    }
};
```

**Lock Coins in Vault**

```javascript
const lockCoins = async (amount, deadline) => {
    try {
        const response = await fetch("http://localhost:4000/profile/vault/lock", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            credentials: "include",
            body: JSON.stringify({ amount, deadline }),
        });

        if (!response.ok) {
            const error = await response.json();
            throw new Error(error.error || "Failed to lock coins");
        }

        const result = await response.json();
        return result.success;
    } catch (error) {
        console.error("Error locking coins:", error);
        return false;
    }
};
```

**Unlock Coins from Vault**

```javascript
const unlockCoins = async () => {
    try {
        const response = await fetch("http://localhost:4000/profile/vault/unlock", {
            method: "POST",
            credentials: "include",
        });

        if (!response.ok) {
            const error = await response.json();
            throw new Error(error.error || "Failed to unlock coins");
        }

        const result = await response.json();
        return result.success;
    } catch (error) {
        console.error("Error unlocking coins:", error);
        return false;
    }
};
```

**Set Trade URL**

```javascript
const setTradeURL = async url => {
    try {
        const response = await fetch("http://localhost:4000/profile/trade-url", {
            method: "PUT",
            headers: {
                "Content-Type": "application/json",
            },
            credentials: "include",
            body: JSON.stringify({ url }),
        });

        if (!response.ok) {
            const error = await response.json();
            throw new Error(error.error || "Failed to set trade URL");
        }

        const result = await response.json();
        return result.success;
    } catch (error) {
        console.error("Error setting trade URL:", error);
        return false;
    }
};
```

***

### Authentication

All protected endpoints require the user to be authenticated via a JWT token. The token must be sent in the `Authorization` header, so make sure to:

1. Obtain a JWT token via the `/auth/steam` or `/auth/google` endpoints
2. Include the `Authorization: Bearer <token>` header in all requests
3. Use HTTPS in production for secure transmission

The authentication middleware checks `req.isAuthenticated()` and returns a 401 error if the user is not logged in.

***

### Error Handling

All endpoints follow a consistent error response format:

```json
{
    "error": "Error message description"
}
```

Common HTTP status codes:

* `200 OK`: Successful request
* `400 Bad Request`: Invalid input or business logic error
* `401 Unauthorized`: User not authenticated
* `404 Not Found`: Resource not found
* `500 Internal Server Error`: Server-side error
* `501 Not Implemented`: Feature not yet available

***

### Notes

* The vault feature allows users to lock their coins for a specified period, preventing them from being used until the deadline passes.
* All monetary amounts are in the platform's base currency units.
* Timestamps are in Unix milliseconds format.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://trident-cas.sabn.xyz/api/profile.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
