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