rustauth-oauth-provider 0.3.0

OAuth 2.1 and OpenID Connect provider support for RustAuth.
Documentation
use super::*;

pub(super) fn logout_endpoint(options: Arc<ResolvedOAuthProviderOptions>) -> AsyncAuthEndpoint {
    create_auth_endpoint(
        "/oauth2/end-session",
        Method::GET,
        AuthEndpointOptions::new(),
        move |context, request| {
            let options = Arc::clone(&options);
            async move {
                let Some(adapter) = context.adapter() else {
                    return error_response(OAuthProviderError::invalid_request(
                        "database adapter required",
                    ));
                };
                let Some(id_token_hint) = query_param(&request, "id_token_hint") else {
                    return error_response(OAuthProviderError::new(
                        StatusCode::UNAUTHORIZED,
                        "invalid_token",
                        "invalid id token",
                    ));
                };
                let validated = match validate_id_token_hint(
                    &context,
                    adapter.as_ref(),
                    &options,
                    &id_token_hint,
                    query_param(&request, "client_id").as_deref(),
                )
                .await
                {
                    Ok(validated) => validated,
                    Err(error) => return error_response(error),
                };
                adapter
                    .delete(crate::utils::delete_by_string(
                        "session",
                        "id",
                        &validated.session_id,
                    ))
                    .await?;
                if let Some(uri) = query_param(&request, "post_logout_redirect_uri") {
                    if validated
                        .client
                        .post_logout_redirect_uris
                        .as_deref()
                        .unwrap_or_default()
                        .iter()
                        .any(|registered| registered == &uri)
                    {
                        let mut redirect = url::Url::parse(&uri)
                            .map_err(|error| RustAuthError::Api(error.to_string()))?;
                        if let Some(state) = query_param(&request, "state") {
                            redirect.query_pairs_mut().append_pair("state", &state);
                        }
                        return redirect_response(redirect.as_str());
                    }
                }
                no_content()
            }
        },
    )
}