ferripfs-config 0.1.0

IPFS node configuration types, compatible with Kubo config format
Documentation
// Ported from: kubo/config/api.go
// Kubo version: v0.39.0
// Original: https://github.com/ipfs/kubo/blob/v0.39.0/config/api.go
//
// Original work: Copyright (c) Protocol Labs, Inc.
// Port: Copyright (c) 2026 ferripfs contributors
// SPDX-License-Identifier: MIT OR Apache-2.0

//! API configuration for HTTP RPC API.

use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// API configuration section
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct Api {
    /// HTTP headers to include in API responses
    #[serde(default, rename = "HTTPHeaders")]
    pub http_headers: HashMap<String, Vec<String>>,

    /// Authorization scopes for API access
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub authorizations: Option<HashMap<String, RpcAuthScope>>,
}

/// RPC authentication scope
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct RpcAuthScope {
    /// Authentication secret (format: "type:value", e.g., "bearer:token" or "basic:user:pass")
    pub auth_secret: String,

    /// Allowed API paths for this scope
    pub allowed_paths: Vec<String>,
}

impl Api {
    /// Get default HTTP headers for API
    pub fn default_http_headers() -> HashMap<String, Vec<String>> {
        let mut headers = HashMap::new();
        headers.insert(
            "Access-Control-Allow-Origin".to_string(),
            vec!["*".to_string()],
        );
        headers
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_api_default() {
        let api = Api::default();
        assert!(api.http_headers.is_empty());
        assert!(api.authorizations.is_none());
    }

    #[test]
    fn test_rpc_auth_scope() {
        let scope = RpcAuthScope {
            auth_secret: "bearer:mytoken".to_string(),
            allowed_paths: vec!["/api/v0/id".to_string()],
        };
        let json = serde_json::to_string(&scope).unwrap();
        assert!(json.contains("AuthSecret"));
        assert!(json.contains("AllowedPaths"));
    }
}