Files
nick-doc/03 - API Reference/User API.md
2026-05-23 20:35:34 +03:30

8.6 KiB

title, tags
title tags
User API
api
user
reference

User API

Two routers are mounted for users:

Address-book CRUD lives on its own service: /api/addresses/*. All endpoints require Bearer JWT unless noted. Source of truth model: User.

Profile (current user)

GET /api/user/profile

Description: Returns the caller's profile. Auth required: Bearer JWT Response 200:

{ "success": true, "data": { /* User without password / verification tokens */ } }

Source: userController.getCurrentUserProfile

PUT /api/user/profile

Description: Updates the caller's profile. Auth required: Bearer JWT Request body (whitelisted fields):

{
  firstName?: string;
  lastName?: string;
  name?: string;            // alias for profile.name
  phone?: string;
  bio?: string;
  website?: string;
  photoURL?: string;        // also mirrored to profile.avatar
  isPublic?: boolean;
  address?: {
    street?: string;
    city?: string;
    state?: string;
    country?: string;
    postalCode?: string;
  };
  preferences?: {
    language?: "en" | "fa" | "ar";
    currency?: "USD" | "EUR" | "IRR" | "AED";
    notifications?: { email?: boolean; sms?: boolean; push?: boolean };
  };
}

Response 200: Updated user.

GET /api/users/profile

Description: Legacy equivalent of the above. Returns the full sanitized user document. Auth required: Bearer JWT

GET /api/users/profile/:userId

Description: Public profile by id. If profile.isPublic === false and caller is not the owner or admin, only firstName, lastName, avatar, role are returned. Auth required: Bearer JWT

Avatar upload

Avatar upload is handled by the File API:

POST /api/files/upload/avatar (multipart avatar) returns a URL that the caller then writes to profile.avatar via PUT /api/user/profile.

Wallet address

GET /api/user/wallet-address

Description: Returns the caller's stored EVM wallet address (or null). Auth required: Bearer JWT Response 200: { "success": true, "data": { "walletAddress": "0x..." | null } }

PATCH /api/user/wallet-address

Description: Verifies an EIP-191 signed message and stores profile.walletAddress. The server uses ethers.verifyMessage(message, signature) and rejects if the recovered address does not match. Auth required: Bearer JWT Request body:

{
  walletAddress: string;   // 0x-prefixed 40-hex
  signature: string;       // signed `message`
  message: string;         // human-readable challenge text
}

Response 200: { "success": true, "data": { "walletAddress": "0x..." } } Errors:

  • 400 missing fields, malformed address, signature mismatch
  • 404 user not found

The legacy alias PATCH /api/users/wallet-address performs the same logic.

GET /api/users/contacts

Description: Returns the users the caller is allowed to chat with based on role:

  • buyer → sees seller + admin
  • seller → sees buyer + admin
  • admin → sees everyone Auth required: Bearer JWT Response 200: { "success": true, "data": { "contacts": [...], "count": N } }

GET /api/users/search?q=&role=

Description: Case-insensitive search across firstName/lastName/email. Returns up to 20 active users. Auth required: Bearer JWT Errors: 400 if q.length < 2.

GET /api/users?role=...&isActive=true&search=...&page=1&limit=50

Description: Paginated user directory (legacy, no admin gate). See pagination conventions in API Overview. Auth required: Bearer JWT

Admin: user management

These are duplicated across the two routers. The newer controller variants live under /api/user/admin/*; the legacy bodies live under /api/users/admin/*. All require req.user.role === 'admin' (the legacy routes check inline; the controller routes only check authenticateToken and the controller enforces the role).

POST /api/user/admin/create

Description: Admin creates a user with a chosen role and verification state. Auth required: Bearer JWT (admin) Request body:

{
  email: string;
  password: string;
  firstName: string;
  lastName: string;
  role?: "buyer" | "seller" | "admin";  // default "buyer"
  isActive?: boolean;                    // default true
  isVerified?: boolean;                  // default false
  profile?: { /* free-form */ };
}

Response 201: { success, data: { user } } Errors: 400 missing fields, 403 non-admin, 409 email exists.

DELETE /api/user/admin/:userId

Description: Hard-delete a user. Prevents self-deletion and deleting other admins. Auth required: Bearer JWT (admin) Response 200: { success, data: { deletedUserId } } Errors: 400 self-delete, 403 admin-on-admin, 404 not found.

PATCH /api/user/admin/:userId/status

Description: Activate / suspend a user. Auth required: Bearer JWT (admin) Request body: { isActive: boolean; reason?: string } Response 200: { success, data: { user: { _id, isActive, statusUpdatedAt } } }

PATCH /api/user/admin/:userId/toggle-status

Description: Flip active/suspended without explicit body. Auth required: Bearer JWT (admin)

PATCH /api/user/admin/:userId/role

Description: Change a user's role. Auth required: Bearer JWT (admin) Request body: { role: "buyer" | "seller" | "admin"; reason?: string } Errors: 400 invalid role.

GET /api/user/admin/list

Description: Paginated admin user list with filters. Auth required: Bearer JWT (admin) Query params: role, isActive, isVerified, search, page, limit, sortBy, sortOrder Response 200: { success, data: { users, pagination, stats: { totalUsers, activeUsers, verifiedUsers, buyers, sellers, admins } } }

GET /api/user/admin/:userId/dependencies

Description: Returns a count of related entities (purchase requests, offers, payments) before a destructive admin operation. Auth required: Bearer JWT (admin)

GET /api/users/admin/stats

Description: Aggregated user stats — total/active/verified counts, role distribution, activity buckets (24h / 7d / 30d). Auth required: Bearer JWT (admin)

GET /api/users/admin/:userId

Description: Fetch a single user by id (admin view, includes preferences and last-login). Auth required: Bearer JWT (admin)

PUT /api/users/admin/:userId

Description: Mass update a user document (admin override). Auth required: Bearer JWT (admin)

PUT /api/users/admin/update/:email

Description: Same as above but keyed on email. Auth required: Bearer JWT (admin)

PATCH /api/users/admin/:userId/password

Description: Admin forces a new password. Wipes refreshTokens so all sessions are invalidated. Auth required: Bearer JWT (admin) Request body: { newPassword: string; reason?: string }

POST /api/users/admin/:userId/resend-verification

Description: Regenerate the 8-digit email verification code and re-send the verification email. Auth required: Bearer JWT (admin) Errors: 400 user already verified.

Address book

Source: backend/src/services/address/addressRoutes.ts, model: Address.

GET /api/addresses

Description: List the caller's addresses. Auth required: Bearer JWT Response 200: { success: true, data: [Address, ...] }

POST /api/addresses

Description: Create a new address. First address auto-becomes primary. Auth required: Bearer JWT Request body:

{
  fullName: string;
  phone: string;
  street: string;
  city: string;
  state?: string;
  country: string;
  postalCode?: string;
  isPrimary?: boolean;
  notes?: string;
}

PUT /api/addresses/:addressId

Description: Update an address. Auth required: Bearer JWT Errors: 404 not owned by user.

DELETE /api/addresses/:addressId

Description: Delete an address. If it was the primary, another address is promoted. Auth required: Bearer JWT

PATCH /api/addresses/:addressId/primary

Description: Promote an address to primary; demotes the previous primary. Auth required: Bearer JWT

See Address for the schema, and Marketplace API for how purchase requests reference an address.