ordinaryd 0.8.2

Ordinary Server
Documentation
// Copyright (C) 2026 Ordinary Labs, LLC.
//
// SPDX-License-Identifier: AGPL-3.0-only

use ordinary_api::server::OrdinaryApiServer;
use ordinary_monitor::tracing::logger::OrdinaryLogger;
use qrcodegen::{QrCode, QrCodeEcc};
use std::io::Write;
use std::path::Path;

#[allow(clippy::too_many_arguments)]
pub async fn run(
    environment: &str,
    api_domain: &str,
    password: &str,
    data_dir: &str,
    storage_size: usize,
    mfa_stored: bool,
    api_contacts: &[String],
    app_domains: &[String],
    privileged_domains: &Option<Vec<String>>,
    logger: Option<OrdinaryLogger>,
) -> anyhow::Result<()> {
    tracing::debug!("initializing API server...");

    let environment_path = Path::new(&data_dir).join("environments").join(environment);

    match OrdinaryApiServer::init(
        environment,
        api_domain,
        password,
        &environment_path,
        storage_size,
        api_contacts,
        app_domains,
        privileged_domains,
        logger,
    )
    .await
    {
        Ok((mfa_url, secret)) => {
            if mfa_stored {
                let mut mfa_secret_file =
                    fs_err::File::create(environment_path.join("mfa_secret"))?;
                mfa_secret_file.write_all(&secret)?;
                mfa_secret_file.flush()?;

                let mut mfa_url_file = fs_err::File::create(environment_path.join("mfa_url"))?;
                mfa_url_file.write_all(mfa_url.as_bytes())?;
                mfa_url_file.flush()?;
            } else {
                let qr: QrCode = QrCode::encode_text(&mfa_url, QrCodeEcc::Medium)?;
                let border: i32 = 4;
                for y in -border..qr.size() + border {
                    for x in -border..qr.size() + border {
                        let c: char = if qr.get_module(x, y) { '' } else { ' ' };
                        print!("{c}{c}");
                    }
                    println!();
                }
                println!("{mfa_url}");
            }
        }
        Err(err) => tracing::error!(%err),
    }

    Ok(())
}