The daemon was returning the login failure error as a plain string instead of the SafeReason object like the API defines, causing the error:
invalid response for read provider login (failure): json: cannot unmarshal string into Go struct field Login.failure of type protocol.SafeReason
This PR fixes that and also logs the real reason a sign-in failed to daemon.log (it was being replaced with a generic message and thrown away before). Additionally this adds the expired state to the robot docs.