feat(api): name response code 2028 as Blocked

Proton answers a blocked sign-in on auth/v4 with HTTP 422 and code 2028,
"feature is disabled, rate-limited or blocked because of abuse". Its
Error text says the app version is no longer supported, which is wrong
for a current client. The code fell through to Unknown, so a client
could not tell it from a real OutdatedApp and showed the misleading text.
This commit is contained in:
nvrl committed 2026-10-13 20:22:55 +02:00
1 parent 56d7b15115
commit 92c6dffb5a
1 file changed
+17
+17
View File
@@ -129,6 +129,11 @@ pub enum ResponseCode {
InvalidValue = 2001,
NotEnoughPermissions = 2011,
NotEnoughPermissionsToGrantPermissions = 2026,
/// The feature is disabled, rate-limited or blocked for abuse. Arrives with
/// HTTP 422. On `auth/v4` it is a temporary block on the sign-in, and its
/// `Error` text claims the app version is no longer supported even when
/// it is.
Blocked = 2028,
InvalidEncryptedIdFormat = 2061,
AlreadyExists = 2500,
DoesNotExist = 2501,
@@ -175,6 +180,7 @@ impl ResponseCode {
2001 => Self::InvalidValue,
2011 => Self::NotEnoughPermissions,
2026 => Self::NotEnoughPermissionsToGrantPermissions,
2028 => Self::Blocked,
2061 => Self::InvalidEncryptedIdFormat,
2500 => Self::AlreadyExists,
2501 => Self::DoesNotExist,
@@ -246,6 +252,17 @@ mod tests {
assert_eq!(envelope.code, ResponseCode::HumanVerificationRequired);
}
/// A blocked sign-in claims the app is outdated. Only the code tells it
/// apart from a real [`ResponseCode::OutdatedApp`].
#[test]
fn a_blocked_login_is_not_an_outdated_app() {
let envelope: ApiResponse = serde_json::from_str(
r#"{"Code": 2028, "Error": "This version of the app is no longer supported, please update to continue using the app"}"#,
)
.unwrap();
assert_eq!(envelope.code, ResponseCode::Blocked);
}
#[test]
fn the_challenge_is_read_off_the_details_object() {
let hv = gated_error()