this repo has no description
1pub mod api;
2pub mod appview;
3pub mod auth;
4pub mod cache;
5pub mod circuit_breaker;
6pub mod config;
7pub mod crawlers;
8pub mod handle;
9pub mod image;
10pub mod metrics;
11pub mod comms;
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.atproto.server.requestEmailUpdate",
207 post(api::server::request_email_update),
208 )
209 .route(
210 "/xrpc/com.atproto.server.confirmEmail",
211 post(api::server::confirm_email),
212 )
213 .route(
214 "/xrpc/com.atproto.server.updateEmail",
215 post(api::server::update_email),
216 )
217 .route(
218 "/xrpc/com.atproto.server.reserveSigningKey",
219 post(api::server::reserve_signing_key),
220 )
221 .route(
222 "/xrpc/com.atproto.identity.updateHandle",
223 post(api::identity::update_handle),
224 )
225 .route(
226 "/xrpc/com.atproto.identity.requestPlcOperationSignature",
227 post(api::identity::request_plc_operation_signature),
228 )
229 .route(
230 "/xrpc/com.atproto.identity.signPlcOperation",
231 post(api::identity::sign_plc_operation),
232 )
233 .route(
234 "/xrpc/com.atproto.identity.submitPlcOperation",
235 post(api::identity::submit_plc_operation),
236 )
237 .route(
238 "/xrpc/com.atproto.repo.importRepo",
239 post(api::repo::import_repo),
240 )
241 .route(
242 "/xrpc/com.atproto.admin.deleteAccount",
243 post(api::admin::delete_account),
244 )
245 .route(
246 "/xrpc/com.atproto.admin.updateAccountEmail",
247 post(api::admin::update_account_email),
248 )
249 .route(
250 "/xrpc/com.atproto.admin.updateAccountHandle",
251 post(api::admin::update_account_handle),
252 )
253 .route(
254 "/xrpc/com.atproto.admin.updateAccountPassword",
255 post(api::admin::update_account_password),
256 )
257 .route(
258 "/xrpc/com.atproto.server.listAppPasswords",
259 get(api::server::list_app_passwords),
260 )
261 .route(
262 "/xrpc/com.atproto.server.createAppPassword",
263 post(api::server::create_app_password),
264 )
265 .route(
266 "/xrpc/com.atproto.server.revokeAppPassword",
267 post(api::server::revoke_app_password),
268 )
269 .route(
270 "/xrpc/com.atproto.server.createInviteCode",
271 post(api::server::create_invite_code),
272 )
273 .route(
274 "/xrpc/com.atproto.server.createInviteCodes",
275 post(api::server::create_invite_codes),
276 )
277 .route(
278 "/xrpc/com.atproto.server.getAccountInviteCodes",
279 get(api::server::get_account_invite_codes),
280 )
281 .route(
282 "/xrpc/com.atproto.admin.getInviteCodes",
283 get(api::admin::get_invite_codes),
284 )
285 .route(
286 "/xrpc/com.tranquil.admin.getServerStats",
287 get(api::admin::get_server_stats),
288 )
289 .route(
290 "/xrpc/com.atproto.admin.disableAccountInvites",
291 post(api::admin::disable_account_invites),
292 )
293 .route(
294 "/xrpc/com.atproto.admin.enableAccountInvites",
295 post(api::admin::enable_account_invites),
296 )
297 .route(
298 "/xrpc/com.atproto.admin.disableInviteCodes",
299 post(api::admin::disable_invite_codes),
300 )
301 .route(
302 "/xrpc/com.atproto.admin.getSubjectStatus",
303 get(api::admin::get_subject_status),
304 )
305 .route(
306 "/xrpc/com.atproto.admin.updateSubjectStatus",
307 post(api::admin::update_subject_status),
308 )
309 .route(
310 "/xrpc/com.atproto.admin.sendEmail",
311 post(api::admin::send_email),
312 )
313 .route(
314 "/xrpc/app.bsky.actor.getPreferences",
315 get(api::actor::get_preferences),
316 )
317 .route(
318 "/xrpc/app.bsky.actor.putPreferences",
319 post(api::actor::put_preferences),
320 )
321 .route("/.well-known/did.json", get(api::identity::well_known_did))
322 .route(
323 "/.well-known/atproto-did",
324 get(api::identity::well_known_atproto_did),
325 )
326 .route("/u/{handle}/did.json", get(api::identity::user_did_doc))
327 .route(
328 "/.well-known/oauth-protected-resource",
329 get(oauth::endpoints::oauth_protected_resource),
330 )
331 .route(
332 "/.well-known/oauth-authorization-server",
333 get(oauth::endpoints::oauth_authorization_server),
334 )
335 .route("/oauth/jwks", get(oauth::endpoints::oauth_jwks))
336 .route(
337 "/oauth/client-metadata.json",
338 get(oauth::endpoints::frontend_client_metadata),
339 )
340 .route(
341 "/oauth/par",
342 post(oauth::endpoints::pushed_authorization_request),
343 )
344 .route("/oauth/authorize", get(oauth::endpoints::authorize_get))
345 .route("/oauth/authorize", post(oauth::endpoints::authorize_post))
346 .route(
347 "/oauth/authorize/select",
348 post(oauth::endpoints::authorize_select),
349 )
350 .route(
351 "/oauth/authorize/2fa",
352 get(oauth::endpoints::authorize_2fa_get),
353 )
354 .route(
355 "/oauth/authorize/2fa",
356 post(oauth::endpoints::authorize_2fa_post),
357 )
358 .route(
359 "/oauth/authorize/deny",
360 post(oauth::endpoints::authorize_deny),
361 )
362 .route("/oauth/token", post(oauth::endpoints::token_endpoint))
363 .route("/oauth/revoke", post(oauth::endpoints::revoke_token))
364 .route(
365 "/oauth/introspect",
366 post(oauth::endpoints::introspect_token),
367 )
368 .route(
369 "/xrpc/com.atproto.temp.checkSignupQueue",
370 get(api::temp::check_signup_queue),
371 )
372 .route(
373 "/xrpc/com.tranquil.account.getNotificationPrefs",
374 get(api::notification_prefs::get_notification_prefs),
375 )
376 .route(
377 "/xrpc/com.tranquil.account.updateNotificationPrefs",
378 post(api::notification_prefs::update_notification_prefs),
379 )
380 .route(
381 "/xrpc/com.tranquil.account.getNotificationHistory",
382 get(api::notification_prefs::get_notification_history),
383 )
384 .route(
385 "/xrpc/com.tranquil.account.confirmChannelVerification",
386 post(api::verification::confirm_channel_verification),
387 )
388 .route("/xrpc/{*method}", any(api::proxy::proxy_handler))
389 .layer(middleware::from_fn(metrics::metrics_middleware))
390 .layer(
391 CorsLayer::new()
392 .allow_origin(Any)
393 .allow_methods([Method::GET, Method::POST, Method::OPTIONS])
394 .allow_headers(Any),
395 )
396 .with_state(state);
397
398 let frontend_dir =
399 std::env::var("FRONTEND_DIR").unwrap_or_else(|_| "./frontend/dist".to_string());
400
401 if std::path::Path::new(&frontend_dir)
402 .join("index.html")
403 .exists()
404 {
405 let index_path = format!("{}/index.html", frontend_dir);
406 let serve_dir = ServeDir::new(&frontend_dir).not_found_service(ServeFile::new(index_path));
407 router.fallback_service(serve_dir)
408 } else {
409 router
410 }
411}