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