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