v0.12.4: Per-user audit trail, RBAC fixes, and Ansible collection v0.5.0
WarmDesk v0.12.18 adds a per-user audit trail to the admin panel, closes three security gaps, ships Ansible collection v0.5.0 with three new modules, and makes dialogs resizable to any width.
Per-user audit trail
Every user in the admin panel now has a Login History tab. It records every authentication and security-sensitive action for that account, along with the IP address, client (User-Agent), and timestamp of the request.
Events tracked
| Event | When it is recorded |
|---|---|
| Successful password or passkey login |
| Failed login attempt |
| Explicit logout |
| Silent access-token renewal |
| User changed their own password |
| User changed their email address |
| TOTP was enabled |
| TOTP was disabled |
| WebAuthn passkey added |
| WebAuthn passkey removed |
| API key generated |
| API key revoked |
| Admin created this account |
| Admin edited this user’s profile or role |
| Admin soft-deleted this user |
| Admin restored this user from soft-delete |
| Admin permanently deleted this user |
| Admin reset this user’s MFA |
Performed by column
The Performed by column distinguishes self-actions from admin-on-behalf actions. For events triggered by the user themselves (password change, logout, etc.) the column is blank. For events triggered by an admin acting on the account (user creation, role change, MFA reset, etc.) it shows the admin’s username.
This makes it straightforward to answer questions like "who changed this user’s role last Tuesday?" or "did the user delete their own passkey, or did an admin remove it?"
RBAC fixes
Customer-role users blocked from inbox ticket writes
The helpdesk inbox routes (PUT and DELETE /api/v1/tickets/inbox/:id) were missing a role check that the customer-scoped ticket routes already had.
Users with the customer global role could call these endpoints to update or delete any inbox ticket.
Both handlers now reject customer-role requests with HTTP 403 before reading the ticket.
ListContracts IDOR fixed
GET /api/v1/customers/:id/contracts was missing a customer-access check.
Any authenticated user could enumerate contracts for any customer by supplying an arbitrary customer ID — even customers they had no access to.
The handler now calls requireCustomerAccess and returns HTTP 403 if the requesting user has neither direct nor group-based access to the customer.
Project API keys require owner role
Creating or deleting a project API key previously required only member role.
A project member could generate keys and use them to automate actions with the project owner’s effective permissions.
Both endpoints now require owner role (or global admin) to match the privilege level the key grants.
Ansible collection v0.5.0
The WarmDesk Ansible collection has been updated to v0.5.0 with three new modules and an extended warmdesk_user module.
New module: warmdesk_epic
Manages Scrum epics within a project.
- name: Create a Q3 delivery epic
ansilabnl.warmdesk.warmdesk_epic:
warmdesk_url: "https://desk.example.com"
warmdesk_token: "{{ api_token }}"
project: my-project
name: "Q3 Delivery"
color: "#4f8ef7"
status: open
state: presentIdempotency is keyed on project slug + name.
Set status: closed to close an existing epic in the same task.
New module: warmdesk_sprint
Full sprint lifecycle management — create, update, and transition sprints between planning, active, and completed.
- name: Start the current sprint
ansilabnl.warmdesk.warmdesk_sprint:
warmdesk_url: "https://desk.example.com"
warmdesk_token: "{{ api_token }}"
project: my-project
name: "Sprint 42"
status: active
state: presentStatus transitions are validated: planning → active and active → completed are allowed; invalid jumps (e.g. planning → completed) fail the task with a clear error.
New module: warmdesk_ticket_checklist_template
Admin CRUD for reusable ticket checklist templates.
- name: Ensure onboarding checklist template
ansilabnl.warmdesk.warmdesk_ticket_checklist_template:
warmdesk_url: "https://desk.example.com"
warmdesk_token: "{{ api_token }}"
name: "New customer onboarding"
items:
- "Send welcome email"
- "Create project board"
- "Schedule kick-off call"
is_active: true
state: presentExtended warmdesk_user: restore and purge
warmdesk_user now accepts two additional state values:
| State | Effect |
|---|---|
| Re-activates a soft-deleted user. Fails if the user is not found at all; is a no-op if the account is already active. |
| Permanently and irreversibly deletes the user record. Searches active users first, then soft-deleted users. Is a no-op if the user is not found. |
- name: Restore a previously deleted account
ansilabnl.warmdesk.warmdesk_user:
warmdesk_url: "https://desk.example.com"
warmdesk_token: "{{ api_token }}"
username: alice
state: restore
- name: Permanently remove a test account
ansilabnl.warmdesk.warmdesk_user:
warmdesk_url: "https://desk.example.com"
warmdesk_token: "{{ api_token }}"
username: test-user
state: purgeFlexible modal widths
BaseModal now accepts a width prop that overrides the default 560 px maximum width.
Any valid CSS length or calc() expression is accepted.
The Login History modal uses min(95vw, 1080px) so the actor, IP, and client columns all fit without horizontal scrolling.
This prop is available to custom integrations and themes that embed WarmDesk modals.
Upgrade
Download v0.12.18 from the download page or pull the latest release tag.
No manual database changes are required. New columns and settings are applied automatically on first boot via GORM AutoMigrate.