this repo has no description
1pub mod api; 2pub mod appview; 3pub mod auth; 4pub mod cache; 5pub mod circuit_breaker; 6pub mod comms; 7pub mod config; 8pub mod crawlers; 9pub mod delegation; 10pub mod handle; 11pub mod image; 12pub mod metrics; 13pub mod moderation; 14pub mod oauth; 15pub mod plc; 16pub mod rate_limit; 17pub mod repo; 18pub mod scheduled; 19pub mod state; 20pub mod storage; 21pub mod sync; 22pub mod util; 23pub mod validation; 24 25use axum::{ 26 Router, 27 extract::DefaultBodyLimit, 28 http::Method, 29 middleware, 30 routing::{any, get, post}, 31}; 32use state::AppState; 33use tower_http::cors::{Any, CorsLayer}; 34use tower_http::services::{ServeDir, ServeFile}; 35 36pub fn app(state: AppState) -> Router { 37 let router = Router::new() 38 .route("/metrics", get(metrics::metrics_handler)) 39 .route("/health", get(api::server::health)) 40 .route("/xrpc/_health", get(api::server::health)) 41 .route("/robots.txt", get(api::server::robots_txt)) 42 .route("/logo", get(api::server::get_logo)) 43 .route( 44 "/xrpc/com.atproto.server.describeServer", 45 get(api::server::describe_server), 46 ) 47 .route( 48 "/xrpc/com.atproto.server.createAccount", 49 post(api::identity::create_account), 50 ) 51 .route( 52 "/xrpc/com.atproto.server.createSession", 53 post(api::server::create_session), 54 ) 55 .route( 56 "/xrpc/com.atproto.server.getSession", 57 get(api::server::get_session), 58 ) 59 .route( 60 "/xrpc/_account.listSessions", 61 get(api::server::list_sessions), 62 ) 63 .route( 64 "/xrpc/_account.revokeSession", 65 post(api::server::revoke_session), 66 ) 67 .route( 68 "/xrpc/_account.revokeAllSessions", 69 post(api::server::revoke_all_sessions), 70 ) 71 .route( 72 "/xrpc/com.atproto.server.deleteSession", 73 post(api::server::delete_session), 74 ) 75 .route( 76 "/xrpc/com.atproto.server.refreshSession", 77 post(api::server::refresh_session), 78 ) 79 .route( 80 "/xrpc/com.atproto.server.confirmSignup", 81 post(api::server::confirm_signup), 82 ) 83 .route( 84 "/xrpc/com.atproto.server.resendVerification", 85 post(api::server::resend_verification), 86 ) 87 .route( 88 "/xrpc/com.atproto.server.getServiceAuth", 89 get(api::server::get_service_auth), 90 ) 91 .route( 92 "/xrpc/com.atproto.identity.resolveHandle", 93 get(api::identity::resolve_handle), 94 ) 95 .route( 96 "/xrpc/com.atproto.repo.createRecord", 97 post(api::repo::create_record), 98 ) 99 .route( 100 "/xrpc/com.atproto.repo.putRecord", 101 post(api::repo::put_record), 102 ) 103 .route( 104 "/xrpc/com.atproto.repo.getRecord", 105 get(api::repo::get_record), 106 ) 107 .route( 108 "/xrpc/com.atproto.repo.deleteRecord", 109 post(api::repo::delete_record), 110 ) 111 .route( 112 "/xrpc/com.atproto.repo.listRecords", 113 get(api::repo::list_records), 114 ) 115 .route( 116 "/xrpc/com.atproto.repo.describeRepo", 117 get(api::repo::describe_repo), 118 ) 119 .route( 120 "/xrpc/com.atproto.repo.uploadBlob", 121 post(api::repo::upload_blob), 122 ) 123 .route( 124 "/xrpc/com.atproto.repo.applyWrites", 125 post(api::repo::apply_writes), 126 ) 127 .route( 128 "/xrpc/com.atproto.sync.getLatestCommit", 129 get(sync::get_latest_commit), 130 ) 131 .route("/xrpc/com.atproto.sync.listRepos", get(sync::list_repos)) 132 .route("/xrpc/com.atproto.sync.getBlob", get(sync::get_blob)) 133 .route("/xrpc/com.atproto.sync.listBlobs", get(sync::list_blobs)) 134 .route( 135 "/xrpc/com.atproto.sync.getRepoStatus", 136 get(sync::get_repo_status), 137 ) 138 .route( 139 "/xrpc/com.atproto.server.checkAccountStatus", 140 get(api::server::check_account_status), 141 ) 142 .route( 143 "/xrpc/com.atproto.identity.getRecommendedDidCredentials", 144 get(api::identity::get_recommended_did_credentials), 145 ) 146 .route( 147 "/xrpc/com.atproto.repo.listMissingBlobs", 148 get(api::repo::list_missing_blobs), 149 ) 150 .route( 151 "/xrpc/com.atproto.sync.notifyOfUpdate", 152 post(sync::notify_of_update), 153 ) 154 .route( 155 "/xrpc/com.atproto.sync.requestCrawl", 156 post(sync::request_crawl), 157 ) 158 .route("/xrpc/com.atproto.sync.getBlocks", get(sync::get_blocks)) 159 .route("/xrpc/com.atproto.sync.getRepo", get(sync::get_repo)) 160 .route("/xrpc/com.atproto.sync.getRecord", get(sync::get_record)) 161 .route( 162 "/xrpc/com.atproto.sync.subscribeRepos", 163 get(sync::subscribe_repos), 164 ) 165 .route("/xrpc/com.atproto.sync.getHead", get(sync::get_head)) 166 .route( 167 "/xrpc/com.atproto.sync.getCheckout", 168 get(sync::get_checkout), 169 ) 170 .route( 171 "/xrpc/com.atproto.moderation.createReport", 172 post(api::moderation::create_report), 173 ) 174 .route( 175 "/xrpc/com.atproto.admin.getAccountInfo", 176 get(api::admin::get_account_info), 177 ) 178 .route( 179 "/xrpc/com.atproto.admin.getAccountInfos", 180 get(api::admin::get_account_infos), 181 ) 182 .route( 183 "/xrpc/com.atproto.admin.searchAccounts", 184 get(api::admin::search_accounts), 185 ) 186 .route( 187 "/xrpc/com.atproto.server.activateAccount", 188 post(api::server::activate_account), 189 ) 190 .route( 191 "/xrpc/com.atproto.server.deactivateAccount", 192 post(api::server::deactivate_account), 193 ) 194 .route( 195 "/xrpc/com.atproto.server.requestAccountDelete", 196 post(api::server::request_account_delete), 197 ) 198 .route( 199 "/xrpc/com.atproto.server.deleteAccount", 200 post(api::server::delete_account), 201 ) 202 .route( 203 "/xrpc/com.atproto.server.requestPasswordReset", 204 post(api::server::request_password_reset), 205 ) 206 .route( 207 "/xrpc/com.atproto.server.resetPassword", 208 post(api::server::reset_password), 209 ) 210 .route( 211 "/xrpc/_account.changePassword", 212 post(api::server::change_password), 213 ) 214 .route( 215 "/xrpc/_account.removePassword", 216 post(api::server::remove_password), 217 ) 218 .route( 219 "/xrpc/_account.getPasswordStatus", 220 get(api::server::get_password_status), 221 ) 222 .route( 223 "/xrpc/_account.getReauthStatus", 224 get(api::server::get_reauth_status), 225 ) 226 .route( 227 "/xrpc/_account.reauthPassword", 228 post(api::server::reauth_password), 229 ) 230 .route("/xrpc/_account.reauthTotp", post(api::server::reauth_totp)) 231 .route( 232 "/xrpc/_account.reauthPasskeyStart", 233 post(api::server::reauth_passkey_start), 234 ) 235 .route( 236 "/xrpc/_account.reauthPasskeyFinish", 237 post(api::server::reauth_passkey_finish), 238 ) 239 .route( 240 "/xrpc/_account.getLegacyLoginPreference", 241 get(api::server::get_legacy_login_preference), 242 ) 243 .route( 244 "/xrpc/_account.updateLegacyLoginPreference", 245 post(api::server::update_legacy_login_preference), 246 ) 247 .route( 248 "/xrpc/_account.updateLocale", 249 post(api::server::update_locale), 250 ) 251 .route( 252 "/xrpc/_account.listTrustedDevices", 253 get(api::server::list_trusted_devices), 254 ) 255 .route( 256 "/xrpc/_account.revokeTrustedDevice", 257 post(api::server::revoke_trusted_device), 258 ) 259 .route( 260 "/xrpc/_account.updateTrustedDevice", 261 post(api::server::update_trusted_device), 262 ) 263 .route( 264 "/xrpc/_account.createPasskeyAccount", 265 post(api::server::create_passkey_account), 266 ) 267 .route( 268 "/xrpc/_account.startPasskeyRegistrationForSetup", 269 post(api::server::start_passkey_registration_for_setup), 270 ) 271 .route( 272 "/xrpc/_account.completePasskeySetup", 273 post(api::server::complete_passkey_setup), 274 ) 275 .route( 276 "/xrpc/_account.requestPasskeyRecovery", 277 post(api::server::request_passkey_recovery), 278 ) 279 .route( 280 "/xrpc/_account.recoverPasskeyAccount", 281 post(api::server::recover_passkey_account), 282 ) 283 .route( 284 "/xrpc/_account.updateDidDocument", 285 post(api::server::update_did_document), 286 ) 287 .route( 288 "/xrpc/_account.getDidDocument", 289 get(api::server::get_did_document), 290 ) 291 .route( 292 "/xrpc/com.atproto.server.requestEmailUpdate", 293 post(api::server::request_email_update), 294 ) 295 .route( 296 "/xrpc/_checkEmailVerified", 297 post(api::server::check_email_verified), 298 ) 299 .route( 300 "/xrpc/com.atproto.server.confirmEmail", 301 post(api::server::confirm_email), 302 ) 303 .route( 304 "/xrpc/com.atproto.server.updateEmail", 305 post(api::server::update_email), 306 ) 307 .route( 308 "/xrpc/com.atproto.server.reserveSigningKey", 309 post(api::server::reserve_signing_key), 310 ) 311 .route( 312 "/xrpc/com.atproto.server.verifyMigrationEmail", 313 post(api::server::verify_migration_email), 314 ) 315 .route( 316 "/xrpc/com.atproto.server.resendMigrationVerification", 317 post(api::server::resend_migration_verification), 318 ) 319 .route( 320 "/xrpc/com.atproto.identity.updateHandle", 321 post(api::identity::update_handle), 322 ) 323 .route( 324 "/xrpc/com.atproto.identity.requestPlcOperationSignature", 325 post(api::identity::request_plc_operation_signature), 326 ) 327 .route( 328 "/xrpc/com.atproto.identity.signPlcOperation", 329 post(api::identity::sign_plc_operation), 330 ) 331 .route( 332 "/xrpc/com.atproto.identity.submitPlcOperation", 333 post(api::identity::submit_plc_operation), 334 ) 335 .route( 336 "/xrpc/com.atproto.repo.importRepo", 337 post(api::repo::import_repo), 338 ) 339 .route( 340 "/xrpc/com.atproto.admin.deleteAccount", 341 post(api::admin::delete_account), 342 ) 343 .route( 344 "/xrpc/com.atproto.admin.updateAccountEmail", 345 post(api::admin::update_account_email), 346 ) 347 .route( 348 "/xrpc/com.atproto.admin.updateAccountHandle", 349 post(api::admin::update_account_handle), 350 ) 351 .route( 352 "/xrpc/com.atproto.admin.updateAccountPassword", 353 post(api::admin::update_account_password), 354 ) 355 .route( 356 "/xrpc/com.atproto.server.listAppPasswords", 357 get(api::server::list_app_passwords), 358 ) 359 .route( 360 "/xrpc/com.atproto.server.createAppPassword", 361 post(api::server::create_app_password), 362 ) 363 .route( 364 "/xrpc/com.atproto.server.revokeAppPassword", 365 post(api::server::revoke_app_password), 366 ) 367 .route( 368 "/xrpc/com.atproto.server.createInviteCode", 369 post(api::server::create_invite_code), 370 ) 371 .route( 372 "/xrpc/com.atproto.server.createInviteCodes", 373 post(api::server::create_invite_codes), 374 ) 375 .route( 376 "/xrpc/com.atproto.server.getAccountInviteCodes", 377 get(api::server::get_account_invite_codes), 378 ) 379 .route( 380 "/xrpc/com.atproto.server.createTotpSecret", 381 post(api::server::create_totp_secret), 382 ) 383 .route( 384 "/xrpc/com.atproto.server.enableTotp", 385 post(api::server::enable_totp), 386 ) 387 .route( 388 "/xrpc/com.atproto.server.disableTotp", 389 post(api::server::disable_totp), 390 ) 391 .route( 392 "/xrpc/com.atproto.server.getTotpStatus", 393 get(api::server::get_totp_status), 394 ) 395 .route( 396 "/xrpc/com.atproto.server.regenerateBackupCodes", 397 post(api::server::regenerate_backup_codes), 398 ) 399 .route( 400 "/xrpc/com.atproto.server.startPasskeyRegistration", 401 post(api::server::start_passkey_registration), 402 ) 403 .route( 404 "/xrpc/com.atproto.server.finishPasskeyRegistration", 405 post(api::server::finish_passkey_registration), 406 ) 407 .route( 408 "/xrpc/com.atproto.server.listPasskeys", 409 get(api::server::list_passkeys), 410 ) 411 .route( 412 "/xrpc/com.atproto.server.deletePasskey", 413 post(api::server::delete_passkey), 414 ) 415 .route( 416 "/xrpc/com.atproto.server.updatePasskey", 417 post(api::server::update_passkey), 418 ) 419 .route( 420 "/xrpc/com.atproto.admin.getInviteCodes", 421 get(api::admin::get_invite_codes), 422 ) 423 .route( 424 "/xrpc/_admin.getServerStats", 425 get(api::admin::get_server_stats), 426 ) 427 .route( 428 "/xrpc/_server.getConfig", 429 get(api::admin::get_server_config), 430 ) 431 .route( 432 "/xrpc/_admin.updateServerConfig", 433 post(api::admin::update_server_config), 434 ) 435 .route( 436 "/xrpc/com.atproto.admin.disableAccountInvites", 437 post(api::admin::disable_account_invites), 438 ) 439 .route( 440 "/xrpc/com.atproto.admin.enableAccountInvites", 441 post(api::admin::enable_account_invites), 442 ) 443 .route( 444 "/xrpc/com.atproto.admin.disableInviteCodes", 445 post(api::admin::disable_invite_codes), 446 ) 447 .route( 448 "/xrpc/com.atproto.admin.getSubjectStatus", 449 get(api::admin::get_subject_status), 450 ) 451 .route( 452 "/xrpc/com.atproto.admin.updateSubjectStatus", 453 post(api::admin::update_subject_status), 454 ) 455 .route( 456 "/xrpc/com.atproto.admin.sendEmail", 457 post(api::admin::send_email), 458 ) 459 .route( 460 "/xrpc/app.bsky.actor.getPreferences", 461 get(api::actor::get_preferences), 462 ) 463 .route( 464 "/xrpc/app.bsky.actor.putPreferences", 465 post(api::actor::put_preferences), 466 ) 467 .route("/.well-known/did.json", get(api::identity::well_known_did)) 468 .route( 469 "/.well-known/atproto-did", 470 get(api::identity::well_known_atproto_did), 471 ) 472 .route("/u/{handle}/did.json", get(api::identity::user_did_doc)) 473 .route( 474 "/.well-known/oauth-protected-resource", 475 get(oauth::endpoints::oauth_protected_resource), 476 ) 477 .route( 478 "/.well-known/oauth-authorization-server", 479 get(oauth::endpoints::oauth_authorization_server), 480 ) 481 .route("/oauth/jwks", get(oauth::endpoints::oauth_jwks)) 482 .route( 483 "/oauth/client-metadata.json", 484 get(oauth::endpoints::frontend_client_metadata), 485 ) 486 .route( 487 "/oauth/par", 488 post(oauth::endpoints::pushed_authorization_request), 489 ) 490 .route("/oauth/authorize", get(oauth::endpoints::authorize_get)) 491 .route("/oauth/authorize", post(oauth::endpoints::authorize_post)) 492 .route( 493 "/oauth/authorize/accounts", 494 get(oauth::endpoints::authorize_accounts), 495 ) 496 .route( 497 "/oauth/authorize/select", 498 post(oauth::endpoints::authorize_select), 499 ) 500 .route( 501 "/oauth/authorize/2fa", 502 get(oauth::endpoints::authorize_2fa_get), 503 ) 504 .route( 505 "/oauth/authorize/2fa", 506 post(oauth::endpoints::authorize_2fa_post), 507 ) 508 .route( 509 "/oauth/authorize/passkey", 510 get(oauth::endpoints::authorize_passkey_start), 511 ) 512 .route( 513 "/oauth/authorize/passkey", 514 post(oauth::endpoints::authorize_passkey_finish), 515 ) 516 .route( 517 "/oauth/passkey/check", 518 get(oauth::endpoints::check_user_has_passkeys), 519 ) 520 .route( 521 "/oauth/security-status", 522 get(oauth::endpoints::check_user_security_status), 523 ) 524 .route( 525 "/oauth/passkey/start", 526 post(oauth::endpoints::passkey_start), 527 ) 528 .route( 529 "/oauth/passkey/finish", 530 post(oauth::endpoints::passkey_finish), 531 ) 532 .route( 533 "/oauth/authorize/deny", 534 post(oauth::endpoints::authorize_deny), 535 ) 536 .route( 537 "/oauth/authorize/consent", 538 get(oauth::endpoints::consent_get), 539 ) 540 .route( 541 "/oauth/authorize/consent", 542 post(oauth::endpoints::consent_post), 543 ) 544 .route( 545 "/oauth/delegation/auth", 546 post(oauth::endpoints::delegation_auth), 547 ) 548 .route( 549 "/oauth/delegation/totp", 550 post(oauth::endpoints::delegation_totp_verify), 551 ) 552 .route("/oauth/token", post(oauth::endpoints::token_endpoint)) 553 .route("/oauth/revoke", post(oauth::endpoints::revoke_token)) 554 .route( 555 "/oauth/introspect", 556 post(oauth::endpoints::introspect_token), 557 ) 558 .route( 559 "/xrpc/com.atproto.temp.checkSignupQueue", 560 get(api::temp::check_signup_queue), 561 ) 562 .route( 563 "/xrpc/com.atproto.temp.dereferenceScope", 564 post(api::temp::dereference_scope), 565 ) 566 .route( 567 "/xrpc/_account.getNotificationPrefs", 568 get(api::notification_prefs::get_notification_prefs), 569 ) 570 .route( 571 "/xrpc/_account.updateNotificationPrefs", 572 post(api::notification_prefs::update_notification_prefs), 573 ) 574 .route( 575 "/xrpc/_account.getNotificationHistory", 576 get(api::notification_prefs::get_notification_history), 577 ) 578 .route( 579 "/xrpc/_account.confirmChannelVerification", 580 post(api::verification::confirm_channel_verification), 581 ) 582 .route( 583 "/xrpc/_account.verifyToken", 584 post(api::server::verify_token), 585 ) 586 .route( 587 "/xrpc/_delegation.listControllers", 588 get(api::delegation::list_controllers), 589 ) 590 .route( 591 "/xrpc/_delegation.addController", 592 post(api::delegation::add_controller), 593 ) 594 .route( 595 "/xrpc/_delegation.removeController", 596 post(api::delegation::remove_controller), 597 ) 598 .route( 599 "/xrpc/_delegation.updateControllerScopes", 600 post(api::delegation::update_controller_scopes), 601 ) 602 .route( 603 "/xrpc/_delegation.listControlledAccounts", 604 get(api::delegation::list_controlled_accounts), 605 ) 606 .route( 607 "/xrpc/_delegation.getAuditLog", 608 get(api::delegation::get_audit_log), 609 ) 610 .route( 611 "/xrpc/_delegation.getScopePresets", 612 get(api::delegation::get_scope_presets), 613 ) 614 .route( 615 "/xrpc/_delegation.createDelegatedAccount", 616 post(api::delegation::create_delegated_account), 617 ) 618 .route("/xrpc/_backup.listBackups", get(api::backup::list_backups)) 619 .route("/xrpc/_backup.getBackup", get(api::backup::get_backup)) 620 .route( 621 "/xrpc/_backup.createBackup", 622 post(api::backup::create_backup), 623 ) 624 .route( 625 "/xrpc/_backup.deleteBackup", 626 post(api::backup::delete_backup), 627 ) 628 .route( 629 "/xrpc/_backup.setEnabled", 630 post(api::backup::set_backup_enabled), 631 ) 632 .route("/xrpc/_backup.exportBlobs", get(api::backup::export_blobs)) 633 .route( 634 "/xrpc/app.bsky.ageassurance.getState", 635 get(api::age_assurance::get_state), 636 ) 637 .route( 638 "/xrpc/app.bsky.unspecced.getAgeAssuranceState", 639 get(api::age_assurance::get_age_assurance_state), 640 ) 641 .route("/xrpc/{*method}", any(api::proxy::proxy_handler)) 642 .layer(DefaultBodyLimit::max(util::get_max_blob_size())) 643 .layer(middleware::from_fn(metrics::metrics_middleware)) 644 .layer( 645 CorsLayer::new() 646 .allow_origin(Any) 647 .allow_methods([Method::GET, Method::POST, Method::OPTIONS]) 648 .allow_headers(Any), 649 ) 650 .with_state(state); 651 652 let frontend_dir = 653 std::env::var("FRONTEND_DIR").unwrap_or_else(|_| "./frontend/dist".to_string()); 654 655 if std::path::Path::new(&frontend_dir) 656 .join("index.html") 657 .exists() 658 { 659 let index_path = format!("{}/index.html", frontend_dir); 660 let homepage_path = format!("{}/homepage.html", frontend_dir); 661 662 let homepage_exists = std::path::Path::new(&homepage_path).exists(); 663 let homepage_file = if homepage_exists { 664 homepage_path 665 } else { 666 index_path.clone() 667 }; 668 669 let spa_router = Router::new().fallback_service(ServeFile::new(&index_path)); 670 671 let serve_dir = ServeDir::new(&frontend_dir).not_found_service(ServeFile::new(&index_path)); 672 673 router 674 .route_service("/", ServeFile::new(&homepage_file)) 675 .nest("/app", spa_router) 676 .fallback_service(serve_dir) 677 } else { 678 router 679 } 680}