5.9 KiB
5.9 KiB
User Management
Overview
User management provides administrators with tools to create, view, update, and delete user accounts, assign roles, and manage user activation status. The system ensures at least one admin account exists.
Architecture
Backend Components:
UserService: User CRUD operations- User routes (routes/users.ts): REST API endpoints
UserDatabaseService: Database operations
Frontend Components:
UsersView: Main user management pageUserTable: User list with actionsUserForm: Create/edit user dialogChangePasswordDialog: Password change form
Database Schema
users table:
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE COLLATE NOCASE,
email TEXT NOT NULL UNIQUE COLLATE NOCASE,
password_hash TEXT NOT NULL,
role_id INTEGER NOT NULL,
is_active BOOLEAN DEFAULT 1,
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now')),
last_login_at TEXT,
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE RESTRICT
);
user_settings table:
CREATE TABLE user_settings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
setting_key TEXT NOT NULL,
setting_value TEXT NOT NULL,
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now')),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
UNIQUE(user_id, setting_key)
);
API Endpoints
GET /api/users
Get all users with pagination.
- Permission: users.read
- Query:
page,limit - Response: Paginated user list with role info
GET /api/users/:id
Get single user by ID.
- Permission: users.read
- Response: User object with permissions list
POST /api/users
Create a new user account.
- Permission: users.create
- Body:
{ "username", "email", "password", "roleId", "isActive" } - Response: Created user (201)
- Validation: Username/email unique, password min 6 chars
PATCH /api/users/:id
Update existing user account.
- Permission: users.update
- Body: Partial update of
{ "email", "roleId", "isActive" } - Response: Updated user
- Note: Cannot change username (immutable)
DELETE /api/users/:id
Delete a user account.
- Permission: users.delete
- Rules: Cannot delete self, cannot delete last admin
- Cascade: Deletes tokens, sessions, settings
- Response:
{ "success": true }
POST /api/users/:id/change-password
Change user password.
- Permission: Own account OR users.update
- Body:
{ "currentPassword", "newPassword" } - Response:
{ "success": true } - Note: Admins don't need current password
PATCH /api/users/me/settings
Update current user's settings.
- Body: Key-value pairs for user settings
- Response: Updated settings object
Business Rules
User Creation:
- Username must be unique (case-insensitive)
- Email must be unique (case-insensitive)
- Password must meet minimum length requirement
- Role must exist in system
- Account is active by default
User Update:
- Cannot change username
- Email must remain unique if changed
- Can change role to any valid role
- Can toggle active status
User Deletion:
- Cannot delete yourself
- Cannot delete last admin user
- Cascade deletes tokens, play sessions, user settings
- Activity logs preserved (user_id set to NULL)
Password Changes:
- Users can change own password (requires current password)
- Admins can change any password (no current password required)
- Password hashed with bcrypt before storage
Permissions
User management operations require:
users.read- View user list and detailsusers.create- Create new user accountsusers.update- Update user information and rolesusers.delete- Delete user accounts
Default Assignments:
- Admin: All user management permissions
- User: None (can only manage own account)
- Guest: None
Common Use Cases
1. Create New User
const createMutation = useCreateUser();
await createMutation.mutateAsync({
username: 'newuser',
email: 'newuser@example.com',
password: 'secure123',
roleId: 2,
isActive: true,
});
2. Update User Role
const updateMutation = useUpdateUser();
await updateMutation.mutateAsync({
userId: 10,
data: { roleId: 3 },
});
3. Deactivate User
const updateMutation = useUpdateUser();
await updateMutation.mutateAsync({
userId: 10,
data: { isActive: false },
});
4. Delete User
const deleteMutation = useDeleteUser();
if (confirm(`Delete user ${user.username}?`)) {
await deleteMutation.mutateAsync(userId);
}
5. Change Own Password
const changePasswordMutation = useChangePassword();
await changePasswordMutation.mutateAsync({
userId: currentUser.id,
currentPassword: 'oldpass',
newPassword: 'newpass',
});
Best Practices
- Always verify permissions before showing admin UI
- Confirm destructive actions (delete user)
- Validate input on both client and server
- Show loading states during operations
- Handle errors gracefully with user feedback
- Log admin actions for audit trail
- Prevent self-deletion to avoid lockouts
- Maintain at least one admin in system
- Deactivate instead of delete when possible
- Require strong passwords
Troubleshooting
Cannot create user:
- Check username/email uniqueness
- Verify password meets requirements
- Ensure role exists
- Check permissions (users.create)
Cannot delete user:
- Verify not deleting self
- Check if last admin user
- Ensure users.delete permission
- Look for foreign key constraints
Password change fails:
- Verify current password is correct
- Check new password meets requirements
- Ensure user exists and is active
- Validate permissions
User list not loading:
- Check users.read permission
- Verify database connection
- Look for query errors in logs