//! ActivePush - Exchange ActiveSync gateway for IMAP/SMTP + CalDAV/CardDAV (Z-Push rewrite). pub mod admin; pub mod app; pub mod autodiscover; pub mod backend; pub mod config; pub mod db; pub mod eas; pub mod logging; pub mod metrics; pub mod probe; pub mod server; pub mod tls; pub mod util; pub mod wbxml; pub mod xmltree; use std::sync::Arc; use axum::routing::any; use axum::Router; /// Public (device facing) router: ActiveSync + Autodiscover. Paths match the nginx /// locations previously routed to Z-Push. pub fn public_router(app: Arc) -> Router { Router::new() .route("/Microsoft-Server-ActiveSync", any(eas::handler)) .route("/microsoft-server-activesync", any(eas::handler)) .route("/AutoDiscover/AutoDiscover.xml", any(autodiscover::handler)) .route("/Autodiscover/Autodiscover.xml", any(autodiscover::handler)) .route("/autodiscover/autodiscover.xml", any(autodiscover::handler)) .route("/healthz", axum::routing::get(healthz)) .route("/", axum::routing::get(index)) .fallback(not_found) .with_state(app) } async fn index() -> impl axum::response::IntoResponse { ( [("Content-Type", "text/plain; charset=utf-8")], "ActivePush - Exchange ActiveSync endpoint.\nDevices connect to /Microsoft-Server-ActiveSync.\n", ) } async fn not_found() -> impl axum::response::IntoResponse { ( axum::http::StatusCode::NOT_FOUND, [("Content-Type", "text/plain; charset=utf-8")], "Not found.\n", ) } /// Liveness + database check for load balancers and monitoring. async fn healthz( axum::extract::State(app): axum::extract::State>, ) -> impl axum::response::IntoResponse { match sqlx::query_scalar::<_, i64>("SELECT 1") .fetch_one(&app.db) .await { Ok(_) => (axum::http::StatusCode::OK, "ok\n"), Err(_) => ( axum::http::StatusCode::SERVICE_UNAVAILABLE, "database unavailable\n", ), } }