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(
113 "/xrpc/com.atproto.sync.listRepos",
114 get(sync::list_repos),
115 )
116 .route(
117 "/xrpc/com.atproto.sync.getBlob",
118 get(sync::get_blob),
119 )
120 .route(
121 "/xrpc/com.atproto.sync.listBlobs",
122 get(sync::list_blobs),
123 )
124 .route(
125 "/xrpc/com.atproto.sync.getRepoStatus",
126 get(sync::get_repo_status),
127 )
128 .route(
129 "/xrpc/com.atproto.server.checkAccountStatus",
130 get(api::server::check_account_status),
131 )
132 .route(
133 "/xrpc/com.atproto.identity.getRecommendedDidCredentials",
134 get(api::identity::get_recommended_did_credentials),
135 )
136 .route(
137 "/xrpc/com.atproto.repo.listMissingBlobs",
138 get(api::repo::list_missing_blobs),
139 )
140 .route(
141 "/xrpc/com.atproto.sync.notifyOfUpdate",
142 post(sync::notify_of_update),
143 )
144 .route(
145 "/xrpc/com.atproto.sync.requestCrawl",
146 post(sync::request_crawl),
147 )
148 .route(
149 "/xrpc/com.atproto.sync.getBlocks",
150 get(sync::get_blocks),
151 )
152 .route(
153 "/xrpc/com.atproto.sync.getRepo",
154 get(sync::get_repo),
155 )
156 .route(
157 "/xrpc/com.atproto.sync.getRecord",
158 get(sync::get_record),
159 )
160 .route(
161 "/xrpc/com.atproto.sync.subscribeRepos",
162 get(sync::subscribe_repos),
163 )
164 .route(
165 "/xrpc/com.atproto.sync.getHead",
166 get(sync::get_head),
167 )
168 .route(
169 "/xrpc/com.atproto.sync.getCheckout",
170 get(sync::get_checkout),
171 )
172 .route(
173 "/xrpc/com.atproto.moderation.createReport",
174 post(api::moderation::create_report),
175 )
176 .route(
177 "/xrpc/com.atproto.admin.getAccountInfo",
178 get(api::admin::get_account_info),
179 )
180 .route(
181 "/xrpc/com.atproto.admin.getAccountInfos",
182 get(api::admin::get_account_infos),
183 )
184 .route(
185 "/xrpc/com.bspds.admin.createProfile",
186 post(api::admin::create_profile),
187 )
188 .route(
189 "/xrpc/com.bspds.admin.createRecord",
190 post(api::admin::create_record_admin),
191 )
192 .route(
193 "/xrpc/com.atproto.server.activateAccount",
194 post(api::server::activate_account),
195 )
196 .route(
197 "/xrpc/com.atproto.server.deactivateAccount",
198 post(api::server::deactivate_account),
199 )
200 .route(
201 "/xrpc/com.atproto.server.requestAccountDelete",
202 post(api::server::request_account_delete),
203 )
204 .route(
205 "/xrpc/com.atproto.server.deleteAccount",
206 post(api::server::delete_account),
207 )
208 .route(
209 "/xrpc/com.atproto.server.requestPasswordReset",
210 post(api::server::request_password_reset),
211 )
212 .route(
213 "/xrpc/com.atproto.server.resetPassword",
214 post(api::server::reset_password),
215 )
216 .route(
217 "/xrpc/com.atproto.server.requestEmailUpdate",
218 post(api::server::request_email_update),
219 )
220 .route(
221 "/xrpc/com.atproto.server.confirmEmail",
222 post(api::server::confirm_email),
223 )
224 .route(
225 "/xrpc/com.atproto.server.updateEmail",
226 post(api::server::update_email),
227 )
228 .route(
229 "/xrpc/com.atproto.server.reserveSigningKey",
230 post(api::server::reserve_signing_key),
231 )
232 .route(
233 "/xrpc/com.atproto.identity.updateHandle",
234 post(api::identity::update_handle),
235 )
236 .route(
237 "/xrpc/com.atproto.identity.requestPlcOperationSignature",
238 post(api::identity::request_plc_operation_signature),
239 )
240 .route(
241 "/xrpc/com.atproto.identity.signPlcOperation",
242 post(api::identity::sign_plc_operation),
243 )
244 .route(
245 "/xrpc/com.atproto.identity.submitPlcOperation",
246 post(api::identity::submit_plc_operation),
247 )
248 .route(
249 "/xrpc/com.atproto.repo.importRepo",
250 post(api::repo::import_repo),
251 )
252 .route(
253 "/xrpc/com.atproto.admin.deleteAccount",
254 post(api::admin::delete_account),
255 )
256 .route(
257 "/xrpc/com.atproto.admin.updateAccountEmail",
258 post(api::admin::update_account_email),
259 )
260 .route(
261 "/xrpc/com.atproto.admin.updateAccountHandle",
262 post(api::admin::update_account_handle),
263 )
264 .route(
265 "/xrpc/com.atproto.admin.updateAccountPassword",
266 post(api::admin::update_account_password),
267 )
268 .route(
269 "/xrpc/com.atproto.server.listAppPasswords",
270 get(api::server::list_app_passwords),
271 )
272 .route(
273 "/xrpc/com.atproto.server.createAppPassword",
274 post(api::server::create_app_password),
275 )
276 .route(
277 "/xrpc/com.atproto.server.revokeAppPassword",
278 post(api::server::revoke_app_password),
279 )
280 .route(
281 "/xrpc/com.atproto.server.createInviteCode",
282 post(api::server::create_invite_code),
283 )
284 .route(
285 "/xrpc/com.atproto.server.createInviteCodes",
286 post(api::server::create_invite_codes),
287 )
288 .route(
289 "/xrpc/com.atproto.server.getAccountInviteCodes",
290 get(api::server::get_account_invite_codes),
291 )
292 .route(
293 "/xrpc/com.atproto.admin.getInviteCodes",
294 get(api::admin::get_invite_codes),
295 )
296 .route(
297 "/xrpc/com.atproto.admin.disableAccountInvites",
298 post(api::admin::disable_account_invites),
299 )
300 .route(
301 "/xrpc/com.atproto.admin.enableAccountInvites",
302 post(api::admin::enable_account_invites),
303 )
304 .route(
305 "/xrpc/com.atproto.admin.disableInviteCodes",
306 post(api::admin::disable_invite_codes),
307 )
308 .route(
309 "/xrpc/com.atproto.admin.getSubjectStatus",
310 get(api::admin::get_subject_status),
311 )
312 .route(
313 "/xrpc/com.atproto.admin.updateSubjectStatus",
314 post(api::admin::update_subject_status),
315 )
316 .route(
317 "/xrpc/com.atproto.admin.sendEmail",
318 post(api::admin::send_email),
319 )
320 .route(
321 "/xrpc/app.bsky.actor.getPreferences",
322 get(api::actor::get_preferences),
323 )
324 .route(
325 "/xrpc/app.bsky.actor.putPreferences",
326 post(api::actor::put_preferences),
327 )
328 .route(
329 "/xrpc/app.bsky.actor.getProfile",
330 get(api::actor::get_profile),
331 )
332 .route(
333 "/xrpc/app.bsky.actor.getProfiles",
334 get(api::actor::get_profiles),
335 )
336 .route(
337 "/xrpc/app.bsky.feed.getTimeline",
338 get(api::feed::get_timeline),
339 )
340 .route(
341 "/xrpc/app.bsky.feed.getAuthorFeed",
342 get(api::feed::get_author_feed),
343 )
344 .route(
345 "/xrpc/app.bsky.feed.getActorLikes",
346 get(api::feed::get_actor_likes),
347 )
348 .route(
349 "/xrpc/app.bsky.feed.getPostThread",
350 get(api::feed::get_post_thread),
351 )
352 .route(
353 "/xrpc/app.bsky.feed.getFeed",
354 get(api::feed::get_feed),
355 )
356 .route(
357 "/xrpc/app.bsky.notification.registerPush",
358 post(api::notification::register_push),
359 )
360 .route("/.well-known/did.json", get(api::identity::well_known_did))
361 .route("/.well-known/atproto-did", get(api::identity::well_known_atproto_did))
362 .route("/u/{handle}/did.json", get(api::identity::user_did_doc))
363 .route(
364 "/.well-known/oauth-protected-resource",
365 get(oauth::endpoints::oauth_protected_resource),
366 )
367 .route(
368 "/.well-known/oauth-authorization-server",
369 get(oauth::endpoints::oauth_authorization_server),
370 )
371 .route("/oauth/jwks", get(oauth::endpoints::oauth_jwks))
372 .route(
373 "/oauth/par",
374 post(oauth::endpoints::pushed_authorization_request),
375 )
376 .route("/oauth/authorize", get(oauth::endpoints::authorize_get))
377 .route("/oauth/authorize", post(oauth::endpoints::authorize_post))
378 .route("/oauth/authorize/select", post(oauth::endpoints::authorize_select))
379 .route("/oauth/authorize/2fa", get(oauth::endpoints::authorize_2fa_get))
380 .route("/oauth/authorize/2fa", post(oauth::endpoints::authorize_2fa_post))
381 .route("/oauth/authorize/deny", post(oauth::endpoints::authorize_deny))
382 .route("/oauth/token", post(oauth::endpoints::token_endpoint))
383 .route("/oauth/revoke", post(oauth::endpoints::revoke_token))
384 .route("/oauth/introspect", post(oauth::endpoints::introspect_token))
385 .route(
386 "/xrpc/com.atproto.temp.checkSignupQueue",
387 get(api::temp::check_signup_queue),
388 )
389 .route(
390 "/xrpc/com.bspds.account.getNotificationPrefs",
391 get(api::notification_prefs::get_notification_prefs),
392 )
393 .route(
394 "/xrpc/com.bspds.account.updateNotificationPrefs",
395 post(api::notification_prefs::update_notification_prefs),
396 )
397 .route("/xrpc/{*method}", any(api::proxy::proxy_handler))
398 .layer(middleware::from_fn(metrics::metrics_middleware))
399 .layer(
400 CorsLayer::new()
401 .allow_origin(Any)
402 .allow_methods([Method::GET, Method::POST, Method::OPTIONS])
403 .allow_headers(Any),
404 )
405 .with_state(state);
406
407 let frontend_dir = std::env::var("FRONTEND_DIR")
408 .unwrap_or_else(|_| "./frontend/dist".to_string());
409
410 if std::path::Path::new(&frontend_dir).join("index.html").exists() {
411 let index_path = format!("{}/index.html", frontend_dir);
412 let serve_dir = ServeDir::new(&frontend_dir)
413 .not_found_service(ServeFile::new(index_path));
414 router.fallback_service(serve_dir)
415 } else {
416 router
417 }
418}