Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions v0.5/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions v0.5/fastn-account/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ fastn-mail.workspace = true
fastn-router.workspace = true
fastn-fbr.workspace = true
autosurgeon.workspace = true

# Include directory for embedded fastn-home content
include_dir = "0.7"
serde.workspace = true
serde_json.workspace = true
thiserror.workspace = true
Expand Down
106 changes: 106 additions & 0 deletions v0.5/fastn-account/src/account/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,16 @@ impl fastn_account::Account {

tracing::info!("Created new account with primary alias: {}", id52);

// Copy default UI content from fastn-home/src to account/public
copy_src_to_public(&account_path)
.await
.map_err(|e| {
tracing::warn!("Failed to copy UI content: {}", e);
// Don't fail account creation if UI copy fails
e
})
.ok();

// Create account instance
Ok(Self {
path: std::sync::Arc::new(account_path),
Expand Down Expand Up @@ -232,3 +242,99 @@ impl fastn_account::Account {
Ok(())
}
}

/// Copy default UI content from fastn-home/src to account/public
async fn copy_src_to_public(
account_path: &std::path::Path,
) -> Result<(), crate::CreateInitialDocumentsError> {
// Find fastn-home directory (account_path is fastn-home/accounts/account-id52)
let fastn_home = account_path
.parent()
.and_then(|p| p.parent())
.ok_or_else(
|| crate::CreateInitialDocumentsError::AliasDocumentCreationFailed {
source: Box::new(std::io::Error::new(
std::io::ErrorKind::NotFound,
"Could not find fastn-home directory",
)),
},
)?;

// Use embedded fastn-home content from build time
static FASTN_HOME_CONTENT: include_dir::Dir = include_dir::include_dir!("../fastn-home/src");

let public_dir = account_path.join("public");

tracing::info!("Copying embedded UI content to {}", public_dir.display());

// Create public directory
tokio::fs::create_dir_all(&public_dir).await.map_err(|e| {
crate::CreateInitialDocumentsError::AliasDocumentCreationFailed {
source: Box::new(e),
}
})?;

// Copy embedded content to public directory
copy_embedded_dir(&FASTN_HOME_CONTENT, &public_dir).await.map_err(|e| {
crate::CreateInitialDocumentsError::AliasDocumentCreationFailed {
source: Box::new(e),
}
})?;

tracing::info!("✅ Copied embedded UI content to account public directory");

Ok(())
}

/// Copy embedded directory contents to filesystem
async fn copy_embedded_dir(
embedded_dir: &include_dir::Dir<'_>,
dst: &std::path::Path,
) -> Result<(), std::io::Error> {
// Copy all files in the embedded directory
for file in embedded_dir.files() {
let file_path = dst.join(file.path());

// Create parent directories if needed
if let Some(parent) = file_path.parent() {
tokio::fs::create_dir_all(parent).await?;
}

// Write file content
tokio::fs::write(&file_path, file.contents()).await?;
}

// Recursively copy subdirectories
for subdir in embedded_dir.dirs() {
let subdir_path = dst.join(subdir.path());
tokio::fs::create_dir_all(&subdir_path).await?;

// Recursive call for subdirectory
Box::pin(copy_embedded_dir(subdir, &subdir_path)).await?;
}

Ok(())
}

/// Recursively copy directory contents
async fn copy_dir_recursive(
src: &std::path::Path,
dst: &std::path::Path,
) -> Result<(), std::io::Error> {
tokio::fs::create_dir_all(dst).await?;

let mut entries = tokio::fs::read_dir(src).await?;
while let Some(entry) = entries.next_entry().await? {
let entry_path = entry.path();
let file_name = entry.file_name();
let dst_path = dst.join(&file_name);

if entry_path.is_dir() {
Box::pin(copy_dir_recursive(&entry_path, &dst_path)).await?;
} else {
tokio::fs::copy(&entry_path, &dst_path).await?;
}
}

Ok(())
}
17 changes: 14 additions & 3 deletions v0.5/fastn-account/src/http_routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,21 @@ impl crate::Account {
};

// Try folder-based routing first with account context
let fbr = fastn_fbr::FolderBasedRouter::new(self.path().await);
let account_path = self.path().await;
println!("🔍 Account path: {}", account_path.display());

let fbr = fastn_fbr::FolderBasedRouter::new(&account_path);
let account_context = self.create_template_context().await;
if let Ok(response) = fbr.route_request(request, Some(&account_context)).await {
return Ok(response);

match fbr.route_request(request, Some(&account_context)).await {
Ok(response) => {
println!("✅ Folder-based routing succeeded for {}", request.path);
return Ok(response);
}
Err(e) => {
println!("❌ Folder-based routing failed for {}: {}", request.path, e);
// Fall through to default interface
}
}

// Fallback to default account interface
Expand Down
11 changes: 10 additions & 1 deletion v0.5/fastn-fbr/src/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,24 @@ impl FolderBasedRouter {
public_dir.join(&clean_path)
};

tracing::debug!("FBR file path: {}", file_path.display());
tracing::debug!(
"FBR base_path: {}, public_dir: {}, file_path: {}",
self.base_path.display(),
public_dir.display(),
file_path.display()
);
println!("🔍 FBR: Looking for file: {}", file_path.display());

// Check if file exists
if !file_path.exists() {
println!("❌ FBR: File not found: {}", file_path.display());
return Err(FbrError::FileNotFound {
path: file_path.display().to_string(),
});
}

println!("✅ FBR: File exists: {}", file_path.display());

// Handle different file types
if file_path.is_dir() {
// Try index.html in directory
Expand Down
39 changes: 39 additions & 0 deletions v0.5/fastn-home/src/-/mail/index.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions v0.5/fastn-home/src/index.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading