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/com.tranquil.account.listSessions",
61 get(api::server::list_sessions),
62 )
63 .route(
64 "/xrpc/com.tranquil.account.revokeSession",
65 post(api::server::revoke_session),
66 )
67 .route(
68 "/xrpc/com.tranquil.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/com.tranquil.account.changePassword",
212 post(api::server::change_password),
213 )
214 .route(
215 "/xrpc/com.tranquil.account.removePassword",
216 post(api::server::remove_password),
217 )
218 .route(
219 "/xrpc/com.tranquil.account.getPasswordStatus",
220 get(api::server::get_password_status),
221 )
222 .route(
223 "/xrpc/com.tranquil.account.getReauthStatus",
224 get(api::server::get_reauth_status),
225 )
226 .route(
227 "/xrpc/com.tranquil.account.reauthPassword",
228 post(api::server::reauth_password),
229 )
230 .route(
231 "/xrpc/com.tranquil.account.reauthTotp",
232 post(api::server::reauth_totp),
233 )
234 .route(
235 "/xrpc/com.tranquil.account.reauthPasskeyStart",
236 post(api::server::reauth_passkey_start),
237 )
238 .route(
239 "/xrpc/com.tranquil.account.reauthPasskeyFinish",
240 post(api::server::reauth_passkey_finish),
241 )
242 .route(
243 "/xrpc/com.tranquil.account.getLegacyLoginPreference",
244 get(api::server::get_legacy_login_preference),
245 )
246 .route(
247 "/xrpc/com.tranquil.account.updateLegacyLoginPreference",
248 post(api::server::update_legacy_login_preference),
249 )
250 .route(
251 "/xrpc/com.tranquil.account.updateLocale",
252 post(api::server::update_locale),
253 )
254 .route(
255 "/xrpc/com.tranquil.account.listTrustedDevices",
256 get(api::server::list_trusted_devices),
257 )
258 .route(
259 "/xrpc/com.tranquil.account.revokeTrustedDevice",
260 post(api::server::revoke_trusted_device),
261 )
262 .route(
263 "/xrpc/com.tranquil.account.updateTrustedDevice",
264 post(api::server::update_trusted_device),
265 )
266 .route(
267 "/xrpc/com.tranquil.account.createPasskeyAccount",
268 post(api::server::create_passkey_account),
269 )
270 .route(
271 "/xrpc/com.tranquil.account.startPasskeyRegistrationForSetup",
272 post(api::server::start_passkey_registration_for_setup),
273 )
274 .route(
275 "/xrpc/com.tranquil.account.completePasskeySetup",
276 post(api::server::complete_passkey_setup),
277 )
278 .route(
279 "/xrpc/com.tranquil.account.requestPasskeyRecovery",
280 post(api::server::request_passkey_recovery),
281 )
282 .route(
283 "/xrpc/com.tranquil.account.recoverPasskeyAccount",
284 post(api::server::recover_passkey_account),
285 )
286 .route(
287 "/xrpc/com.tranquil.account.getMigrationStatus",
288 get(api::server::get_migration_status),
289 )
290 .route(
291 "/xrpc/com.tranquil.account.updateMigrationForwarding",
292 post(api::server::update_migration_forwarding),
293 )
294 .route(
295 "/xrpc/com.tranquil.account.clearMigrationForwarding",
296 post(api::server::clear_migration_forwarding),
297 )
298 .route(
299 "/xrpc/com.tranquil.account.updateDidDocument",
300 post(api::server::update_did_document),
301 )
302 .route(
303 "/xrpc/com.tranquil.account.getDidDocument",
304 get(api::server::get_did_document),
305 )
306 .route(
307 "/xrpc/com.atproto.server.requestEmailUpdate",
308 post(api::server::request_email_update),
309 )
310 .route(
311 "/xrpc/com.atproto.server.confirmEmail",
312 post(api::server::confirm_email),
313 )
314 .route(
315 "/xrpc/com.atproto.server.updateEmail",
316 post(api::server::update_email),
317 )
318 .route(
319 "/xrpc/com.atproto.server.reserveSigningKey",
320 post(api::server::reserve_signing_key),
321 )
322 .route(
323 "/xrpc/com.atproto.server.verifyMigrationEmail",
324 post(api::server::verify_migration_email),
325 )
326 .route(
327 "/xrpc/com.atproto.server.resendMigrationVerification",
328 post(api::server::resend_migration_verification),
329 )
330 .route(
331 "/xrpc/com.atproto.identity.updateHandle",
332 post(api::identity::update_handle),
333 )
334 .route(
335 "/xrpc/com.atproto.identity.requestPlcOperationSignature",
336 post(api::identity::request_plc_operation_signature),
337 )
338 .route(
339 "/xrpc/com.atproto.identity.signPlcOperation",
340 post(api::identity::sign_plc_operation),
341 )
342 .route(
343 "/xrpc/com.atproto.identity.submitPlcOperation",
344 post(api::identity::submit_plc_operation),
345 )
346 .route(
347 "/xrpc/com.atproto.repo.importRepo",
348 post(api::repo::import_repo),
349 )
350 .route(
351 "/xrpc/com.atproto.admin.deleteAccount",
352 post(api::admin::delete_account),
353 )
354 .route(
355 "/xrpc/com.atproto.admin.updateAccountEmail",
356 post(api::admin::update_account_email),
357 )
358 .route(
359 "/xrpc/com.atproto.admin.updateAccountHandle",
360 post(api::admin::update_account_handle),
361 )
362 .route(
363 "/xrpc/com.atproto.admin.updateAccountPassword",
364 post(api::admin::update_account_password),
365 )
366 .route(
367 "/xrpc/com.atproto.server.listAppPasswords",
368 get(api::server::list_app_passwords),
369 )
370 .route(
371 "/xrpc/com.atproto.server.createAppPassword",
372 post(api::server::create_app_password),
373 )
374 .route(
375 "/xrpc/com.atproto.server.revokeAppPassword",
376 post(api::server::revoke_app_password),
377 )
378 .route(
379 "/xrpc/com.atproto.server.createInviteCode",
380 post(api::server::create_invite_code),
381 )
382 .route(
383 "/xrpc/com.atproto.server.createInviteCodes",
384 post(api::server::create_invite_codes),
385 )
386 .route(
387 "/xrpc/com.atproto.server.getAccountInviteCodes",
388 get(api::server::get_account_invite_codes),
389 )
390 .route(
391 "/xrpc/com.atproto.server.createTotpSecret",
392 post(api::server::create_totp_secret),
393 )
394 .route(
395 "/xrpc/com.atproto.server.enableTotp",
396 post(api::server::enable_totp),
397 )
398 .route(
399 "/xrpc/com.atproto.server.disableTotp",
400 post(api::server::disable_totp),
401 )
402 .route(
403 "/xrpc/com.atproto.server.getTotpStatus",
404 get(api::server::get_totp_status),
405 )
406 .route(
407 "/xrpc/com.atproto.server.regenerateBackupCodes",
408 post(api::server::regenerate_backup_codes),
409 )
410 .route(
411 "/xrpc/com.atproto.server.startPasskeyRegistration",
412 post(api::server::start_passkey_registration),
413 )
414 .route(
415 "/xrpc/com.atproto.server.finishPasskeyRegistration",
416 post(api::server::finish_passkey_registration),
417 )
418 .route(
419 "/xrpc/com.atproto.server.listPasskeys",
420 get(api::server::list_passkeys),
421 )
422 .route(
423 "/xrpc/com.atproto.server.deletePasskey",
424 post(api::server::delete_passkey),
425 )
426 .route(
427 "/xrpc/com.atproto.server.updatePasskey",
428 post(api::server::update_passkey),
429 )
430 .route(
431 "/xrpc/com.atproto.admin.getInviteCodes",
432 get(api::admin::get_invite_codes),
433 )
434 .route(
435 "/xrpc/com.tranquil.admin.getServerStats",
436 get(api::admin::get_server_stats),
437 )
438 .route(
439 "/xrpc/com.tranquil.server.getConfig",
440 get(api::admin::get_server_config),
441 )
442 .route(
443 "/xrpc/com.tranquil.admin.updateServerConfig",
444 post(api::admin::update_server_config),
445 )
446 .route(
447 "/xrpc/com.atproto.admin.disableAccountInvites",
448 post(api::admin::disable_account_invites),
449 )
450 .route(
451 "/xrpc/com.atproto.admin.enableAccountInvites",
452 post(api::admin::enable_account_invites),
453 )
454 .route(
455 "/xrpc/com.atproto.admin.disableInviteCodes",
456 post(api::admin::disable_invite_codes),
457 )
458 .route(
459 "/xrpc/com.atproto.admin.getSubjectStatus",
460 get(api::admin::get_subject_status),
461 )
462 .route(
463 "/xrpc/com.atproto.admin.updateSubjectStatus",
464 post(api::admin::update_subject_status),
465 )
466 .route(
467 "/xrpc/com.atproto.admin.sendEmail",
468 post(api::admin::send_email),
469 )
470 .route(
471 "/xrpc/app.bsky.actor.getPreferences",
472 get(api::actor::get_preferences),
473 )
474 .route(
475 "/xrpc/app.bsky.actor.putPreferences",
476 post(api::actor::put_preferences),
477 )
478 .route("/.well-known/did.json", get(api::identity::well_known_did))
479 .route(
480 "/.well-known/atproto-did",
481 get(api::identity::well_known_atproto_did),
482 )
483 .route("/u/{handle}/did.json", get(api::identity::user_did_doc))
484 .route(
485 "/.well-known/oauth-protected-resource",
486 get(oauth::endpoints::oauth_protected_resource),
487 )
488 .route(
489 "/.well-known/oauth-authorization-server",
490 get(oauth::endpoints::oauth_authorization_server),
491 )
492 .route("/oauth/jwks", get(oauth::endpoints::oauth_jwks))
493 .route(
494 "/oauth/client-metadata.json",
495 get(oauth::endpoints::frontend_client_metadata),
496 )
497 .route(
498 "/oauth/par",
499 post(oauth::endpoints::pushed_authorization_request),
500 )
501 .route("/oauth/authorize", get(oauth::endpoints::authorize_get))
502 .route("/oauth/authorize", post(oauth::endpoints::authorize_post))
503 .route(
504 "/oauth/authorize/accounts",
505 get(oauth::endpoints::authorize_accounts),
506 )
507 .route(
508 "/oauth/authorize/select",
509 post(oauth::endpoints::authorize_select),
510 )
511 .route(
512 "/oauth/authorize/2fa",
513 get(oauth::endpoints::authorize_2fa_get),
514 )
515 .route(
516 "/oauth/authorize/2fa",
517 post(oauth::endpoints::authorize_2fa_post),
518 )
519 .route(
520 "/oauth/authorize/passkey",
521 get(oauth::endpoints::authorize_passkey_start),
522 )
523 .route(
524 "/oauth/authorize/passkey",
525 post(oauth::endpoints::authorize_passkey_finish),
526 )
527 .route(
528 "/oauth/passkey/check",
529 get(oauth::endpoints::check_user_has_passkeys),
530 )
531 .route(
532 "/oauth/security-status",
533 get(oauth::endpoints::check_user_security_status),
534 )
535 .route(
536 "/oauth/passkey/start",
537 post(oauth::endpoints::passkey_start),
538 )
539 .route(
540 "/oauth/passkey/finish",
541 post(oauth::endpoints::passkey_finish),
542 )
543 .route(
544 "/oauth/authorize/deny",
545 post(oauth::endpoints::authorize_deny),
546 )
547 .route(
548 "/oauth/authorize/consent",
549 get(oauth::endpoints::consent_get),
550 )
551 .route(
552 "/oauth/authorize/consent",
553 post(oauth::endpoints::consent_post),
554 )
555 .route(
556 "/oauth/delegation/auth",
557 post(oauth::endpoints::delegation_auth),
558 )
559 .route(
560 "/oauth/delegation/totp",
561 post(oauth::endpoints::delegation_totp_verify),
562 )
563 .route("/oauth/token", post(oauth::endpoints::token_endpoint))
564 .route("/oauth/revoke", post(oauth::endpoints::revoke_token))
565 .route(
566 "/oauth/introspect",
567 post(oauth::endpoints::introspect_token),
568 )
569 .route(
570 "/xrpc/com.atproto.temp.checkSignupQueue",
571 get(api::temp::check_signup_queue),
572 )
573 .route(
574 "/xrpc/com.atproto.temp.dereferenceScope",
575 post(api::temp::dereference_scope),
576 )
577 .route(
578 "/xrpc/com.tranquil.account.getNotificationPrefs",
579 get(api::notification_prefs::get_notification_prefs),
580 )
581 .route(
582 "/xrpc/com.tranquil.account.updateNotificationPrefs",
583 post(api::notification_prefs::update_notification_prefs),
584 )
585 .route(
586 "/xrpc/com.tranquil.account.getNotificationHistory",
587 get(api::notification_prefs::get_notification_history),
588 )
589 .route(
590 "/xrpc/com.tranquil.account.confirmChannelVerification",
591 post(api::verification::confirm_channel_verification),
592 )
593 .route(
594 "/xrpc/com.tranquil.account.verifyToken",
595 post(api::server::verify_token),
596 )
597 .route(
598 "/xrpc/com.tranquil.delegation.listControllers",
599 get(api::delegation::list_controllers),
600 )
601 .route(
602 "/xrpc/com.tranquil.delegation.addController",
603 post(api::delegation::add_controller),
604 )
605 .route(
606 "/xrpc/com.tranquil.delegation.removeController",
607 post(api::delegation::remove_controller),
608 )
609 .route(
610 "/xrpc/com.tranquil.delegation.updateControllerScopes",
611 post(api::delegation::update_controller_scopes),
612 )
613 .route(
614 "/xrpc/com.tranquil.delegation.listControlledAccounts",
615 get(api::delegation::list_controlled_accounts),
616 )
617 .route(
618 "/xrpc/com.tranquil.delegation.getAuditLog",
619 get(api::delegation::get_audit_log),
620 )
621 .route(
622 "/xrpc/com.tranquil.delegation.getScopePresets",
623 get(api::delegation::get_scope_presets),
624 )
625 .route(
626 "/xrpc/com.tranquil.delegation.createDelegatedAccount",
627 post(api::delegation::create_delegated_account),
628 )
629 .route(
630 "/xrpc/app.bsky.ageassurance.getState",
631 get(api::age_assurance::get_state),
632 )
633 .route(
634 "/xrpc/app.bsky.unspecced.getAgeAssuranceState",
635 get(api::age_assurance::get_age_assurance_state),
636 )
637 .route("/xrpc/{*method}", any(api::proxy::proxy_handler))
638 .layer(DefaultBodyLimit::max(util::get_max_blob_size()))
639 .layer(middleware::from_fn(metrics::metrics_middleware))
640 .layer(
641 CorsLayer::new()
642 .allow_origin(Any)
643 .allow_methods([Method::GET, Method::POST, Method::OPTIONS])
644 .allow_headers(Any),
645 )
646 .with_state(state);
647
648 let frontend_dir =
649 std::env::var("FRONTEND_DIR").unwrap_or_else(|_| "./frontend/dist".to_string());
650
651 if std::path::Path::new(&frontend_dir)
652 .join("index.html")
653 .exists()
654 {
655 let index_path = format!("{}/index.html", frontend_dir);
656 let serve_dir = ServeDir::new(&frontend_dir).not_found_service(ServeFile::new(index_path));
657 router.fallback_service(serve_dir)
658 } else {
659 router
660 }
661}