ordinary-api 0.8.0

API server for Ordinary
// Copyright (C) 2026 Ordinary Labs, LLC.
//
// SPDX-License-Identifier: AGPL-3.0-only

use crate::server::ops;
use utoipa::openapi::security::{Http, HttpAuthScheme, SecurityScheme};
use utoipa::{Modify, OpenApi};

pub const ROOT: &str = "root";
pub const ADMIN: &str = "admin";
pub const APPLICATION: &str = "application";
pub const AUTHENTICATION: &str = "authentication";

#[derive(OpenApi)]
#[openapi(
    info(
        title = "Ordinary API Server",
        description = "
## ordinary-api

[![docs.rs](https://img.shields.io/docsrs/ordinary-api/0.8.0)](https://docs.rs/ordinary-api/0.8.0)
[![dependency status](https://img.shields.io/deps-rs/ordinary-api/0.8.0)](https://deps.rs/crate/ordinary-api/0.8.0)

### Access Token

Use the [Ordinary CLI](https://crates.io/crates/ordinary) to get an access token.

```sh
ordinary accounts access get --min 15
```
",
        contact(),
    ),
    modifiers(&Security),
    nest(
        (path = "/v1", api = OrdinaryV1ApiOpenApi),
    ),
    paths(ops::builtins::health),
    tags(
        (name = APPLICATION, description = "Application API"),
        (name = ADMIN, description = "Admin API"),
        (name = ROOT, description = "Root API"),
        (name = AUTHENTICATION, description = "Authentication API"),
    )
)]
pub struct ApiDoc;

struct Security;

impl Modify for Security {
    fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) {
        if let Some(components) = openapi.components.as_mut() {
            components.add_security_scheme(
                "invite",
                SecurityScheme::Http(Http::new(HttpAuthScheme::Bearer)),
            );

            components.add_security_scheme(
                "refresh",
                SecurityScheme::Http(Http::new(HttpAuthScheme::Bearer)),
            );

            components.add_security_scheme(
                "access",
                SecurityScheme::Http(Http::new(HttpAuthScheme::Bearer)),
            );
        }
    }
}

#[derive(OpenApi)]
#[openapi(paths(
    ops::accounts::invite,
    ops::accounts::list,
    ops::accounts::delete,
    ops::accounts::registration_start,
    ops::accounts::registration_finish,
    ops::accounts::login_start,
    ops::accounts::login_finish,
    ops::accounts::access_get,
    ops::accounts::password_reset_login_start,
    ops::accounts::password_reset_login_finish,
    ops::accounts::password_reset_registration_start,
    ops::accounts::password_reset_registration_finish,
    ops::accounts::password_forgot_start,
    ops::accounts::password_forgot_finish,
    ops::accounts::mfa_reset_totp_start,
    ops::accounts::mfa_reset_totp_finish,
    ops::accounts::mfa_lost_totp_start,
    ops::accounts::mfa_lost_totp_finish,
    ops::accounts::recovery_reset_codes_start,
    ops::accounts::recovery_reset_codes_finish,
    ops::accounts::account_delete_start,
    ops::accounts::account_delete_finish,
    ops::root::log_files_metadata,
    ops::root::log_files,
    ops::root::info,
    ops::root::lock,
    ops::root::unlock,
    ops::app::log_files_metadata,
    ops::app::log_files,
    ops::app::deploy,
    ops::app::kill,
    ops::app::restart,
    ops::app::erase,
    ops::templates::upload,
    ops::secrets::store,
    ops::keys::dh_public_key,
    ops::content::update,
    ops::assets::write,
    ops::models::items_list,
    ops::actions::install,
    ops::builtins::limits,
))]
pub struct OrdinaryV1ApiOpenApi;