8.6 KiB
title, tags
| title | tags | |||
|---|---|---|---|---|
| User API |
|
User API
Two routers are mounted for users:
/api/user/*- the new controller pattern inbackend/src/services/user/userControllerRoutes.tswired touserController./api/users/*- the legacy router inbackend/src/services/user/userRoutes.ts(kept for backward compatibility, primarily used by the admin console).
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:
400missing fields, malformed address, signature mismatch404user not found
The legacy alias PATCH /api/users/wallet-address performs the same logic.
Contacts and search
GET /api/users/contacts
Description: Returns the users the caller is allowed to chat with based on role:
buyer→ seesseller+adminseller→ seesbuyer+adminadmin→ 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.