Hostityourself/server/src/models.rs
Claude 0b3cbf8734
feat: private repo support via encrypted git token
- db.rs: add nullable git_token column (idempotent ALTER TABLE ADD COLUMN)
- models.rs: git_token on App (#[serde(skip_serializing)]), CreateApp, UpdateApp
- routes/apps.rs: encrypt token on create/update; empty string clears it
- builder.rs: decrypt token, pass as GIT_TOKEN env var to build script
- build.sh: GIT_TERMINAL_PROMPT=0 (fail fast, not hang); when GIT_TOKEN is
  set, inject it into the HTTPS clone URL as x-token-auth; strip credentials
  from .git/config after clone/fetch so the token is never persisted to disk

Token usage: PATCH /api/apps/:id with {"git_token": "ghp_..."}
Clear token:  PATCH /api/apps/:id with {"git_token": ""}

https://claude.ai/code/session_01FKCW3FDjNFj6jve4niMFXH
2026-03-26 08:24:55 +00:00

124 lines
2.9 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>,
}
#[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>,
}
#[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,
}