this repo has no description
1pub mod api;
2pub mod auth;
3pub mod cache;
4pub mod circuit_breaker;
5pub mod config;
6pub mod crawlers;
7pub mod image;
8pub mod metrics;
9pub mod notifications;
10pub mod oauth;
11pub mod plc;
12pub mod rate_limit;
13pub mod repo;
14pub mod state;
15pub mod storage;
16pub mod sync;
17pub mod util;
18pub mod validation;
19
20use axum::{
21 Router,
22 http::Method,
23 middleware,
24 routing::{any, get, post},
25};
26use state::AppState;
27use tower_http::cors::{Any, CorsLayer};
28use tower_http::services::{ServeDir, ServeFile};
29
30pub fn app(state: AppState) -> Router {
31 let router = Router::new()
32 .route("/metrics", get(metrics::metrics_handler))
33 .route("/health", get(api::server::health))
34 .route("/xrpc/_health", get(api::server::health))
35 .route("/robots.txt", get(api::server::robots_txt))
36 .route(
37 "/xrpc/com.atproto.server.describeServer",
38 get(api::server::describe_server),
39 )
40 .route(
41 "/xrpc/com.atproto.server.createAccount",
42 post(api::identity::create_account),
43 )
44 .route(
45 "/xrpc/com.atproto.server.createSession",
46 post(api::server::create_session),
47 )
48 .route(
49 "/xrpc/com.atproto.server.getSession",
50 get(api::server::get_session),
51 )
52 .route(
53 "/xrpc/com.atproto.server.deleteSession",
54 post(api::server::delete_session),
55 )
56 .route(
57 "/xrpc/com.atproto.server.refreshSession",
58 post(api::server::refresh_session),
59 )
60 .route(
61 "/xrpc/com.atproto.server.confirmSignup",
62 post(api::server::confirm_signup),
63 )
64 .route(
65 "/xrpc/com.atproto.server.resendVerification",
66 post(api::server::resend_verification),
67 )
68 .route(
69 "/xrpc/com.atproto.server.getServiceAuth",
70 get(api::server::get_service_auth),
71 )
72 .route(
73 "/xrpc/com.atproto.identity.resolveHandle",
74 get(api::identity::resolve_handle),
75 )
76 .route(
77 "/xrpc/com.atproto.repo.createRecord",
78 post(api::repo::create_record),
79 )
80 .route(
81 "/xrpc/com.atproto.repo.putRecord",
82 post(api::repo::put_record),
83 )
84 .route(
85 "/xrpc/com.atproto.repo.getRecord",
86 get(api::repo::get_record),
87 )
88 .route(
89 "/xrpc/com.atproto.repo.deleteRecord",
90 post(api::repo::delete_record),
91 )
92 .route(
93 "/xrpc/com.atproto.repo.listRecords",
94 get(api::repo::list_records),
95 )
96 .route(
97 "/xrpc/com.atproto.repo.describeRepo",
98 get(api::repo::describe_repo),
99 )
100 .route(
101 "/xrpc/com.atproto.repo.uploadBlob",
102 post(api::repo::upload_blob),
103 )
104 .route(
105 "/xrpc/com.atproto.repo.applyWrites",
106 post(api::repo::apply_writes),
107 )
108 .route(
109 "/xrpc/com.atproto.sync.getLatestCommit",
110 get(sync::get_latest_commit),
111 )
112 .route("/xrpc/com.atproto.sync.listRepos", get(sync::list_repos))
113 .route("/xrpc/com.atproto.sync.getBlob", get(sync::get_blob))
114 .route("/xrpc/com.atproto.sync.listBlobs", get(sync::list_blobs))
115 .route(
116 "/xrpc/com.atproto.sync.getRepoStatus",
117 get(sync::get_repo_status),
118 )
119 .route(
120 "/xrpc/com.atproto.server.checkAccountStatus",
121 get(api::server::check_account_status),
122 )
123 .route(
124 "/xrpc/com.atproto.identity.getRecommendedDidCredentials",
125 get(api::identity::get_recommended_did_credentials),
126 )
127 .route(
128 "/xrpc/com.atproto.repo.listMissingBlobs",
129 get(api::repo::list_missing_blobs),
130 )
131 .route(
132 "/xrpc/com.atproto.sync.notifyOfUpdate",
133 post(sync::notify_of_update),
134 )
135 .route(
136 "/xrpc/com.atproto.sync.requestCrawl",
137 post(sync::request_crawl),
138 )
139 .route("/xrpc/com.atproto.sync.getBlocks", get(sync::get_blocks))
140 .route("/xrpc/com.atproto.sync.getRepo", get(sync::get_repo))
141 .route("/xrpc/com.atproto.sync.getRecord", get(sync::get_record))
142 .route(
143 "/xrpc/com.atproto.sync.subscribeRepos",
144 get(sync::subscribe_repos),
145 )
146 .route("/xrpc/com.atproto.sync.getHead", get(sync::get_head))
147 .route(
148 "/xrpc/com.atproto.sync.getCheckout",
149 get(sync::get_checkout),
150 )
151 .route(
152 "/xrpc/com.atproto.moderation.createReport",
153 post(api::moderation::create_report),
154 )
155 .route(
156 "/xrpc/com.atproto.admin.getAccountInfo",
157 get(api::admin::get_account_info),
158 )
159 .route(
160 "/xrpc/com.atproto.admin.getAccountInfos",
161 get(api::admin::get_account_infos),
162 )
163 .route(
164 "/xrpc/com.bspds.admin.createProfile",
165 post(api::admin::create_profile),
166 )
167 .route(
168 "/xrpc/com.bspds.admin.createRecord",
169 post(api::admin::create_record_admin),
170 )
171 .route(
172 "/xrpc/com.atproto.server.activateAccount",
173 post(api::server::activate_account),
174 )
175 .route(
176 "/xrpc/com.atproto.server.deactivateAccount",
177 post(api::server::deactivate_account),
178 )
179 .route(
180 "/xrpc/com.atproto.server.requestAccountDelete",
181 post(api::server::request_account_delete),
182 )
183 .route(
184 "/xrpc/com.atproto.server.deleteAccount",
185 post(api::server::delete_account),
186 )
187 .route(
188 "/xrpc/com.atproto.server.requestPasswordReset",
189 post(api::server::request_password_reset),
190 )
191 .route(
192 "/xrpc/com.atproto.server.resetPassword",
193 post(api::server::reset_password),
194 )
195 .route(
196 "/xrpc/com.atproto.server.requestEmailUpdate",
197 post(api::server::request_email_update),
198 )
199 .route(
200 "/xrpc/com.atproto.server.confirmEmail",
201 post(api::server::confirm_email),
202 )
203 .route(
204 "/xrpc/com.atproto.server.updateEmail",
205 post(api::server::update_email),
206 )
207 .route(
208 "/xrpc/com.atproto.server.reserveSigningKey",
209 post(api::server::reserve_signing_key),
210 )
211 .route(
212 "/xrpc/com.atproto.identity.updateHandle",
213 post(api::identity::update_handle),
214 )
215 .route(
216 "/xrpc/com.atproto.identity.requestPlcOperationSignature",
217 post(api::identity::request_plc_operation_signature),
218 )
219 .route(
220 "/xrpc/com.atproto.identity.signPlcOperation",
221 post(api::identity::sign_plc_operation),
222 )
223 .route(
224 "/xrpc/com.atproto.identity.submitPlcOperation",
225 post(api::identity::submit_plc_operation),
226 )
227 .route(
228 "/xrpc/com.atproto.repo.importRepo",
229 post(api::repo::import_repo),
230 )
231 .route(
232 "/xrpc/com.atproto.admin.deleteAccount",
233 post(api::admin::delete_account),
234 )
235 .route(
236 "/xrpc/com.atproto.admin.updateAccountEmail",
237 post(api::admin::update_account_email),
238 )
239 .route(
240 "/xrpc/com.atproto.admin.updateAccountHandle",
241 post(api::admin::update_account_handle),
242 )
243 .route(
244 "/xrpc/com.atproto.admin.updateAccountPassword",
245 post(api::admin::update_account_password),
246 )
247 .route(
248 "/xrpc/com.atproto.server.listAppPasswords",
249 get(api::server::list_app_passwords),
250 )
251 .route(
252 "/xrpc/com.atproto.server.createAppPassword",
253 post(api::server::create_app_password),
254 )
255 .route(
256 "/xrpc/com.atproto.server.revokeAppPassword",
257 post(api::server::revoke_app_password),
258 )
259 .route(
260 "/xrpc/com.atproto.server.createInviteCode",
261 post(api::server::create_invite_code),
262 )
263 .route(
264 "/xrpc/com.atproto.server.createInviteCodes",
265 post(api::server::create_invite_codes),
266 )
267 .route(
268 "/xrpc/com.atproto.server.getAccountInviteCodes",
269 get(api::server::get_account_invite_codes),
270 )
271 .route(
272 "/xrpc/com.atproto.admin.getInviteCodes",
273 get(api::admin::get_invite_codes),
274 )
275 .route(
276 "/xrpc/com.bspds.admin.getServerStats",
277 get(api::admin::get_server_stats),
278 )
279 .route(
280 "/xrpc/com.atproto.admin.disableAccountInvites",
281 post(api::admin::disable_account_invites),
282 )
283 .route(
284 "/xrpc/com.atproto.admin.enableAccountInvites",
285 post(api::admin::enable_account_invites),
286 )
287 .route(
288 "/xrpc/com.atproto.admin.disableInviteCodes",
289 post(api::admin::disable_invite_codes),
290 )
291 .route(
292 "/xrpc/com.atproto.admin.getSubjectStatus",
293 get(api::admin::get_subject_status),
294 )
295 .route(
296 "/xrpc/com.atproto.admin.updateSubjectStatus",
297 post(api::admin::update_subject_status),
298 )
299 .route(
300 "/xrpc/com.atproto.admin.sendEmail",
301 post(api::admin::send_email),
302 )
303 .route(
304 "/xrpc/app.bsky.actor.getPreferences",
305 get(api::actor::get_preferences),
306 )
307 .route(
308 "/xrpc/app.bsky.actor.putPreferences",
309 post(api::actor::put_preferences),
310 )
311 .route(
312 "/xrpc/app.bsky.actor.getProfile",
313 get(api::actor::get_profile),
314 )
315 .route(
316 "/xrpc/app.bsky.actor.getProfiles",
317 get(api::actor::get_profiles),
318 )
319 .route(
320 "/xrpc/app.bsky.feed.getTimeline",
321 get(api::feed::get_timeline),
322 )
323 .route(
324 "/xrpc/app.bsky.feed.getAuthorFeed",
325 get(api::feed::get_author_feed),
326 )
327 .route(
328 "/xrpc/app.bsky.feed.getActorLikes",
329 get(api::feed::get_actor_likes),
330 )
331 .route(
332 "/xrpc/app.bsky.feed.getPostThread",
333 get(api::feed::get_post_thread),
334 )
335 .route("/xrpc/app.bsky.feed.getFeed", get(api::feed::get_feed))
336 .route(
337 "/xrpc/app.bsky.notification.registerPush",
338 post(api::notification::register_push),
339 )
340 .route("/.well-known/did.json", get(api::identity::well_known_did))
341 .route(
342 "/.well-known/atproto-did",
343 get(api::identity::well_known_atproto_did),
344 )
345 .route("/u/{handle}/did.json", get(api::identity::user_did_doc))
346 .route(
347 "/.well-known/oauth-protected-resource",
348 get(oauth::endpoints::oauth_protected_resource),
349 )
350 .route(
351 "/.well-known/oauth-authorization-server",
352 get(oauth::endpoints::oauth_authorization_server),
353 )
354 .route("/oauth/jwks", get(oauth::endpoints::oauth_jwks))
355 .route(
356 "/oauth/par",
357 post(oauth::endpoints::pushed_authorization_request),
358 )
359 .route("/oauth/authorize", get(oauth::endpoints::authorize_get))
360 .route("/oauth/authorize", post(oauth::endpoints::authorize_post))
361 .route(
362 "/oauth/authorize/select",
363 post(oauth::endpoints::authorize_select),
364 )
365 .route(
366 "/oauth/authorize/2fa",
367 get(oauth::endpoints::authorize_2fa_get),
368 )
369 .route(
370 "/oauth/authorize/2fa",
371 post(oauth::endpoints::authorize_2fa_post),
372 )
373 .route(
374 "/oauth/authorize/deny",
375 post(oauth::endpoints::authorize_deny),
376 )
377 .route("/oauth/token", post(oauth::endpoints::token_endpoint))
378 .route("/oauth/revoke", post(oauth::endpoints::revoke_token))
379 .route(
380 "/oauth/introspect",
381 post(oauth::endpoints::introspect_token),
382 )
383 .route(
384 "/xrpc/com.atproto.temp.checkSignupQueue",
385 get(api::temp::check_signup_queue),
386 )
387 .route(
388 "/xrpc/com.bspds.account.getNotificationPrefs",
389 get(api::notification_prefs::get_notification_prefs),
390 )
391 .route(
392 "/xrpc/com.bspds.account.updateNotificationPrefs",
393 post(api::notification_prefs::update_notification_prefs),
394 )
395 .route(
396 "/xrpc/com.bspds.account.getNotificationHistory",
397 get(api::notification_prefs::get_notification_history),
398 )
399 .route(
400 "/xrpc/com.bspds.account.confirmChannelVerification",
401 post(api::verification::confirm_channel_verification),
402 )
403 .route("/xrpc/{*method}", any(api::proxy::proxy_handler))
404 .layer(middleware::from_fn(metrics::metrics_middleware))
405 .layer(
406 CorsLayer::new()
407 .allow_origin(Any)
408 .allow_methods([Method::GET, Method::POST, Method::OPTIONS])
409 .allow_headers(Any),
410 )
411 .with_state(state);
412
413 let frontend_dir =
414 std::env::var("FRONTEND_DIR").unwrap_or_else(|_| "./frontend/dist".to_string());
415
416 if std::path::Path::new(&frontend_dir)
417 .join("index.html")
418 .exists()
419 {
420 let index_path = format!("{}/index.html", frontend_dir);
421 let serve_dir = ServeDir::new(&frontend_dir).not_found_service(ServeFile::new(index_path));
422 router.fallback_service(serve_dir)
423 } else {
424 router
425 }
426}