diff --git a/src/error.rs b/src/error.rs index e2db423..1a3b7ac 100644 --- a/src/error.rs +++ b/src/error.rs @@ -184,6 +184,9 @@ pub enum Error { #[error("Expired APNs certificate")] ApnsCertificateExpired, + #[error("Unknown CA of APNs certificate")] + ApnsCertificateUnknownCA, + #[error("client deleted due to invalid device token")] ClientDeleted, diff --git a/src/handlers/push_message.rs b/src/handlers/push_message.rs index 596b031..a6aecb7 100644 --- a/src/handlers/push_message.rs +++ b/src/handlers/push_message.rs @@ -435,6 +435,23 @@ pub async fn handler_internal( ); Err(Error::TenantSuspended) } + Error::ApnsCertificateUnknownCA => { + let reason = "Unknown APNs certificate's CA"; + state + .tenant_store + .suspend_tenant(&tenant_id, reason) + .await + .map_err(|e| (e, analytics.clone()))?; + increment_counter!(state.metrics, tenant_suspensions); + warn!( + %tenant_id, + client_id = %client_id, + notification_id = %notification.id, + push_type = client.push_type.as_str(), + "tenant has been suspended due to: {reason}" + ); + Err(Error::TenantSuspended) + } Error::BadFcmApiKey => { state .tenant_store diff --git a/src/providers/apns.rs b/src/providers/apns.rs index a306003..86bc63e 100644 --- a/src/providers/apns.rs +++ b/src/providers/apns.rs @@ -150,16 +150,23 @@ impl PushProvider for ApnsProvider { a2::Error::ConnectionError(ref hyper_error) => { let dbg = format!("{hyper_error:?}"); // e.g. Apns(ConnectionError(hyper::Error(Io, Custom { kind: InvalidData, error: "received fatal alert: CertificateExpired" }))) - if dbg.contains("received fatal alert: CertificateExpired") { - // Checking if debug fmt contains something is strange. - // Logging stuff here temporarily so we can determine better - // ways to detect this error (e.g. display). Ideally we can extract - // the error field directly and check if exactly equal to the above - // rather than using contains() - info!("APNs certificate expired: debug:{dbg}, display: {hyper_error}"); - Err(Error::ApnsCertificateExpired) - } else { - Err(Error::Apns(e)) + // Checking if debug fmt contains something is strange. + // Logging stuff here temporarily so we can determine better + // ways to detect this error (e.g. display). Ideally we can extract + // the error field directly and check if exactly equal to the above + // rather than using contains() + match dbg { + dbg if dbg.contains("received fatal alert: CertificateExpired") => { + info!("APNs certificate expired: debug:{dbg}, display: {hyper_error}"); + Err(Error::ApnsCertificateExpired) + } + dbg if dbg.contains("received fatal alert: UnknownCA") => { + info!( + "APNs certificate unknown CA: debug:{dbg}, display: {hyper_error}" + ); + Err(Error::ApnsCertificateUnknownCA) + } + _ => Err(Error::Apns(e)), } } e => Err(Error::Apns(e)),