If expected fields are deleted rather than reset to empty, those fields
will not be resubmitted in future requests, resulting in the content of
those requests not accurately representing true client-side login state.
For example, if a user receives an insufficient credentials error due to
their password expiring, failing to provide any new password should
result in at least the following fields:
1. Their original username (part of the initial login attempt)
2. Their original password (part of the initial login attempt)
3. Their new password (empty)
If fields are incorrectly reset to null, those fields will not be
submitted, resulting instead in a request containing only:
1. Their original username (part of the initial login attempt)
2. Their original password (part of the initial login attempt)
which is indistinguishable from a normal login attempt.
Firefox, and perhaps other browsers, does not fire a keyup event for
keys involved in submitting a form. This results in the enter key being
stuck in a pressed state if it is used to submit Guacamole's login
form.
Keyboard state should be reset whenever keyboard state cannot be
reliably maintained. This is already done for loss of window focus, but
should also be done for form submission (this specific case) and
navigation to a different page (generic catch-all).
Creating a new injector re-initializes services and providers within
its modules. If those services or providers rely on being singletons
(as colorPickerService does), this produces unexpected behavior.
Enclosing the entire field within the <label> results in problems when
the field is large and when the field contains multiple interactive
elements. Clicking within interactive elements of a complex field
triggers the <label>, refocusing the first input element. If the field
is large, the <label> will contain empty space which also refocuses the
input field upon being clicked, despite appearing to be the background
of the page.
$evalAsync() does not necessarily guarantee execution within a timer;
the provided function may well execute after the current $digest loop
without control returning to the browser. If we need a timer to ensure
focus() behaves reliably, we should explicitly use one via $timeout.
There is an unassignable expression in the form directive that was being assinged a value by the guacFocus directive. The part that deals with this assigning is removed since no part of the app is relying upon this feature.