Apps default to private (require login). Marking an app public bypasses the forward_auth check so anyone can access it without logging in. Changes: - db.rs: is_public INTEGER NOT NULL DEFAULT 0 column (idempotent) - models.rs: is_public: i64 on App; is_public: Option<bool> on UpdateApp - Cargo.toml: add reqwest for Caddy admin API calls from Rust - routes/apps.rs: PATCH is_public → save flag + immediately push updated Caddy route (no redeploy needed); caddy_route() builds correct JSON for both public (plain reverse_proxy) and private (forward_auth) cases - builder.rs: pass IS_PUBLIC env var to build.sh - build.sh: use IS_PUBLIC to select route type on deploy - ui.rs + app_detail.html: private/public badge + toggle button in subtitle https://claude.ai/code/session_01FKCW3FDjNFj6jve4niMFXH
126 lines
3 KiB
Rust
126 lines
3 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
|
pub struct App {
|
|
pub id: String,
|
|
pub name: String,
|
|
pub repo_url: String,
|
|
pub branch: String,
|
|
pub port: i64,
|
|
pub webhook_secret: String,
|
|
pub memory_limit: String,
|
|
pub cpu_limit: String,
|
|
pub created_at: String,
|
|
pub updated_at: String,
|
|
/// Encrypted git token for cloning private repos. Never serialised to API responses.
|
|
#[serde(skip_serializing)]
|
|
pub git_token: Option<String>,
|
|
pub is_public: i64,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct CreateApp {
|
|
pub name: String,
|
|
pub repo_url: Option<String>,
|
|
pub branch: Option<String>,
|
|
pub port: i64,
|
|
pub memory_limit: Option<String>,
|
|
pub cpu_limit: Option<String>,
|
|
pub git_token: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct UpdateApp {
|
|
pub repo_url: Option<String>,
|
|
pub branch: Option<String>,
|
|
pub port: Option<i64>,
|
|
pub memory_limit: Option<String>,
|
|
pub cpu_limit: Option<String>,
|
|
pub git_token: Option<String>,
|
|
pub is_public: Option<bool>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
|
pub struct Deploy {
|
|
pub id: String,
|
|
pub app_id: String,
|
|
pub sha: Option<String>,
|
|
pub status: String,
|
|
pub log: String,
|
|
pub triggered_by: String,
|
|
pub started_at: Option<String>,
|
|
pub finished_at: Option<String>,
|
|
pub created_at: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
|
pub struct EnvVar {
|
|
pub app_id: String,
|
|
pub key: String,
|
|
pub value: String,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct SetEnvVar {
|
|
pub key: String,
|
|
pub value: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
|
pub struct User {
|
|
pub id: String,
|
|
pub username: String,
|
|
pub password_hash: String,
|
|
pub is_admin: i64,
|
|
pub created_at: String,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct CreateUser {
|
|
pub username: String,
|
|
pub password: String,
|
|
pub is_admin: Option<bool>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct UpdateUser {
|
|
pub password: Option<String>,
|
|
pub is_admin: Option<bool>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
|
pub struct SshKey {
|
|
pub id: String,
|
|
pub user_id: String,
|
|
pub label: String,
|
|
pub public_key: String,
|
|
pub created_at: String,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct CreateSshKey {
|
|
pub label: String,
|
|
pub public_key: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
|
pub struct ApiKey {
|
|
pub id: String,
|
|
pub user_id: String,
|
|
pub label: String,
|
|
pub created_at: String,
|
|
// key_hash is intentionally not exposed in serialised output
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct CreateApiKey {
|
|
pub label: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
|
pub struct Database {
|
|
pub app_id: String,
|
|
pub pg_user: String,
|
|
pub pg_password: String,
|
|
pub created_at: String,
|
|
}
|