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

# User Preferences

> Manage personal profile information and password

## Overview

**User Preferences** allow you to manage your personal profile information and password. These are user-specific settings that apply only to your account, as opposed to organization-wide settings.

<Note>
  **Authentication required**: All endpoints require user authentication (valid access token).

  These endpoints operate on the authenticated user's profile only. No special permissions required beyond being logged in.
</Note>

***

## API Endpoints

### Get My Profile

**Retrieve your own profile information:**

```http theme={null}
GET /users/me
Headers:
  Authorization: Bearer {accessToken}
```

**Response:**

```json theme={null}
{
  "message": "User profile fetched successfully",
  "user": {
    "id": "user-123",
    "name": "John Doe",
    "phone": "+250781234567",
    "email": "john.doe@example.com",
    "profilePhotoUrl": "https://example.com/photos/john.jpg",
    "createdAt": "2025-01-15T10:30:00.000Z"
  }
}
```

***

### Update My Profile

**Update your profile information:**

```http theme={null}
PUT /users/me
Headers:
  Authorization: Bearer {accessToken}
Body:
{
  "name": "John Doe",
  "email": "john.doe@example.com",
  "phone": "+250781234567",
  "profilePhotoUrl": "https://example.com/photos/john.jpg"
}
```

**Request body fields:**

| Field             | Type   | Required | Validation                     | Description       |
| ----------------- | ------ | -------- | ------------------------------ | ----------------- |
| `name`            | string | No       | -                              | Display name      |
| `email`           | string | No       | Valid email format             | Email address     |
| `phone`           | string | No       | Rwandan phone number (+250...) | Phone number      |
| `profilePhotoUrl` | string | No       | Valid URL                      | Profile photo URL |

**All fields are optional** - include only fields you want to update.

**Response:**

```json theme={null}
{
  "message": "User updated successfully",
  "user": {
    "id": "user-123",
    "name": "John Doe",
    "phone": "+250781234567",
    "email": "john.doe@example.com",
    "profilePhotoUrl": "https://example.com/photos/john.jpg"
  }
}
```

**Error cases:**

| Status | Message                                        | Cause                                  |
| ------ | ---------------------------------------------- | -------------------------------------- |
| 401    | "User not found"                               | Invalid token or user deleted          |
| 409    | "User with that email or phone already exists" | Email/phone conflict with another user |

***

### Change Password

**Update your password:**

```http theme={null}
POST /users/change-password
Headers:
  Authorization: Bearer {accessToken}
Body:
{
  "oldPassword": "current-password",
  "newPassword": "new-password"
}
```

**Request body fields:**

| Field         | Type   | Required | Validation                  | Description                       |
| ------------- | ------ | -------- | --------------------------- | --------------------------------- |
| `oldPassword` | string | Yes      | Must match current password | Current password for verification |
| `newPassword` | string | Yes      | Minimum 6 characters        | New password                      |

**Response:**

```json theme={null}
{
  "message": "Password changed successfully."
}
```

**Error cases:**

| Status | Message                    | Cause                            |
| ------ | -------------------------- | -------------------------------- |
| 401    | "User not found"           | Invalid token or user deleted    |
| 401    | "User has no password set" | Account created without password |
| 401    | "Invalid old password"     | Incorrect current password       |

**Important**: After password change, existing sessions remain valid. User is NOT logged out automatically.

***

## Editable Profile Fields

### Name

**Field**: `name`

**Description**: Your display name shown throughout the application

**Example**: "John Doe"

**Usage**:

* Appears on transaction records
* Shown in audit logs
* Displayed to other organization members

**Recommendation**: Use your real name for accountability

***

### Email Address

**Field**: `email`

**Description**: Email address for notifications and login

**Format**: Valid email format

**Example**: "[john.doe@example.com](mailto:john.doe@example.com)"

**Usage**:

* Login identifier (in addition to phone)
* Email notification recipient (if organization has email enabled)
* Password reset destination

**Validation**: Must be unique across all users in Agatabo (not just your organization)

**Important**: Changing email does not require re-verification. New email becomes active immediately.

***

### Phone Number

**Field**: `phone`

**Description**: Phone number for SMS notifications and login

**Format**: Rwandan phone number in international format

**Example**: "+250781234567"

**Validation**:

* Must start with "+250"
* Must be valid Rwandan number format
* Must be unique across all users

**Usage**:

* Login identifier (in addition to email)
* SMS notification recipient (if organization has SMS enabled)
* Password reset destination (via SMS)

**Recommendation**: Keep phone number up-to-date for account recovery

***

### Profile Photo

**Field**: `profilePhotoUrl`

**Description**: URL to your profile photo

**Format**: Valid URL (http or https)

**Example**: "[https://example.com/photos/profile.jpg](https://example.com/photos/profile.jpg)"

**Usage**:

* Displayed in navigation bar
* Shown in user menus

**Note**: Agatabo does not host photos. You must provide a URL to an externally-hosted image.

***

### Password

**Updated via**: `POST /users/change-password` (separate endpoint)

**Requirements**:

* Minimum 6 characters
* Must provide current password for verification

**Best practices**:

* Use mix of letters, numbers, and symbols
* Don't reuse passwords from other services
* Use password manager for strong passwords
* Change password if you suspect unauthorized access

**Security**: Passwords are hashed using bcrypt. Never stored or transmitted in plain text.

***

## Immutable Fields

**These fields CANNOT be changed by users:**

### User ID

**Field**: `id`

**Description**: System-generated unique identifier

**Example**: "user-abc123"

**Usage**: Internal database references, API parameters

***

### Created At

**Field**: `createdAt`

**Description**: Account creation timestamp

**Format**: ISO 8601 datetime

**Example**: "2025-01-15T10:30:00.000Z"

***

## Organization-Level Settings

**The following are NOT user preferences** (controlled at organization level):

### Notification Preferences

**Current limitation**: Users CANNOT opt out of individual notification types.

**How it works**:

* Organization administrator enables/disables email notifications for entire organization
* Organization administrator enables/disables SMS notifications for entire organization
* If enabled, ALL users with email/phone receive notifications

**Workaround** (not recommended):

* Remove email/phone from profile to stop receiving notifications
* This affects login capability (you'll only be able to use remaining identifier)

See: [Organization Settings](/tontines/settings/organization-settings)

***

### Display Preferences

**Currently NOT available**:

The following features do not exist at user or organization level:

* Language selection (system uses browser language)
* Theme (light/dark mode)
* Custom date/time format (uses organization setting)
* Dashboard layout customization
* Report default filters
* Timezone preference (uses organization timezone)

These may be added in future versions.

***

## Common Use Cases

### Update Your Email

**API call:**

```bash theme={null}
curl -X PUT "/users/me" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "newemail@example.com"
  }'
```

**Result**: Email updated immediately. No verification email sent.

**Important**:

* Ensure you have access to new email (for future password resets)
* New email must not be used by another account

***

### Update Phone Number

**API call:**

```bash theme={null}
curl -X PUT "/users/me" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+250787654321"
  }'
```

**Phone format**:

* Must start with "+250"
* Must be valid Rwandan phone number
* Example: "+250781234567"

**Validation error if**:

* Phone doesn't match Rwandan format
* Phone already used by another account

***

### Change Password

**API call:**

```bash theme={null}
curl -X POST "/users/change-password" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "oldPassword": "current-password",
    "newPassword": "new-strong-password-123"
  }'
```

**Result**: Password changed immediately. Existing sessions remain valid.

**Security note**: Sessions are NOT automatically invalidated. User remains logged in on all devices.

***

### Update Multiple Fields at Once

**API call:**

```bash theme={null}
curl -X PUT "/users/me" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Jane Smith",
    "email": "jane.smith@example.com",
    "phone": "+250781234567",
    "profilePhotoUrl": "https://example.com/jane.jpg"
  }'
```

**All fields optional** - include only what you want to update.

***

## Password Reset Flow

**If you forgot your password:**

### Step 1: Request Reset

**API endpoint:**

```http theme={null}
POST /users/reset-password
Body:
{
  "identifier": "john.doe@example.com"
}
```

**identifier** can be:

* Email address
* Phone number (starting with "+")

**Response:**

```json theme={null}
{
  "message": "If an account with that identifier exists, a password reset link has been sent."
}
```

**What happens**:

* If identifier is email: Password reset link sent via email
* If identifier is phone: Password reset link sent via SMS
* If identifier doesn't exist: Same message returned (security - don't reveal account existence)

**Email example:**

Subject: "Reset your Agatabo password"

Body: "Reset your Agatabo password: [https://agatabo.com/auth/reset-password?token=abc123xyz](https://agatabo.com/auth/reset-password?token=abc123xyz)..."

***

### Step 2: Confirm Reset

**After clicking reset link, submit new password:**

```http theme={null}
POST /users/reset-password/confirm
Body:
{
  "token": "abc123xyz",
  "newPassword": "new-password-here"
}
```

**Response:**

```json theme={null}
{
  "message": "Password reset successfully",
  "accessToken": "eyJhbGc...",
  "refreshToken": "eyJhbGc...",
  "user": {
    "id": "user-123",
    "name": "John Doe",
    "phone": "+250781234567",
    "email": "john.doe@example.com",
    "profilePhotoUrl": "https://example.com/photos/john.jpg",
    "userType": "user"
  }
}
```

**Important**:

* All existing sessions are invalidated (logged out on all devices)
* New session created automatically (user logged in)
* Reset token can only be used once

***

## Best Practices

<Note>
  **Managing your user preferences:**

  **Profile updates:**

  * ✅ Keep email and phone current for account recovery
  * ✅ Use real name for accountability
  * ✅ Verify email/phone change immediately (test notifications)
  * ✅ Update profile photo from reliable hosting (not temporary links)

  **Password security:**

  * ✅ Use minimum 10 characters (even though system allows 6)
  * ✅ Include mix of uppercase, lowercase, numbers, symbols
  * ✅ Use unique password (not reused from other sites)
  * ✅ Use password manager (LastPass, 1Password, Bitwarden)
  * ✅ Change password if suspicious activity detected

  **Email/phone uniqueness:**

  * ✅ One email = one Agatabo account (cannot share across accounts)
  * ✅ One phone = one Agatabo account
  * ✅ To use same email/phone elsewhere, remove from current account first

  **Password reset:**

  * ✅ Check spam folder if reset email not received
  * ✅ Wait 5 minutes before requesting another reset
  * ✅ Contact administrator if reset emails not arriving
  * ✅ Reset token expires after limited time (use promptly)

  **Privacy:**

  * ✅ Your name visible to other organization members
  * ✅ Email/phone visible to organization administrators
  * ✅ Password never visible to anyone (encrypted)
  * ✅ Profile photo should not contain sensitive information
</Note>

***

## Troubleshooting

**Q: Email/phone change says "already exists"**

A: Error: "User with that email or phone already exists"

**Cause**: Another user account already has that email or phone.

**Solution**:

* Use different email/phone
* If you own the other account, remove email/phone from that account first
* Contact administrator if email/phone incorrectly assigned elsewhere

***

**Q: Password change says "invalid old password"**

A: Error: "Invalid old password"

**Cause**: Current password entered incorrectly.

**Solution**:

* Verify current password (check Caps Lock, keyboard layout)
* If truly forgotten, use password reset flow instead
* Contact administrator if account locked

***

**Q: Profile update doesn't reflect immediately**

A: Check:

* Did request succeed? (200 response)
* Try logging out and back in
* Clear browser cache
* Check if you're viewing cached data

***

**Q: Can I use email/phone from deleted account?**

A: Depends on implementation. If user account was deleted:

* Email/phone may become available again
* May require administrator intervention
* Contact support if error persists

***

**Q: Want to disable notifications just for me**

A: Not possible. Notifications are organization-wide settings.

**Options**:

* Ask administrator to disable notifications for entire organization
* Remove your email/phone (affects login capability - not recommended)

See: [Organization Settings](/tontines/settings/organization-settings)

***

**Q: Password reset email not received**

A: Check:

* Spam/junk folder
* Email address correct (no typos)
* Organization has email service configured
* Wait 5 minutes (email delivery may be delayed)

Contact administrator if still not received.

***

**Q: Want to change timezone/date format**

A: These are organization-level settings, not user preferences.

Contact administrator with `settings:write` permission.

See: [Organization Settings](/tontines/settings/organization-settings)

***

## Related Topics

<CardGroup cols={2}>
  <Card title="Organization Settings" icon="gear" href="/tontines/settings/organization-settings">
    Organization-wide configuration
  </Card>

  <Card title="Managing Members" icon="users" href="/tontines/organization-users/managing-users">
    Update member information (for admins)
  </Card>

  <Card title="Permissions" icon="shield" href="/tontines/settings/permissions">
    Access control and roles
  </Card>

  <Card title="Audit Trail" icon="file-magnifying-glass" href="/tontines/advanced/audit-trail">
    Track profile changes
  </Card>
</CardGroup>
