fixed guardian login edge cases and misleading placeholders on failed loads
This commit is contained in:
@@ -30,8 +30,10 @@ class AuthGuardianRequestResponse {
|
||||
}
|
||||
|
||||
/// Starts a passwordless guardian login: the server mails a code and a link.
|
||||
/// The answer is identical for unknown addresses, so it reveals nothing about
|
||||
/// which e-mails are registered.
|
||||
/// An unknown address is reported as such (`email_not_registered`) instead of
|
||||
/// being answered like a known one — a deliberate trade: without it guardians
|
||||
/// wait for a mail that never arrives. Registered addresses are therefore
|
||||
/// enumerable; keep that in mind when changing the server contract.
|
||||
class AuthGuardianRequest extends MarianumConnectQuery {
|
||||
AuthGuardianRequest({Dio? dio})
|
||||
: super(dio: dio ?? MarianumConnectApi.plainDio());
|
||||
@@ -52,7 +54,7 @@ class AuthGuardianRequest extends MarianumConnectQuery {
|
||||
);
|
||||
return AuthGuardianRequestResponse.fromJson(response.data!);
|
||||
} on DioException catch (e) {
|
||||
throw GuardianLoginException.fromDio(e);
|
||||
throw GuardianLoginException.fromDio(e, verifying: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,14 +31,17 @@ class GuardianLoginException extends AppException {
|
||||
/// Maps a failed guardian auth call. Only 4xx answers that carry a guardian
|
||||
/// login reason become [GuardianLoginException]; everything else keeps the
|
||||
/// generic MarianumConnect mapping (network, 5xx, …).
|
||||
static AppException fromDio(DioException e) {
|
||||
///
|
||||
/// [verifying] false marks the e-mail step, where no code exists yet: a bare
|
||||
/// 401 (reverse proxy, gateway) must not be reported as a wrong code there.
|
||||
static AppException fromDio(DioException e, {bool verifying = true}) {
|
||||
final response = e.response;
|
||||
final status = response?.statusCode;
|
||||
if (status == null || status < 400 || status >= 500) {
|
||||
return mapMarianumConnectError(e);
|
||||
}
|
||||
final (code, attemptsLeft) = _parseBody(response!.data);
|
||||
final error = _errorFor(code, status);
|
||||
final error = _errorFor(code, status, verifying: verifying);
|
||||
if (error == null) return mapMarianumConnectError(e);
|
||||
return GuardianLoginException(
|
||||
error,
|
||||
@@ -89,8 +92,11 @@ class GuardianLoginException extends AppException {
|
||||
return (marianumConnectErrorCode(data), attempts is int ? attempts : null);
|
||||
}
|
||||
|
||||
static GuardianLoginError? _errorFor(String? code, int status) =>
|
||||
switch (code) {
|
||||
static GuardianLoginError? _errorFor(
|
||||
String? code,
|
||||
int status, {
|
||||
required bool verifying,
|
||||
}) => switch (code) {
|
||||
'invalid_request' => GuardianLoginError.invalidRequest,
|
||||
'email_not_registered' => GuardianLoginError.emailNotRegistered,
|
||||
'account_disabled' => GuardianLoginError.accountDisabled,
|
||||
@@ -100,7 +106,7 @@ class GuardianLoginException extends AppException {
|
||||
'request_expired' => GuardianLoginError.requestExpired,
|
||||
'too_many_attempts' => GuardianLoginError.tooManyAttempts,
|
||||
_ => switch (status) {
|
||||
401 => GuardianLoginError.invalidCode,
|
||||
401 when verifying => GuardianLoginError.invalidCode,
|
||||
// The server names an unknown address explicitly
|
||||
// (`email_not_registered`); a bare 404/405 means the endpoint itself
|
||||
// is missing, i.e. a server version without guardian login.
|
||||
|
||||
Reference in New Issue
Block a user