Remove dotenv

This commit is contained in:
Louis Knight-Webb
2025-06-17 19:59:10 -04:00
parent 7f7b6fbc70
commit 56e8f61064
7 changed files with 23 additions and 164 deletions

View File

@@ -73,5 +73,3 @@ Try to build the Typescript project after any frontend changes `npm run build`
SQLX queries should be located in backend/src/models/\*
Use getters and setters instead of raw SQL queries where possible.
DATABASE_URL=sqlite:/Users/louisknight-webb/Documents/mission-control.sqlite

View File

@@ -39,23 +39,13 @@ bloop/
### Installation
1. Install Postgres
2. Configure .env (see template in backend/.env.example)
3. Install dependencies
1. Install dependencies
```bash
# Install dependencies
npm install
```
4. Run SQLX migrations
```bash
cargo sqlx migrate run
```
### Development
```bash

View File

@@ -1,4 +0,0 @@
SSH_ENCRYPTION_KEY="bloop_ssh_key_32_characters_long"
DATABASE_URL=sqlite::memory:
ADMIN_PASSWORD=SOME_DEFAULT_PASSWORD
JWT_SECRET="somesecret"

View File

@@ -21,7 +21,6 @@ tracing-subscriber = { workspace = true }
sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "sqlite", "chrono", "uuid"] }
chrono = { version = "0.4", features = ["serde"] }
uuid = { version = "1.0", features = ["v4", "serde"] }
dotenvy = "0.15"
bcrypt = "0.15"
jsonwebtoken = "9.2"
ts-rs = { version = "9.0", features = ["uuid-impl", "chrono-impl"] }
@@ -31,6 +30,7 @@ async-trait = "0.1"
dissimilar = "1.0"
rust-embed = "8.2"
mime_guess = "2.0"
directories = "6.0.0"
[build-dependencies]
ts-rs = { version = "9.0", features = ["uuid-impl", "chrono-impl"] }

View File

@@ -1,122 +0,0 @@
use axum::{
async_trait,
body::Body,
extract::FromRequestParts,
http::{request::Parts, Request, StatusCode},
middleware::Next,
response::Response,
};
use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};
use sqlx::SqlitePool;
use uuid::Uuid;
#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
pub user_id: Uuid,
pub email: String,
pub is_admin: bool,
pub exp: usize,
}
#[derive(Clone)]
pub struct AuthUser {
pub user_id: Uuid,
pub email: String,
pub is_admin: bool,
}
#[async_trait]
impl<S> FromRequestParts<S> for AuthUser
where
S: Send + Sync,
{
type Rejection = StatusCode;
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
// Get user from request extensions (set by auth middleware)
parts
.extensions
.get::<AuthUser>()
.cloned()
.ok_or(StatusCode::UNAUTHORIZED)
}
}
pub fn create_token(
user_id: Uuid,
email: String,
is_admin: bool,
) -> Result<String, jsonwebtoken::errors::Error> {
let jwt_secret = std::env::var("JWT_SECRET").unwrap_or_else(|_| "your-secret-key".to_string());
let expiration = chrono::Utc::now()
.checked_add_signed(chrono::Duration::hours(24))
.expect("valid timestamp")
.timestamp() as usize;
let claims = Claims {
user_id,
email,
is_admin,
exp: expiration,
};
encode(
&Header::default(),
&claims,
&EncodingKey::from_secret(jwt_secret.as_ref()),
)
}
pub fn hash_password(password: &str) -> Result<String, bcrypt::BcryptError> {
bcrypt::hash(password, bcrypt::DEFAULT_COST)
}
pub fn verify_password(password: &str, hash: &str) -> Result<bool, bcrypt::BcryptError> {
bcrypt::verify(password, hash)
}
// Auth middleware that requires authentication for all routes
pub async fn auth_middleware(
mut request: Request<Body>,
next: Next,
) -> Result<Response, StatusCode> {
let headers = request.headers();
let auth_header = headers
.get("authorization")
.and_then(|value| value.to_str().ok())
.ok_or(StatusCode::UNAUTHORIZED)?;
let token = auth_header
.strip_prefix("Bearer ")
.ok_or(StatusCode::UNAUTHORIZED)?;
let jwt_secret = std::env::var("JWT_SECRET").unwrap_or_else(|_| "your-secret-key".to_string());
let claims = decode::<Claims>(
token,
&DecodingKey::from_secret(jwt_secret.as_ref()),
&Validation::default(),
)
.map_err(|_| StatusCode::UNAUTHORIZED)?
.claims;
// Get database pool from request extensions
let pool = request
.extensions()
.get::<SqlitePool>()
.ok_or(StatusCode::INTERNAL_SERVER_ERROR)?;
// Note: User table removed, skipping database verification
// Add user info to request extensions for handlers to access
request.extensions_mut().insert(AuthUser {
user_id: claims.user_id,
email: claims.email,
is_admin: claims.is_admin,
});
Ok(next.run(request).await)
}

View File

@@ -1,4 +1,3 @@
pub mod auth;
pub mod execution_monitor;
pub mod executor;
pub mod executors;

View File

@@ -6,6 +6,7 @@ use axum::{
routing::{get, post},
Json, Router,
};
use directories::ProjectDirs;
use rust_embed::RustEmbed;
use sqlx::{sqlite::SqliteConnectOptions, SqlitePool};
use std::str::FromStr;
@@ -13,7 +14,6 @@ use std::{collections::HashMap, env, sync::Arc};
use tokio::sync::Mutex;
use tower_http::cors::CorsLayer;
mod auth;
mod execution_monitor;
mod executor;
mod executors;
@@ -83,11 +83,6 @@ async fn serve_file(path: &str) -> impl IntoResponse {
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Load environment variables from .env file
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR")?;
dotenvy::from_path(format!("{manifest_dir}/.env")).ok();
// dotenvy::dotenv().ok();
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::from_default_env()
@@ -95,24 +90,16 @@ async fn main() -> anyhow::Result<()> {
)
.init();
// Create asset directory if it doesn't exist
if !asset_dir().exists() {
std::fs::create_dir_all(asset_dir())?;
}
// Database connection
let database_url =
env::var("DATABASE_URL").expect("DATABASE_URL must be set in environment or .env file");
// if !Sqlite::database_exists(database_url).await.unwrap_or(false) {
// println!("Creating database {}", DB_URL);
// match Sqlite::create_database(DB_URL).await {
// Ok(_) => println!("Create db success"),
// Err(error) => panic!("error: {}", error),
// }
// } else {
// println!("Database already exists");
// }
// let pool = SqlitePoolOptions::new()
// .max_connections(10)
// .connect(&database_url)
// .await?;
let database_url = format!(
"sqlite://{}",
asset_dir().join("db.sqlite").to_string_lossy()
);
let options = SqliteConnectOptions::from_str(&database_url)?.create_if_missing(true);
let pool = SqlitePool::connect_with(options).await?;
@@ -164,3 +151,14 @@ async fn main() -> anyhow::Result<()> {
Ok(())
}
fn asset_dir() -> std::path::PathBuf {
// (“com”, “YourOrg”, “MyApp”) → tweak to suit your bundle ID
let proj = ProjectDirs::from("ai", "bloop", env!("CARGO_PKG_NAME"))
.expect("OS didnt give us a home directory");
// ✔ macOS → ~/Library/Application Support/MyApp
// ✔ Linux → ~/.local/share/myapp (respects XDG_DATA_HOME)
// ✔ Windows → %APPDATA%\Example\MyApp
proj.data_dir().to_path_buf()
}