From 511e8f2bb26e2f447d691e9c1460762dbb1347a4 Mon Sep 17 00:00:00 2001 From: Jared Hendrickson Date: Sun, 9 Nov 2025 15:23:52 -0700 Subject: [PATCH 1/3] fix(GraphQL): only mark types as nonNull if they are unconditional #778 Fields that are conditionally required need to be nullable as they are only required if the fields conditions are met. Marking them as nonNull types will result in schema errors if the condition is not met for a specific object. --- .../files/usr/local/pkg/RESTAPI/Schemas/GraphQLSchema.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Schemas/GraphQLSchema.inc b/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Schemas/GraphQLSchema.inc index 10b9d9e64..25562bd5b 100644 --- a/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Schemas/GraphQLSchema.inc +++ b/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Schemas/GraphQLSchema.inc @@ -127,8 +127,8 @@ class GraphQLSchema extends Schema { $type = Type::listOf($type); } - # Make this field non-nullable if it is required - if ($field->required and !$ignore_required) { + # Make this field non-nullable if it is required and unconditional + if ($field->required and !$field->conditions and !$ignore_required) { $type = Type::nonNull($type); } From 7856ae9813aff58f25e94c682b2a43ce77bffb4a Mon Sep 17 00:00:00 2001 From: Jared Hendrickson Date: Wed, 12 Nov 2025 21:10:48 -0700 Subject: [PATCH 2/3] test(GraphQL): ensure conditionally required fields can always be queried #778 --- .../pkg/RESTAPI/Tests/APIModelsGraphQLTestCase.inc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Tests/APIModelsGraphQLTestCase.inc b/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Tests/APIModelsGraphQLTestCase.inc index 7521b0353..f09d523c4 100644 --- a/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Tests/APIModelsGraphQLTestCase.inc +++ b/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Tests/APIModelsGraphQLTestCase.inc @@ -388,4 +388,17 @@ class APIModelsGraphQLTestCase extends TestCase { }, ); } + + /** + * Ensure we can query for model fields that are conditionally required. Regression test for #778 + */ + public function test_query_conditionally_required_field(): void { + # Query for interfaces including conditionally required fields and ensure no errors are returned. + $graphql = new GraphQL( + query: 'query {queryInterfaces {id ipaddr subnet descr typev4 track6_interface}}', + client: $this->auth + ); + $graphql->create(); + $this->assert_is_empty($graphql->result->value['errors'] ?? []); + } } From d5e28a308fb7667ad261f0351da0ff8c4557bc24 Mon Sep 17 00:00:00 2001 From: Jared Hendrickson Date: Wed, 12 Nov 2025 21:11:15 -0700 Subject: [PATCH 3/3] style: run prettier on changed files --- .../usr/local/pkg/RESTAPI/Tests/APIModelsGraphQLTestCase.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Tests/APIModelsGraphQLTestCase.inc b/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Tests/APIModelsGraphQLTestCase.inc index f09d523c4..cb1147e8e 100644 --- a/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Tests/APIModelsGraphQLTestCase.inc +++ b/pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Tests/APIModelsGraphQLTestCase.inc @@ -396,7 +396,7 @@ class APIModelsGraphQLTestCase extends TestCase { # Query for interfaces including conditionally required fields and ensure no errors are returned. $graphql = new GraphQL( query: 'query {queryInterfaces {id ipaddr subnet descr typev4 track6_interface}}', - client: $this->auth + client: $this->auth, ); $graphql->create(); $this->assert_is_empty($graphql->result->value['errors'] ?? []);