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