Shared state

This commit is contained in:
Andras Schmelczer 2026-03-17 21:08:32 +00:00
parent 53fff3efaa
commit 15fa09430b
25 changed files with 174 additions and 215 deletions

View file

@ -1,6 +1,6 @@
use std::sync::Arc;
use axum::extract::Path;
use axum::extract::{Path, State};
use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
use axum::{Extension, Json};
@ -9,7 +9,7 @@ use tracing::{info, warn};
use crate::auth::OptionalUser;
use crate::pocketbase::auth_superuser;
use crate::state::AppState;
use crate::state::SharedState;
#[derive(Serialize)]
struct InviteResponse {
@ -90,10 +90,11 @@ fn generate_invite_code() -> String {
/// Create an invite. Admins create "admin" invites (free license) by default,
/// but can explicitly request "referral" type. Licensed non-admin users always create "referral" invites (30% off).
pub async fn post_invites(
state: Arc<AppState>,
State(shared): State<Arc<SharedState>>,
Extension(user): Extension<OptionalUser>,
Json(body): Json<CreateInviteRequest>,
) -> Response {
let state = shared.load_state();
let user = match user.0 {
Some(u) => u,
None => return StatusCode::UNAUTHORIZED.into_response(),
@ -179,10 +180,11 @@ const DEV_INVITE_CODE: &str = "devdevdevdev";
/// Validate an invite code. Public endpoint — codes are 12-char random alphanumeric
/// so enumeration is impractical, and the response only reveals valid/invalid + type.
pub async fn get_invite(
state: Arc<AppState>,
State(shared): State<Arc<SharedState>>,
Extension(_user): Extension<OptionalUser>,
Path(code): Path<String>,
) -> Response {
let state = shared.load_state();
if let Err(msg) = validate_invite_code(&code) {
return (StatusCode::BAD_REQUEST, msg).into_response();
}
@ -297,10 +299,11 @@ pub async fn get_invite(
/// Admin invite: sets subscription to "licensed" directly.
/// Referral invite: returns a discounted Stripe checkout URL.
pub async fn post_redeem_invite(
state: Arc<AppState>,
State(shared): State<Arc<SharedState>>,
Extension(user): Extension<OptionalUser>,
Json(req): Json<RedeemRequest>,
) -> Response {
let state = shared.load_state();
let user = match user.0 {
Some(u) => u,
None => return StatusCode::UNAUTHORIZED.into_response(),
@ -486,9 +489,10 @@ pub async fn post_redeem_invite(
/// List invites. Admins see all invites; licensed users see only their own.
pub async fn get_invites(
state: Arc<AppState>,
State(shared): State<Arc<SharedState>>,
Extension(user): Extension<OptionalUser>,
) -> Response {
let state = shared.load_state();
let user = match user.0 {
Some(u) => u,
None => return StatusCode::UNAUTHORIZED.into_response(),