# User Page Requirements This document contains the complete frontend requirements for all user management pages and components. All UI components are dynamically generated from backend metadata—no hardcoding required. **IMPORTANT:** All user management pages are **admin-only**. Non-admin users should not see navigation links or be able to access these pages. The frontend must check user privileges before rendering user management UI. ## Table of Contents 1. [Overview](#overview) 2. [Page Structure and Layout](#page-structure-and-layout) 3. [User Interactions and Functionality](#user-interactions-and-functionality) 4. [Backend Routes and API Integration](#backend-routes-and-api-integration) 5. [Field and Attribute Reference](#field-and-attribute-reference) 6. [Dynamic Rendering Guidelines](#dynamic-rendering-guidelines) 7. [Admin Access Control](#admin-access-control) --- ## Overview The user management page enables administrators to manage users within their mandate. The frontend consists of a single page (`/users`) with different views/states: - **List View** - Browse, search, filter, and sort users (admin-only) - **Detail View** - View complete user information (admin-only) - **Edit View** - Edit user properties (admin-only) - **Create View** - Create new users (admin-only) All views use backend-driven UI generation, meaning field definitions, labels, validation rules, and UI structure come entirely from backend metadata through the `/api/attributes/User` endpoint. Views are managed through component state and routing within the same page, not as separate routes. --- ## Page Structure and Layout ### User Management Page (`/users`) **Access Control:** Admin-only. Non-admin users should not see this page or navigation links to it. The user management page uses different views/states to handle different user interactions. Views are managed through component state and routing within the same page component. ### List View **State:** `view === 'list'` or `selectedUserId === null` **What the administrator sees:** - **Main Content Area:** - Table or card grid displaying all users in the mandate - Each user row/card shows: username, email, full name, privilege badge, enabled toggle (interactive switch), authentication authority - Enabled toggle is clickable and immediately updates user status with optimistic update - Clickable rows/cards that switch to Detail View (set selectedUserId and view state) - **Search and Filter Controls:** - General search input box (searches across all text fields) - Field-specific filter controls (one filter per visible field) - Active filter indicators (chips/badges showing applied filters) - "Clear all filters" button when filters are active - **Sorting Controls:** - Clickable column headers with sort indicators (up/down arrows) - Visual indication of current sort field and direction - Support for multi-level sorting - **Pagination Controls:** - Page information display ("Page X of Y", "Showing 1-20 of 45 users") - Previous/Next page buttons - Page number buttons - Page size selector (10, 20, 50, 100 items per page) - **Action Buttons:** - "Create User" button (admin-only) - switches to Create View ### Detail View **State:** `view === 'detail'` and `selectedUserId !== null` **Access Control:** Admin-only. **What the administrator sees:** - **User Header Section:** - Username (editable indicator if user has permission) - Full name (if available) - Privilege badge with color coding - Enabled status indicator - **User Information Section:** - All user properties displayed as formatted fields - Read-only fields shown as formatted text - Editable fields shown with edit indicators (if admin has permission) - Special formatting: - Privilege → Color-coded badge (User/Admin/SysAdmin) - Enabled → Checkmark icon or "Enabled"/"Disabled" text - Authentication Authority → Badge with icon - Email → Clickable mailto link - **Action Buttons:** - Edit button (if admin has permission and editable fields exist) - switches to Edit View - Reset Password button (admin-only) - Revoke Sessions button (admin-only) - Delete button (if admin has permission) ### Edit View **State:** `view === 'edit'` and `selectedUserId !== null` **Access Control:** Admin-only. **What the administrator sees:** - **Form Section:** - Dynamic form with editable user fields only - Field labels with required indicators (asterisk for required fields) - Help text/tooltips from field descriptions - Input validation errors displayed inline - **Action Buttons:** - Save button (submits form) - Cancel button (switches back to Detail View) ### Create View **State:** `view === 'create'` **Access Control:** Admin-only. **What the administrator sees:** - **Form Section:** - Dynamic form with all editable user fields - Password field (special field, not in User model attributes) - Confirm password field (frontend-only validation) - Field labels with required indicators - Help text/tooltips from field descriptions - Input validation errors displayed inline - **Action Buttons:** - Create button (submits form) - Cancel button (switches back to List View) - **Confirmation Dialogs:** - Delete confirmation dialog (on user detail page) - Password reset confirmation dialog --- ## User Interactions and Functionality ### Admin Access Control **Before Rendering Any User Management UI:** 1. Check if current user has admin or sysadmin privilege 2. If not admin: - Hide navigation links to user management pages - Redirect if user tries to access pages directly - Show unauthorized access message 3. If admin: - Render user management UI normally - Handle 403 errors gracefully (may occur if permissions change) ### Browsing and Discovery **Search Functionality:** - Administrator types in general search box - Frontend debounces input (300-500ms delay) - Search applies across all text fields in user objects - Results update automatically - Page resets to page 1 when search changes **Field Filtering:** - Administrator selects field to filter by - Frontend shows appropriate filter UI based on field type: - Text fields → Text input with operator selection (contains, equals, startsWith, endsWith) - Select fields → Dropdown with options from backend metadata - Email fields → Email input filter - Checkbox fields → Boolean toggle (true/false/any) - Administrator applies filter → Filter appears as active chip/badge - Administrator can remove individual filters - Multiple filters work together (AND logic) - Page resets to page 1 when filters change **Sorting:** - Administrator clicks column header - Sort direction toggles (asc → desc → remove) - Multiple columns can be sorted (multi-level sorting) - Sort indicators show on column headers - All filters and search preserved when sorting **Pagination:** - Administrator clicks page number or navigation button - Page updates and data refetches - All filters, search, and sort preserved - Administrator changes page size → Page resets to 1, data refetches **View Switching:** - Administrator clicks user row/card → Switches to Detail View (set `selectedUserId` and `view: 'detail'`) - Administrator clicks username → Switches to Detail View (set `selectedUserId` and `view: 'detail'`) ### Viewing User Details **Information Display:** - All user fields displayed using dynamic rendering - Read-only fields shown as formatted text - Editable fields shown with edit indicators - Special fields formatted appropriately (privilege badges, enabled status, email links) **Action Availability:** - Edit button shown if editable fields exist and admin has permission - Reset Password button always shown (admin-only action) - Revoke Sessions button always shown (admin-only action) - Delete button shown if admin has permission ### Creating Users **Form Interaction:** - Administrator clicks "Create User" button → Switches to Create View (set `view: 'create'`) - Form shows all editable fields plus password field - Administrator fills in fields - Client-side validation shows errors immediately - Administrator clicks Create → Form validates and submits - Administrator clicks Cancel → Switches back to List View (set `view: 'list'`, `selectedUserId: null`) **Form Validation:** - Required field validation (shows error if empty) - Type validation (e.g., email fields must be valid email format) - Select field validation (value must be in options array) - Password validation (minimum 8 characters) - Password confirmation validation (must match password) - Validation errors displayed inline below fields **Form Submission:** - User data sent as User object - Password sent as separate field in request body - Success → Switch to Detail View for created user (set `selectedUserId` to new user ID, `view: 'detail'`) - Error handling: - 403 (permission denied) → Show permission error - 400 (validation errors) → Display backend validation errors - Other errors → Show generic error message ### Editing Users **Form Interaction:** - Administrator clicks "Edit" button → Switches to Edit View (set `view: 'edit'`) - Form pre-populated with current user values - Administrator modifies fields - Client-side validation shows errors immediately - Administrator clicks Save → Form validates and submits - Administrator clicks Cancel → Switches back to Detail View (set `view: 'detail'`) **Form Validation:** - Required field validation (shows error if empty) - Type validation (e.g., email fields must be valid email format) - Select field validation (value must be in options array) - Validation errors displayed inline below fields **Form Submission:** - Only changed fields sent (or all form data) - Success → Switch back to Detail View (set `view: 'detail'`) and show success message - Error handling: - 403 (permission denied) → Show permission error - 400 (validation errors) → Display backend validation errors - Other errors → Show generic error message ### Enabling and Disabling Users **Toggle Interaction:** - Administrator views user list table - Table displays enabled/disabled status as toggle switch in "Enabled" column - Administrator clicks toggle switch for a user - Frontend immediately updates toggle state (optimistic update) - Frontend sends PUT request to update user's enabled property - Administrator sees immediate feedback (toggle changes instantly) **Toggle Submission:** - Success → Keep optimistic update, refetch user list to ensure consistency - Error → Revert toggle to original state, show error message - No confirmation dialog needed - toggle is immediate and reversible **Implementation Notes:** - Toggle should be part of the main table column - Use optimistic updates for instant feedback - Refetch list after successful update - Handle errors gracefully by reverting toggle state ### Customer Journey 5: Enabling and Disabling Users > **📋 Complete customer journey documentation is available in [User Customer Journeys](./user-page-customer-journeys.md#customer-journey-5-enabling-and-disabling-users)** ### Resetting User Passwords **Password Reset Interaction:** - Administrator clicks "Reset Password" button - Password reset dialog appears - Administrator enters new password - Administrator confirms new password - Client-side validation: - Password must be at least 8 characters - Passwords must match - Administrator clicks Reset → Password reset request sent - Administrator clicks Cancel → Dialog closes, no action **Password Reset Submission:** - Success → Show success message, close dialog - Backend automatically revokes all user tokens - Error handling: - 403 (permission denied) → Show permission error - 400 (password too short) → Show validation error - Other errors → Show generic error message ### Revoking User Sessions **Session Revocation Interaction:** - Administrator clicks "Revoke Sessions" button - Session revocation dialog appears - Administrator optionally selects authority filter: - All authorities (default) - revokes all sessions - Local only - revokes only local authentication sessions - Google only - revokes only Google OAuth sessions - Microsoft only - revokes only Microsoft OAuth sessions - Administrator optionally enters reason (for audit logging) - Administrator clicks "Revoke Sessions" → Session revocation request sent - Administrator clicks Cancel → Dialog closes, no action **Session Revocation Submission:** - Success → Show success message with count of revoked sessions, close dialog - User will need to log in again on all affected devices - Error handling: - 403 (permission denied) → Show permission error - 400 (invalid parameters) → Show validation error - Other errors → Show generic error message **Use Cases:** - Security incident: User's account may have been compromised - Device management: User lost a device or needs to log out of specific service - Account suspension: Temporarily disable user access - Force re-authentication: Make user log in again without changing password **Password Reset Interaction:** - Administrator clicks "Reset Password" button - Password reset dialog appears - Administrator enters new password - Administrator confirms new password - Client-side validation: - Password must be at least 8 characters - Passwords must match - Administrator clicks Reset → Password reset request sent - Administrator clicks Cancel → Dialog closes, no action **Password Reset Submission:** - Success → Show success message, close dialog - Backend automatically revokes all user tokens - Error handling: - 403 (permission denied) → Show permission error - 400 (password too short) → Show validation error - Other errors → Show generic error message ### Customer Journey 7: Revoking User Sessions > **📋 Complete customer journey documentation is available in [User Customer Journeys](./user-page-customer-journeys.md#customer-journey-7-revoking-user-sessions)** ### Deleting Users **Delete Action:** - Administrator clicks delete button (on detail page or list) - Confirmation dialog appears with user name/username - Warning about permanent deletion - Administrator confirms → User deleted - Administrator cancels → Dialog closes, no action **Delete Success Handling:** - Success message displayed - If in Detail View → Switch back to List View (set `view: 'list'`, `selectedUserId: null`) - If in List View → Remove user from list or refresh --- ## Backend Routes and API Integration ### Complete Route Reference All backend routes used by user pages: | Route | Method | Purpose | When Used | Access Control | |-------|--------|---------|-----------|----------------| | `/api/users/` | GET | Get all users (with pagination) | Initial page load, pagination changes, sort changes, filter changes, search changes | All authenticated users (filtered by mandate) | | `/api/users/{userId}` | GET | Get user details | Detail page load, edit page load | All authenticated users | | `/api/users/{userId}` | PUT | Update user | Edit form submission | All authenticated users | | `/api/users/{userId}` | DELETE | Delete user | User confirms deletion | All authenticated users | | `/api/users` | POST | Create user | Create form submission | All authenticated users | | `/api/users/{userId}/reset-password` | POST | Reset user password | Admin confirms password reset | **Admin-only** | | `/api/admin/tokens/revoke/user` | POST | Revoke all active sessions for a user | Admin confirms session revocation | **Admin-only** | | `/api/users/change-password` | POST | Change current user's password | User changes own password | Current user only (not admin-only) | | `/api/attributes/User` | GET | Get field definitions | Page load (once per page) - used to generate all UI components | All authenticated users | ### API Request Patterns **Pagination Request:** ``` GET /api/users/?pagination={"page":1,"pageSize":20,"sort":[],"filters":null} ``` - `pagination` parameter is JSON-encoded string - If user wants all users: omit `pagination` parameter entirely - Filters structure: `{"search":"query","fieldName":"value",...}` - Optional `mandateId` query parameter to filter by mandate **Create Request:** ``` POST /api/users Content-Type: application/json Body: { "username": "john.doe", "email": "john@example.com", "fullName": "John Doe", "language": "en", "enabled": true, "privilege": "user", "authenticationAuthority": "local", "password": "securepassword123" } ``` - Password is sent as separate field in body (not part of User model) - All User model fields sent as User object - Handle 403 (permission denied) and 400 (validation errors) **Update Request:** ``` PUT /api/users/{userId} Content-Type: application/json Body: {fieldName: value, ...} ``` - Send only changed fields or all form data - Handle 403 (permission denied) and 400 (validation errors) **Password Reset Request:** ``` POST /api/users/{userId}/reset-password Content-Type: application/json Body: {"newPassword": "newsecurepassword123"} ``` - **Admin-only endpoint** - Password must be at least 8 characters - Backend automatically revokes all user tokens - Handle 403 (permission denied) and 400 (validation errors) **Session Revocation Request:** ``` POST /api/admin/tokens/revoke/user Content-Type: application/json Body: { "userId": "user-id-here", "authority": "local", // Optional: "local", "google", "msft", or omit for all "reason": "Security incident" // Optional reason for audit logging } ``` - **Admin-only endpoint** - `userId` is required - `authority` is optional - if omitted, revokes all sessions regardless of authority - `reason` is optional - defaults to "admin revoke" if not provided - Returns `{"revoked": count}` - number of sessions revoked - Handle 403 (permission denied) and 400 (validation errors) **Delete Requests:** ``` DELETE /api/users/{userId} ``` - Delete operation requires user confirmation - Handle 403 (permission denied) and 404 (not found) gracefully ### Response Handling **Paginated Response:** ```json { "items": [...], "pagination": { "currentPage": 1, "pageSize": 20, "totalItems": 45, "totalPages": 3, "sort": [...], "filters": {...} } } ``` **Error Responses:** - 403 Forbidden → Show permission error message (admin-only actions) - 404 Not Found → Show "not found" error message - 400 Bad Request → Display validation errors from response - 500 Internal Server Error → Show generic error message --- ## Field and Attribute Reference ### Complete Field List The following is a comprehensive list of all parameters, attributes, and fields that will be displayed for users. All of these are provided by the backend through the `/api/attributes/User` endpoint and should never be hardcoded in the frontend. #### Core User Fields **Identification Fields:** - `id` - Unique user identifier (text, readonly, not required, visible) - `mandateId` - ID of the mandate this user belongs to (text, readonly, not required, visible) **Account Fields:** - `username` - Username for login (text, editable, required, visible) - `email` - Email address of the user (email, editable, required, visible) - `fullName` - Full name of the user (text, editable, not required, visible) **Configuration Fields:** - `language` - Preferred language of the user (select, editable, required, visible) - Options: "de", "en", "fr", "it" - Each option has localized labels (en/fr) - `enabled` - Indicates whether the user is enabled (checkbox, editable, not required, visible) - `privilege` - Permission level (select, editable, required, visible) - Options: "user", "admin", "sysadmin" - Each option has localized labels (en/fr) - `authenticationAuthority` - Primary authentication authority (select, readonly, not required, visible) - Options: "local", "google", "msft" - Each option has localized labels (en/fr) **Special Fields (Not in User Model):** - `password` - Password field for create forms (password, not in attributes, required for creation) - `confirmPassword` - Password confirmation (password, frontend-only, required for creation) ### Pagination Parameters **Request Parameters (`PaginationParams`):** - `page` - Current page number (1-based, minimum 1) - `pageSize` - Number of items per page (minimum 1, maximum 1000) - `sort` - Array of sort field configurations - Each sort field contains: - `field` - Field name to sort by (must match a user field name) - `direction` - Sort direction: "asc" or "desc" - `filters` - Filter criteria dictionary - `search` - General search term (searches across all text fields, case-insensitive) - Field-specific filters: `{fieldName: value}` or `{fieldName: {operator: "operator", value: value}}` - Supported operators: "equals", "contains", "startsWith", "endsWith", "in", "notIn" **Response Metadata (`PaginationMetadata`):** - `currentPage` - Current page number (1-based) - `pageSize` - Number of items per page - `totalItems` - Total number of items across all pages (after filters applied) - `totalPages` - Total number of pages (calculated from totalItems / pageSize) - `sort` - Current sort configuration applied (array of SortField objects) - `filters` - Current filters applied (mirrors request filters) ### Attribute Definition Structure Each field returned from `/api/attributes/User` contains: - `name` - Field name (e.g., "username", "email", "privilege") - `type` - Field data type (e.g., "text", "email", "select", "checkbox") - `label` - Localized field label (object with language keys: {"en": "English Label", "fr": "French Label"}) - `description` - Field description text - `required` - Boolean indicating if field is required - `readonly` - Boolean indicating if field is read-only - `editable` - Boolean indicating if field can be edited (inverse of readonly) - `visible` - Boolean indicating if field should be displayed in UI - `options` - Array of options for select fields (each option has `value` and localized `label`) --- ## Dynamic Rendering Guidelines The frontend must render all UI components dynamically based on backend metadata. No field definitions, labels, validation rules, or UI structure should be hardcoded. ### Table Column Generation When rendering the user list table: 1. Fetch attribute definitions from `/api/attributes/User` 2. Filter attributes where `visible: true` to determine which columns to display 3. Use `label` property for column headers (select appropriate language based on user preference) 4. Use `type` property to determine how to format cell values: - `text` fields → Display as plain text - `email` fields → Display as clickable mailto link - `select` fields → Display value using label from options array (match value to option.value, then display option.label) - `checkbox` fields → Display as checkmark icon or "Enabled"/"Disabled" text 5. Use `readonly` property to determine if column should be sortable (readonly fields may still be sortable, but editable fields definitely are) 6. Generate click handlers for column headers to update sort parameters and refetch data ### Filter Control Generation When rendering filter controls: 1. Fetch attribute definitions from `/api/attributes/User` 2. Filter attributes where `visible: true` to determine which filters to show 3. For each visible field, generate appropriate filter UI based on `type`: - `text` fields → Text input filter (supports "contains", "equals", "startsWith", "endsWith" operators) - `email` fields → Email input filter - `select` fields → Dropdown filter with options from `options` array (use localized labels) - `checkbox` fields → Boolean toggle filter (true/false/any) 4. Use `label` property for filter labels (localized) 5. When administrator applies filter, update `filters` object in pagination parameters and refetch data 6. Display active filters as chips/badges showing field label and value 7. Allow removing individual filters by removing them from `filters` object ### Search Implementation For general search functionality: 1. Display a single search input box (not field-specific) 2. When administrator types, update `filters.search` in pagination parameters 3. Debounce search input (wait 300-500ms after user stops typing before sending request) 4. Search applies across all text fields in the user object 5. Reset to page 1 when search query changes 6. Combine search with field-specific filters (both are in the `filters` object) ### Form Field Generation When rendering edit forms: 1. Fetch attribute definitions from `/api/attributes/User` 2. Filter attributes where `visible: true` AND `editable: true` to determine which fields to show 3. For each editable field, generate appropriate form input based on `type`: - `text` fields → Text input - `email` fields → Email input - `select` fields → Dropdown/select input with options from `options` array (use localized labels) - `checkbox` fields → Checkbox input 4. Use `label` property for field labels (localized) 5. Use `required` property to show required indicators (asterisk, etc.) 6. Use `description` property to show help text or tooltips 7. Validate form before submission: - Check all `required: true` fields have values - Validate types (e.g., email fields must be valid email format) - Validate select fields (value must be in options array) 8. On submit, send only changed fields or all form data to update endpoint ### Create Form Field Generation When rendering create forms: 1. Follow same pattern as edit forms for User model fields 2. **Add password field** (not in User model attributes): - Password input field - Confirm password input field (frontend-only validation) - Both fields required for creation - Validate password strength (minimum 8 characters) - Validate passwords match 3. On submit, send User object fields plus `password` as separate field in request body ### Display Formatting When displaying field values: 1. Use `type` property to determine formatting: - `text` → Display as-is (may need HTML escaping) - `email` → Display as clickable mailto link - `select` → Look up value in `options` array and display localized label - `checkbox` → Display as checkmark icon or "Enabled"/"Disabled" text 2. Handle `null` or `undefined` values gracefully (show "-" or "Not set") 3. Use `readonly` property to determine if field should show edit indicators 4. Special formatting for privilege field: - Color-code badges (User = blue, Admin = orange, SysAdmin = red) - Use localized labels from options ### Localization All labels and options support multiple languages: 1. Use user's preferred language (from user settings or browser locale) 2. Access localized labels from `label` object: `label[userLanguage]` or `label.en` as fallback 3. For select options, use `option.label[userLanguage]` or `option.label.en` as fallback 4. If label for current language is missing, fall back to English ### Key Principles - Never hardcode field names, labels, types, or validation rules - Always fetch attribute definitions from backend before rendering UI - Use attribute metadata to determine what to display and how to display it - Support all field types dynamically - if backend adds new types, frontend should handle them - Respect `visible`, `editable`, `readonly`, and `required` flags from backend - Use localized labels from backend metadata - Generate filters, forms, and tables entirely from attribute definitions - When backend adds new fields, frontend should automatically display them without code changes - Handle all error cases gracefully (403, 404, 400, 500) - Provide user feedback for all actions (loading states, success messages, error messages) - **Always check admin privileges before rendering user management UI** --- ## Admin Access Control ### Frontend Access Control The frontend must implement access control to ensure only administrators can access user management pages: **1. Navigation Link Visibility:** ```typescript // Only show user management link if user is admin {currentUser?.privilege === 'admin' || currentUser?.privilege === 'sysadmin' ? ( Manage Users ) : null} ``` **2. Route Protection:** ```typescript // Protect route with admin check - single route for all views function UserManagementPage() { const { currentUser } = useAuth(); const [view, setView] = useState<'list' | 'detail' | 'edit' | 'create'>('list'); const [selectedUserId, setSelectedUserId] = useState(null); // Check admin status if (currentUser?.privilege !== 'admin' && currentUser?.privilege !== 'sysadmin') { return ; } // Render appropriate view based on state if (view === 'list') { return { setSelectedUserId(id); setView('detail'); }} onCreate={() => setView('create')} />; } else if (view === 'detail' && selectedUserId) { return setView('edit')} onBack={() => { setSelectedUserId(null); setView('list'); }} />; } else if (view === 'edit' && selectedUserId) { return setView('detail')} onCancel={() => setView('detail')} />; } else if (view === 'create') { return { setSelectedUserId(userId); setView('detail'); }} onCancel={() => setView('list')} />; } return null; } ``` **3. Component-Level Checks:** ```typescript // Check admin status before rendering components function ListView({ onUserSelect }) { const { currentUser } = useAuth(); if (currentUser?.privilege !== 'admin' && currentUser?.privilege !== 'sysadmin') { return ; } // Render list view UI return (
{/* List table */}
); } ``` **4. Error Handling:** ```typescript // Handle 403 errors gracefully try { const response = await fetch('/api/users/userId/reset-password', { method: 'POST', body: JSON.stringify({ newPassword }) }); if (response.status === 403) { showError('You do not have permission to reset passwords'); return; } // Handle other responses } catch (error) { showError('Failed to reset password'); } ``` **5. View State Management:** ```typescript // Manage views within the same page component function UserManagementPage() { const [view, setView] = useState<'list' | 'detail' | 'edit' | 'create'>('list'); const [selectedUserId, setSelectedUserId] = useState(null); // Switch to detail view const handleUserSelect = (userId: string) => { setSelectedUserId(userId); setView('detail'); }; // Switch to edit view const handleEdit = () => { setView('edit'); }; // Switch to create view const handleCreate = () => { setSelectedUserId(null); setView('create'); }; // Switch back to list view const handleBackToList = () => { setSelectedUserId(null); setView('list'); }; // Render based on view state return ( <> {view === 'list' && } {view === 'detail' && selectedUserId && } {view === 'edit' && selectedUserId && setView('detail')} onCancel={() => setView('detail')} />} {view === 'create' && { setSelectedUserId(userId); setView('detail'); }} onCancel={handleBackToList} />} ); } ``` ### Admin-Only Actions The following actions are admin-only and should only be available to administrators: - **Reset User Password** (`POST /api/users/{userId}/reset-password`) - Only admins can reset other users' passwords - Backend enforces this with privilege check - Frontend should hide button for non-admins - **User Management Page** - The user management page should be admin-only - Navigation links should be hidden for non-admins - Direct URL access should show unauthorized message for non-admins ### Security Best Practices 1. **Never trust frontend-only checks** - Backend always enforces permissions 2. **Handle 403 errors gracefully** - Show appropriate error messages 3. **Hide UI elements** - Don't show admin actions to non-admins 4. **Redirect unauthorized access** - Redirect non-admins away from admin pages 5. **Log security events** - Backend logs admin actions (handled by backend) --- ## Summary This document provides complete frontend requirements for all user management pages and components. All requirements follow the principle of **backend-driven UI generation**—no hardcoding of field definitions, labels, or validation rules. The frontend should dynamically generate all UI components from backend metadata provided through the `/api/attributes/User` endpoint. **Critical Security Requirement:** All user management pages are **admin-only**. The frontend must: - Check user privileges before rendering navigation links - Check user privileges before allowing access to pages - Handle 403 Forbidden errors gracefully - Never expose user management UI to non-admin users For generic patterns that apply across all entity types (not just users), see the [Dynamic Forms and Pagination documentation](./dynamic-forms-and-pagination.md).