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