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