Skip to main content

max / makenotwork

5.1 KB · 79 lines History Blame Raw
1 //! Internal API endpoints for service-to-service communication.
2 //!
3 //! These endpoints are protected by `ServiceAuth` (Bearer token) and are
4 //! called by the CLI SSH server running on the same host.
5
6 mod cli_features;
7 mod content;
8 mod creators;
9 mod git;
10 mod items;
11 mod uploads;
12
13 pub(super) use git::restart_status;
14
15 use axum::routing::get;
16
17 use crate::{
18 csrf::{delete_csrf_skip, post_csrf_skip, put_csrf_skip, with_csrf_skip, CsrfRouter},
19 AppState,
20 };
21
22 /// All routes in this file are HMAC-bearer authed via `ServiceAuth` (no
23 /// session); CSRF is not applicable. Each registration carries the same
24 /// `Skip` reason so the posture is visible at the call site.
25 const INTERNAL_SKIP: &str = "internal API: HMAC bearer auth, no session";
26
27 /// Internal service-to-service routes (ServiceAuth, no rate limit).
28 pub(super) fn internal_routes() -> CsrfRouter<AppState> {
29 CsrfRouter::new()
30 .route_get("/api/internal/ssh-key-lookup", get(git::ssh_key_lookup))
31 .route("/api/internal/creator/projects", with_csrf_skip(INTERNAL_SKIP, get(creators::creator_projects).post(cli_features::create_project)))
32 .route_get("/api/internal/creator/projects/{id}/items", get(creators::creator_project_items))
33 .route_get("/api/internal/creator/stats", get(creators::creator_stats))
34 .route("/api/internal/creator/items", post_csrf_skip(INTERNAL_SKIP, items::create_item))
35 .route("/api/internal/upload/presign", post_csrf_skip(INTERNAL_SKIP, uploads::presign_upload))
36 .route("/api/internal/upload/confirm", post_csrf_skip(INTERNAL_SKIP, uploads::confirm_upload))
37 .route_get("/api/internal/creator/storage", get(uploads::creator_storage))
38 .route_get("/api/internal/creator/items/{id}", get(items::get_item))
39 .route("/api/internal/creator/items/{id}", put_csrf_skip(INTERNAL_SKIP, items::update_item))
40 .route("/api/internal/creator/items/{id}", delete_csrf_skip(INTERNAL_SKIP, items::delete_item))
41 .route("/api/internal/creator/items/{id}/publish", post_csrf_skip(INTERNAL_SKIP, items::publish_item))
42 .route("/api/internal/creator/items/{id}/unpublish", post_csrf_skip(INTERNAL_SKIP, items::unpublish_item))
43 .route_get("/api/internal/creator/items/{id}/versions", get(items::item_versions))
44 // Blog posts
45 .route_get("/api/internal/creator/projects/{id}/blog", get(content::list_blog_posts))
46 .route("/api/internal/creator/blog", post_csrf_skip(INTERNAL_SKIP, content::create_blog_post))
47 .route("/api/internal/creator/blog/{id}", delete_csrf_skip(INTERNAL_SKIP, content::delete_blog_post))
48 // Promo codes
49 .route("/api/internal/creator/promo-codes", with_csrf_skip(INTERNAL_SKIP, get(content::list_promo_codes).post(content::create_promo_code)))
50 .route("/api/internal/creator/promo-codes/{id}", delete_csrf_skip(INTERNAL_SKIP, content::delete_promo_code))
51 // License keys
52 .route("/api/internal/creator/items/{id}/keys", with_csrf_skip(INTERNAL_SKIP, get(content::list_license_keys).post(content::generate_license_key)))
53 .route("/api/internal/creator/keys/{id}/revoke", post_csrf_skip(INTERNAL_SKIP, content::revoke_license_key))
54 // Analytics + export
55 .route_get("/api/internal/creator/analytics", get(creators::creator_analytics))
56 .route_get("/api/internal/creator/transactions", get(creators::creator_transactions))
57 .route_get("/api/internal/creator/export/sales", get(creators::export_sales))
58 // Settings
59 .route_get("/api/internal/creator/ssh-keys", get(git::list_ssh_keys))
60 // Git authorization
61 .route("/api/internal/git/authorize", post_csrf_skip(INTERNAL_SKIP, git::git_authorize))
62 .route("/api/internal/restart-warning", post_csrf_skip(INTERNAL_SKIP, git::set_restart_warning))
63 // CLI features: tags
64 .route_get("/api/internal/creator/items/{id}/tags", get(cli_features::list_item_tags))
65 .route("/api/internal/creator/items/tags", post_csrf_skip(INTERNAL_SKIP, cli_features::add_item_tag))
66 .route("/api/internal/creator/items/tags/remove", post_csrf_skip(INTERNAL_SKIP, cli_features::remove_item_tag))
67 .route_get("/api/internal/tags/search", get(cli_features::search_tags))
68 // CLI features: broadcast
69 .route("/api/internal/creator/broadcast", post_csrf_skip(INTERNAL_SKIP, cli_features::send_broadcast))
70 // CLI features: tiers
71 .route_get("/api/internal/creator/projects/{id}/tiers", get(cli_features::list_tiers))
72 // CLI features: collections
73 .route("/api/internal/creator/collections", with_csrf_skip(INTERNAL_SKIP, get(cli_features::list_collections).post(cli_features::create_collection)))
74 .route("/api/internal/creator/collections/{id}", delete_csrf_skip(INTERNAL_SKIP, cli_features::delete_collection))
75 // CLI features: custom domains
76 .route("/api/internal/creator/domain", with_csrf_skip(INTERNAL_SKIP, get(cli_features::get_domain).post(cli_features::add_domain).delete(cli_features::remove_domain)))
77 .route("/api/internal/creator/domain/verify", post_csrf_skip(INTERNAL_SKIP, cli_features::verify_domain))
78 }
79