Implement user management enhancements and password change functionality

- Add change password feature in UserService, allowing users to update their password after verifying the current one.
- Introduce UpdateUserRequest model for updating user details, including username, password, and role.
- Implement RESTful endpoints for changing passwords and updating user information in AuthResource and UsersResource.
- Enhance OpenAPI specification to document new endpoints for password change and user updates.
- Create frontend components for user management, including a dedicated UsersPage for admin users to manage user accounts.
- Add unit tests for UserService to ensure correct behavior of password changes and user updates.
This commit is contained in:
Konrad Neitzel
2026-02-22 17:55:45 +01:00
parent 1e1368e519
commit 3218cb1a2a
16 changed files with 1306 additions and 14 deletions
@@ -445,6 +445,31 @@ paths:
"401":
description: Not authenticated.
/auth/change-password:
post:
operationId: changePassword
summary: Change password
description: Changes the current user's password. Requires current password verification.
tags:
- auth
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ChangePasswordRequest'
responses:
"204":
description: Password changed.
"400":
description: Current password wrong or validation failed.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
"401":
description: Not authenticated.
/admin/users:
get:
operationId: listUsers
@@ -493,6 +518,72 @@ paths:
"403":
description: Forbidden (admin only).
/admin/users/{userId}:
put:
operationId: updateUser
summary: Update user (admin only)
description: Updates an existing user by id. Username and role required; password optional (omit to keep current).
tags:
- users
parameters:
- $ref: '#/components/parameters/UserId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateUserRequest'
responses:
"200":
description: User updated.
content:
application/json:
schema:
$ref: '#/components/schemas/UserSummary'
"400":
description: Invalid request (e.g. username already exists).
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
"401":
description: Not authenticated.
"403":
description: Forbidden (admin only).
"404":
description: User not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
delete:
operationId: deleteUser
summary: Delete user (admin only)
description: Deletes a user by id. Cannot delete self or the last admin.
tags:
- users
parameters:
- $ref: '#/components/parameters/UserId'
responses:
"204":
description: User deleted.
"400":
description: Cannot delete self or last admin.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
"401":
description: Not authenticated.
"403":
description: Forbidden (admin only).
"404":
description: User not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
components:
parameters:
@@ -519,6 +610,14 @@ components:
schema:
type: string
format: uuid
UserId:
name: userId
in: path
required: true
description: Unique identifier of the user (UUID).
schema:
type: string
format: uuid
schemas:
@@ -1117,6 +1216,20 @@ components:
- username
- roles
ChangePasswordRequest:
type: object
description: Request to change the current user's password.
properties:
currentPassword:
type: string
description: Current plain-text password (verified before change).
newPassword:
type: string
description: New plain-text password (hashed on server).
required:
- currentPassword
- newPassword
UserSummary:
type: object
description: User without password (for list and create response).
@@ -1163,6 +1276,26 @@ components:
- password
- role
UpdateUserRequest:
type: object
description: Request to update an existing user (admin only). Password optional; omit to keep current.
properties:
username:
type: string
description: Login name.
password:
type: string
description: Optional new plain-text password (omit or blank to keep current).
role:
type: string
enum:
- admin
- user
description: Role to assign.
required:
- username
- role
# ─── Error ────────────────────────────────────────────────────────────────
ErrorResponse: