better-auth-api 1.0.0-alpha.5

Plugin implementations for better-auth
#![allow(
    clippy::expect_used,
    reason = "Fixture setup and response assertions require successful fallible construction."
)]
use super::*;
use crate::plugins::organization::OrganizationPlugin;
use better_auth_core::{CreateMember, CreateOrganization, SchemaValue};

async fn check_organization_actor<S: AuthSchema>(ctx: AuthContext<S>) {
    let (ctx, _, sessions, _, callbacks) = harness(ctx, false, &[&OrganizationPlugin::new()]).await;
    let plugin = ApiKeyPlugin::builder()
        .references(ApiKeyReferences::Organization)
        .enable_metadata(true)
        .default_permissions_callback(Arc::new(Permissions(callbacks.clone())))
        .build();
    let mut user = CreateUser::new()
        .with_email("member@native-actor.test")
        .with_name("Member");
    user.id = Some("7".into());
    let _ = ctx.database.create_user(user).await.unwrap();
    let mut organization = CreateOrganization::new("Machines", "machines");
    organization.id = Some("machine-org".into());
    let _ = ctx
        .database
        .create_organization(organization)
        .await
        .unwrap();
    let _ = ctx
        .database
        .create_member(CreateMember {
            additional_fields: Default::default(),
            organization_id: "machine-org".into(),
            user_id: SchemaValue::from_field(7.0.into()),
            role: "owner".into(),
        })
        .await
        .unwrap();
    actor(&sessions, Some(&json!(7))).await;
    let metadata = &cases()["metadata"];
    let created = json_body(
        &plugin
            .handle_create(
                &request(
                    HttpMethod::Post,
                    "/api-key/create",
                    Some(json!({"organizationId": "machine-org", "metadata": metadata})),
                    None,
                ),
                &ctx,
            )
            .await
            .unwrap(),
    );
    let id = created["id"].as_str().unwrap();
    assert_eq!(created["referenceId"], "machine-org");
    assert_eq!(
        *callbacks.lock().unwrap(),
        vec![json!(["machine-org", metadata, 0])]
    );
    assert_eq!(
        json_body(
            &plugin
                .handle_get(
                    &request(
                        HttpMethod::Get,
                        "/api-key/get",
                        None,
                        Some(json!({"id": id}))
                    ),
                    &ctx
                )
                .await
                .unwrap()
        )["id"],
        id
    );
    let listed = json_body(
        &plugin
            .handle_list(
                &request(
                    HttpMethod::Get,
                    "/api-key/list",
                    None,
                    Some(json!({"organizationId": "machine-org"})),
                ),
                &ctx,
            )
            .await
            .unwrap(),
    );
    assert_eq!(listed["total"], 1);
    assert_eq!(listed["apiKeys"][0]["id"], id);
    actor(&sessions, Some(&json!(8))).await;
    for result in [
        plugin
            .handle_get(
                &request(
                    HttpMethod::Get,
                    "/api-key/get",
                    None,
                    Some(json!({"id": id})),
                ),
                &ctx,
            )
            .await,
        plugin
            .handle_update(
                &request(
                    HttpMethod::Post,
                    "/api-key/update",
                    Some(json!({"keyId": id, "name": "Unauthorized"})),
                    None,
                ),
                &ctx,
            )
            .await,
        plugin
            .handle_delete(
                &request(
                    HttpMethod::Post,
                    "/api-key/delete",
                    Some(json!({"keyId": id})),
                    None,
                ),
                &ctx,
            )
            .await,
        plugin
            .handle_list(
                &request(
                    HttpMethod::Get,
                    "/api-key/list",
                    None,
                    Some(json!({"organizationId": "machine-org"})),
                ),
                &ctx,
            )
            .await,
    ] {
        let error = result.unwrap_err();
        assert_eq!(error.status_code().unwrap(), 403);
        assert_eq!(
            json_body(&error.to_auth_response().expect("fixture response succeeds"))["code"],
            "USER_NOT_MEMBER_OF_ORGANIZATION"
        );
    }
    actor(&sessions, Some(&json!(7))).await;
    assert_eq!(
        json_body(
            &plugin
                .handle_update(
                    &request(
                        HttpMethod::Post,
                        "/api-key/update",
                        Some(json!({"keyId": id, "name": "Updated"})),
                        None
                    ),
                    &ctx
                )
                .await
                .unwrap()
        )["name"],
        "Updated"
    );
    assert_eq!(
        json_body(
            &plugin
                .handle_delete(
                    &request(
                        HttpMethod::Post,
                        "/api-key/delete",
                        Some(json!({"keyId": id})),
                        None
                    ),
                    &ctx
                )
                .await
                .unwrap()
        ),
        json!({"success": true})
    );
}

#[tokio::test]
async fn memory_organization_api_keys_query_membership_with_native_actor() {
    let config = Arc::new(crate::plugins::test_helpers::create_test_config());
    check_organization_actor(
        AuthContext::new(config.clone(), Arc::new(EphemeralStore::new(config)))
            .expect("fixture context initializes"),
    )
    .await;
}

#[tokio::test]
async fn sqlite_organization_api_keys_query_membership_with_native_actor() {
    check_organization_actor(crate::plugins::test_helpers::create_test_context().await).await;
}