InvoicePlane stores the user's user_type in the session at login, then uses that session value in Admin_Controller to make administrative authorization decisions instead of revalidating ip_users.user_type from the database on each request.
When administrator Y downgrades administrator X, the database role changes but X's active session is not destroyed or refreshed. The session-update logic handles only the case where the edited account is the currently authenticated account, so X's session continues to carry the administrative state and still passes the Admin_Controller check.
The still-authorized session allows the downgraded user to invoke administrative functionality, including user management. In Users::form(), the controller puts the user_type field from HTTP input back into the record even though the model protects that field. As a result, a user with the stale administrative session can set their own user_type back to 1; the value is written to the database and makes the restored privilege persistent.
The project advisory describes a tested scope of InvoicePlane on CodeIgniter 3 with the files session driver. The public record does not establish that every session configuration or every customized authorization implementation outside that scope behaves identically.