From 11c030160bba33ffe6d92cb9706a1bbb32f744eb Mon Sep 17 00:00:00 2001 From: Marcelle <53578688+m-goggins@users.noreply.github.com> Date: Tue, 19 Nov 2024 15:12:28 -0800 Subject: [PATCH 1/9] Replace non-numeric characters in phone numbers with url encoding (#166) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- query-connector/src/app/format-service.tsx | 4 ++-- query-connector/src/app/tests/unit/format-service.test.tsx | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/query-connector/src/app/format-service.tsx b/query-connector/src/app/format-service.tsx index 877ee15a2..306b4cf37 100644 --- a/query-connector/src/app/format-service.tsx +++ b/query-connector/src/app/format-service.tsx @@ -250,12 +250,12 @@ const FORMATS_TO_SEARCH: string[] = [ export async function GetPhoneQueryFormats(phone: string) { // Digit-only phone numbers will resolve as actual numbers if (isNaN(Number(phone)) || phone.length != 10) { - const strippedPhone = phone.replace(" ", "+"); + const strippedPhone = phone.replace(" ", "%2D"); return [strippedPhone]; } // Map the phone number into each format we want to check const possibleFormats: string[] = FORMATS_TO_SEARCH.map((fmt) => { - return phone.replace(/(\d{3})(\d{3})(\d{4})/gi, fmt); + return encodeURIComponent(phone.replace(/(\d{3})(\d{3})(\d{4})/gi, fmt)); }); return possibleFormats; } diff --git a/query-connector/src/app/tests/unit/format-service.test.tsx b/query-connector/src/app/tests/unit/format-service.test.tsx index 7c03fbf38..ea9105c9f 100644 --- a/query-connector/src/app/tests/unit/format-service.test.tsx +++ b/query-connector/src/app/tests/unit/format-service.test.tsx @@ -470,7 +470,7 @@ describe("FormatPhoneAsDigits", () => { describe("GetPhoneQueryFormats", () => { it("should fail gracefully on partial phone number inputs", async () => { const partialPhone = "456 7890"; - const expectedResult = ["456+7890"]; + const expectedResult = ["456%2D7890"]; //456+7890 expect(await GetPhoneQueryFormats(partialPhone)).toEqual(expectedResult); }); it("should fail gracefully on given phones with separators remaining", async () => { @@ -486,8 +486,8 @@ describe("GetPhoneQueryFormats", () => { const expectedResult = [ "1234567890", "123-456-7890", - "123+456+7890", - "(123)+456+7890", + "123%2B456%2B7890", //123+456+7890 + "(123)%2B456%2B7890", //(123)+456+7890 "(123)-456-7890", "(123)456-7890", "1(123)456-7890", From 39d80b3ce6d6f5d662f7c290658df0430423dc63 Mon Sep 17 00:00:00 2001 From: Marcelle <53578688+m-goggins@users.noreply.github.com> Date: Wed, 20 Nov 2024 13:53:16 -0800 Subject: [PATCH 2/9] Update Postman Collection Copy + base_url (#165) --- ...ery_Connector_API.postman_collection.json} | 195 ++++++++++-------- 1 file changed, 113 insertions(+), 82 deletions(-) rename query-connector/src/app/assets/{TEFCA_Query_Connector_API.postman_collection.json => DIBBs_Query_Connector_API.postman_collection.json} (55%) diff --git a/query-connector/src/app/assets/TEFCA_Query_Connector_API.postman_collection.json b/query-connector/src/app/assets/DIBBs_Query_Connector_API.postman_collection.json similarity index 55% rename from query-connector/src/app/assets/TEFCA_Query_Connector_API.postman_collection.json rename to query-connector/src/app/assets/DIBBs_Query_Connector_API.postman_collection.json index cadfb11e3..a9f24174f 100644 --- a/query-connector/src/app/assets/TEFCA_Query_Connector_API.postman_collection.json +++ b/query-connector/src/app/assets/DIBBs_Query_Connector_API.postman_collection.json @@ -1,8 +1,8 @@ { "info": { - "_postman_id": "41c63eee-477f-402d-ab91-974b6c660833", - "name": "TEFCA Query Connector API", - "description": "# Overview\n\nThis document offers guidance for using the DIBBs TEFCA Query Connector service. It's intended to help you understand what the TEFCA Query Connector does (e.g., what use cases you can query for and what data is returned for each query) and how to make API requests to query for relevant case investigation data using this service.\n\n## What is the TEFCA Query Connector?\n\nThe TEFCA Query Connector is a tool for public health practitioners to quickly retrieve patient records and relevant case information from healthcare organizations. The tool works by connecting to Qualified Health Information Networks (QHINs) within the Trusted Exchange Framework and Common Agreement (TEFCA), ensuring immediate access to essential health data and facilitating timely public health decisions and interventions. Public health staff can interact with the TEFCA Query Connector via API or manually by entering simple patient details \u2014 such as name, date of birth, or medical identifiers \u2014 into a web-based search form. The tool also allows for automated queries via integration engines like Rhapsody and Mirth.\n\n## Available Use Cases\n\nOur team has put together a collection of eleven API requests to demonstrate the functionality of the TEFCA Query Connector. Users can query for the following 6 use cases either directly or via the eHealth Exchange QHIN:\n\n- Cancer\n \n- Chlamydia\n \n- Gonorrhea\n \n- Newborn Screening\n \n- Social Determinants of Health\n \n- Syphilis\n \n\nEach of the requests is made up of the request's Body, which consists of the data sent to the API, and Documentation, which explains the possible use cases of the functionality demonstrated in the test. To view the documentation for a test, click the icon of a page with a folded corner near the top of the right-hand bar.\n\nAll data featured in these requests comes from synthetic FHIR data generated by J Michael Consulting and the Interoperability Institute.", + "_postman_id": "4b9fe84c-a61e-48f7-8df0-15e65e1919d0", + "name": "DIBBs Query Connector API", + "description": "# Overview\n\nThis document offers guidance for using the DIBBs Query Connector service. It's intended to help you understand what the Query Connector does (e.g., what use cases you can query for and what data is returned for each query) and how to make API requests to query for relevant case investigation data using this service.\n\n## What is it?\n\nThe Query Connector is a data collection tool that uses an intuitive querying process to help your staff quickly retrieve patient records and relevant case information from a wide range of healthcare providers — all without the need for a direct connection. It does this by leveraging your jurisdiction's existing data use agreements, like the Data Use and Reciprocal Support Agreement (DURSA), while also supporting innovative standards for data sharing, like the Trusted Exchange Framework and Common Agreement (TEFCA).\n\n## How does it work?\n\nPublic health staff can interact with the Query Connector manually by entering simple patient details — such as name, date of birth, or medical identifiers — along with a query, into the web-based portal. The Query Connector API enables public health practitioners to retrieve patient records and case information directly from healthcare organizations via API requests to FHIR endpoints at health care organizations.\n\nTo make a request, users submit a patient resource in the body of the request. Users must also include the type of query they'd like to make, e.g., query for data related to chlamydia for this patient, and the endpoint that they'd like to retrieve the data from, e.g., a particular healthcare organization's EHR. Users can also make requests to Qualified Health Information Networks (QHINs) under TEFCA to query networks of healthcare organizations. For additional flexibility, the tool also supports integration with systems like Rhapsody and Mirth for automated queries. \n \nAvailable Use Cases\n\nOur team has put together a collection of eleven API requests to demonstrate the functionality of the Query Connector. Users can query for the following 6 use cases either directly or via the eHealth Exchange QHIN:\n\n- Cancer\n \n- Chlamydia\n \n- Gonorrhea\n \n- Newborn Screening\n \n- Social Determinants of Health\n \n- Syphilis\n \n\nEach of the requests is made up of the request's Body, which consists of the data sent to the API, and Documentation, which explains the possible use cases of the functionality demonstrated in the test. To view the documentation for a test, click the icon of a page with a folded corner near the top of the right-hand bar.\n\nAll data featured in these requests comes from synthetic FHIR data generated by J Michael Consulting and the Interoperability Institute.", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", "_exporter_id": "35028120" }, @@ -23,8 +23,13 @@ }, "url": { "raw": "{{base_url}}/api/query?fhir_server=HELIOS Meld: Direct&use_case=cancer", - "host": ["{{base_url}}"], - "path": ["api", "query"], + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "query" + ], "query": [ { "key": "fhir_server", @@ -36,7 +41,7 @@ } ] }, - "description": "# Set Up\n\nThis API request demonstrates the TEFCA Query Connector's ability to directly query a server for a given patient and return data relevant to a case investigation. The direct query represents a point-to-point connection between a public health agency and a healthcare organization.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the TEFCA Query Connector. In addition to the FHIR patient resource, the TEFCA Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a direct query to the Helios Meld server. The request is for data relevant to a cancer query for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=HELIOS Meld: Direct&use_case=cancer`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's cancer follow-up. For example, the returned results include a Patient resource and relevant Observation resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a cancer query will only return observation resources that contain SNOMED codes that are pertinent to a cancer follow-up. If a resource is not present, e.g., if there are no Encounter resources with cancer-relevant SNOMED codes, the response will not contain any Encounter resources.\n\n## Expected resources returned from cancer query\n\n- Patient\n \n- Conditions\n \n- Encounters\n \n- Medication Requests\n \n\n## LOINC codes included in cancer query\n\nNot applicable for this use case\n\n## SNOMED codes included in cancer query\n\n| **Code** | **Value** |\n| --- | --- |\n| 92814006 | Chronic lymphoid leukemia, disease |\n\n## RxNorm codes included in cancer query\n\n| **Code** | **Value** |\n| --- | --- |\n| 828265 | 1 ML alemtuzumab 30 MG/ML Injection |" + "description": "# Set Up\n\nThis API request demonstrates the Query Connector's ability to directly query a server for a given patient and return data relevant to a case investigation. The direct query represents a point-to-point connection between a public health agency and a healthcare organization.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the Query Connector. In addition to the FHIR patient resource, the Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a direct query to the Helios Meld server. The request is for data relevant to a cancer query for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=HELIOS Meld: Direct&use_case=cancer`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's cancer follow-up. For example, the returned results include a Patient resource and relevant Observation resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a cancer query will only return observation resources that contain SNOMED codes that are pertinent to a cancer follow-up. If a resource is not present, e.g., if there are no Encounter resources with cancer-relevant SNOMED codes, the response will not contain any Encounter resources.\n\n## Expected resources returned from cancer query\n\n- Patient\n \n- Conditions\n \n- Encounters\n \n- Medication Requests\n \n\n## LOINC codes included in cancer query\n\nNot applicable for this use case\n\n## SNOMED codes included in cancer query\n\n| **Code** | **Value** |\n| --- | --- |\n| 92814006 | Chronic lymphoid leukemia, disease |\n\n## RxNorm codes included in cancer query\n\n| **Code** | **Value** |\n| --- | --- |\n| 828265 | 1 ML alemtuzumab 30 MG/ML Injection |" }, "response": [] }, @@ -56,8 +61,13 @@ }, "url": { "raw": "{{base_url}}/api/query?fhir_server=HELIOS Meld: eHealthExchange&use_case=cancer", - "host": ["{{base_url}}"], - "path": ["api", "query"], + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "query" + ], "query": [ { "key": "fhir_server", @@ -69,7 +79,7 @@ } ] }, - "description": "# Set Up\n\nThis API request demonstrates the TEFCA Query Connector's ability to query a Qualified Health Information Network (QHIN) for a given patient and return data relevant to a case investigation. The query represents a connection between a public health agency and a healthcare organization via a QHIN.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the TEFCA Query Connector. In addition to the FHIR patient resource, the TEFCA Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a query to the HELIOS Meld server via the eHealthExchange QHIN. The request is for data relevant to a cancer query for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=HELIOS Meld: eHealthExchange&use_case=cancer`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's cancer follow-up. For example, the returned results include a Patient resource and relevant Observation resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a cancer query will only return observation resources that contain LOINC codes that are pertinent to a cancer follow-up. If a resource is not present, e.g., if there are no Encounter resources with cancer-relevant SNOMED codes, the response will not contain any Encounter resources.\n\n## Expected resources returned from gonorrhea query\n\n- Patient\n \n- Conditions\n \n- Encounters\n \n- Medication Requests\n \n\n## LOINC codes included in cancer query\n\nNot applicable for this use case\n\n## SNOMED codes included in cancer query\n\n| **Code** | **Value** |\n| --- | --- |\n| 92814006 | Chronic lymphoid leukemia, disease |\n\n## RxNorm codes included in cancer query\n\n| **Code** | **Value** |\n| --- | --- |\n| 828265 | 1 ML alemtuzumab 30 MG/ML Injection |" + "description": "# Set Up\n\nThis API request demonstrates the Query Connector's ability to query a Qualified Health Information Network (QHIN) for a given patient and return data relevant to a case investigation. The query represents a connection between a public health agency and a healthcare organization via a QHIN.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the Query Connector. In addition to the FHIR patient resource, the Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a query to the HELIOS Meld server via the eHealthExchange QHIN. The request is for data relevant to a cancer query for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=HELIOS Meld: eHealthExchange&use_case=cancer`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's cancer follow-up. For example, the returned results include a Patient resource and relevant Observation resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a cancer query will only return observation resources that contain LOINC codes that are pertinent to a cancer follow-up. If a resource is not present, e.g., if there are no Encounter resources with cancer-relevant SNOMED codes, the response will not contain any Encounter resources.\n\n## Expected resources returned from gonorrhea query\n\n- Patient\n \n- Conditions\n \n- Encounters\n \n- Medication Requests\n \n\n## LOINC codes included in cancer query\n\nNot applicable for this use case\n\n## SNOMED codes included in cancer query\n\n| **Code** | **Value** |\n| --- | --- |\n| 92814006 | Chronic lymphoid leukemia, disease |\n\n## RxNorm codes included in cancer query\n\n| **Code** | **Value** |\n| --- | --- |\n| 828265 | 1 ML alemtuzumab 30 MG/ML Injection |" }, "response": [] }, @@ -89,8 +99,13 @@ }, "url": { "raw": "{{base_url}}/api/query?fhir_server=JMC Meld: Direct&use_case=chlamydia", - "host": ["{{base_url}}"], - "path": ["api", "query"], + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "query" + ], "query": [ { "key": "fhir_server", @@ -102,7 +117,7 @@ } ] }, - "description": "# Set Up\n\nThis API request demonstrates the TEFCA Query Connector's ability to directly query a server for a given patient and return data relevant to a case investigation. The direct query represents a point-to-point connection between a public health agency and a healthcare organization.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the TEFCA Query Connector. In addition to the FHIR patient resource, the TEFCA Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a direct query to the JMC Meld server. The request is for data relevant to a chlamydia case investigation for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=JMC Meld: Direct&use_case=chlamydia`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's chlamydia case. For example, the returned results include a Patient resource and relevant Observation, Condition, Medication Request, and Encounter resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a chlamydia query will only return observation resources that contain LOINC codes that are pertinent to a chlamydia case investigation. If a resource is not present, e.g., if there are no Observation resources with chlamydia relevant LOINC codes, the response will not contain any Observation resources.\n\n## Expected resources returned from chlamydia query\n\n- Patient\n \n- Conditions\n \n- Diagnostic Reports\n \n- Encounters\n \n- Medication Requests\n \n- Observations\n \n\n## LOINC codes included in chlamydia query\n\n| **Code** | **Value** |\n| --- | --- |\n| 24111-7 | Neisseria gonorrhoeae DNA \\[Presence\\] in Unspecified specimen by NAA with probe detection |\n| 72828-7 | Chlamydia trachomatis and Neisseria gonorrhoeae DNA panel - Unspecified specimen |\n| 21613-5 | Chlamydia trachomatis DNA \\[Presence\\] in Unspecified specimen by NAA with probe detection |\n| 82810-3 | Pregnancy status |\n| 11350-6 | History of Sexual behavior Narrative |\n| 83317-8 | Sexual activity with anonymous partner in the past year |\n\n## SNOMED codes included in chlamydia query\n\n| **Code** | **Value** |\n| --- | --- |\n| 2339001 | Sexual overexposure |\n| 72531000052105 | Contraceptive counseling |\n| 102874004 | Possible pregnancy |\n| A74.9 | HLA-Aw74 antigen |\n\n## RxNorm codes included in chlamydia query\n\n| **Code** | **Value** |\n| --- | --- |\n| 434692 | azithromycin 1000 MG |\n| 82122 | levofloxacin |\n| 1649987 | doxycycline hyclate 100 MG |\n| 1665005 | ceftriaxone 500 MG Injection |" + "description": "# Set Up\n\nThis API request demonstrates the Query Connector's ability to directly query a server for a given patient and return data relevant to a case investigation. The direct query represents a point-to-point connection between a public health agency and a healthcare organization.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the Query Connector. In addition to the FHIR patient resource, the Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a direct query to the JMC Meld server. The request is for data relevant to a chlamydia case investigation for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=JMC Meld: Direct&use_case=chlamydia`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's chlamydia case. For example, the returned results include a Patient resource and relevant Observation, Condition, Medication Request, and Encounter resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a chlamydia query will only return observation resources that contain LOINC codes that are pertinent to a chlamydia case investigation. If a resource is not present, e.g., if there are no Observation resources with chlamydia relevant LOINC codes, the response will not contain any Observation resources.\n\n## Expected resources returned from chlamydia query\n\n- Patient\n \n- Conditions\n \n- Diagnostic Reports\n \n- Encounters\n \n- Medication Requests\n \n- Observations\n \n\n## LOINC codes included in chlamydia query\n\n| **Code** | **Value** |\n| --- | --- |\n| 24111-7 | Neisseria gonorrhoeae DNA \\[Presence\\] in Unspecified specimen by NAA with probe detection |\n| 72828-7 | Chlamydia trachomatis and Neisseria gonorrhoeae DNA panel - Unspecified specimen |\n| 21613-5 | Chlamydia trachomatis DNA \\[Presence\\] in Unspecified specimen by NAA with probe detection |\n| 82810-3 | Pregnancy status |\n| 11350-6 | History of Sexual behavior Narrative |\n| 83317-8 | Sexual activity with anonymous partner in the past year |\n\n## SNOMED codes included in chlamydia query\n\n| **Code** | **Value** |\n| --- | --- |\n| 2339001 | Sexual overexposure |\n| 72531000052105 | Contraceptive counseling |\n| 102874004 | Possible pregnancy |\n| A74.9 | HLA-Aw74 antigen |\n\n## RxNorm codes included in chlamydia query\n\n| **Code** | **Value** |\n| --- | --- |\n| 434692 | azithromycin 1000 MG |\n| 82122 | levofloxacin |\n| 1649987 | doxycycline hyclate 100 MG |\n| 1665005 | ceftriaxone 500 MG Injection |" }, "response": [] }, @@ -122,8 +137,13 @@ }, "url": { "raw": "{{base_url}}/api/query?fhir_server=JMC Meld: eHealthExchange&use_case=chlamydia", - "host": ["{{base_url}}"], - "path": ["api", "query"], + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "query" + ], "query": [ { "key": "fhir_server", @@ -135,7 +155,7 @@ } ] }, - "description": "# Set Up\n\nThis API request demonstrates the TEFCA Query Connector's ability to query a Qualified Health Information Network (QHIN) for a given patient and return data relevant to a case investigation. The query represents a connection between a public health agency and a healthcare organization via a QHIN.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the TEFCA Query Connector. In addition to the FHIR patient resource, the TEFCA Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a query to the JMC Meld server via the eHealthExchange QHIN. The request is for data relevant to a chlamydia case investigation for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=JMC Meld: eHealthExchange&use_case=chlamydia`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's chlamydia case. For example, the returned results include a Patient resource and relevant Observation, Condition, Medication Request, and Encounter resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a chlamydia query will only return observation resources that contain LOINC codes that are pertinent to a chlamydia case investigation. If a resource is not present, e.g., if there are no Observation resources with chlamydia relevant LOINC codes, the response will not contain any Observation resources.\n\n## Expected resources returned from chlamydia query\n\n- Patient\n \n- Conditions\n \n- Diagnostic Reports\n \n- Encounters\n \n- Medication Requests\n \n- Observations\n \n\n## LOINC codes included in chlamydia query\n\n| **Code** | **Value** |\n| --- | --- |\n| 24111-7 | Neisseria gonorrhoeae DNA \\[Presence\\] in Unspecified specimen by NAA with probe detection |\n| 72828-7 | Chlamydia trachomatis and Neisseria gonorrhoeae DNA panel - Unspecified specimen |\n| 21613-5 | Chlamydia trachomatis DNA \\[Presence\\] in Unspecified specimen by NAA with probe detection |\n| 82810-3 | Pregnancy status |\n| 11350-6 | History of Sexual behavior Narrative |\n| 83317-8 | Sexual activity with anonymous partner in the past year |\n\n## SNOMED codes included in chlamydia query\n\n| **Code** | **Value** |\n| --- | --- |\n| 2339001 | Sexual overexposure |\n| 72531000052105 | Contraceptive counseling |\n| 102874004 | Possible pregnancy |\n| A74.9 | HLA-Aw74 antigen |\n\n## RxNorm codes included in chlamydia query\n\n| **Code** | **Value** |\n| --- | --- |\n| 434692 | azithromycin 1000 MG |\n| 82122 | levofloxacin |\n| 1649987 | doxycycline hyclate 100 MG |\n| 1665005 | ceftriaxone 500 MG Injection |" + "description": "# Set Up\n\nThis API request demonstrates the Query Connector's ability to query a Qualified Health Information Network (QHIN) for a given patient and return data relevant to a case investigation. The query represents a connection between a public health agency and a healthcare organization via a QHIN.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the Query Connector. In addition to the FHIR patient resource, the Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a query to the JMC Meld server via the eHealthExchange QHIN. The request is for data relevant to a chlamydia case investigation for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=JMC Meld: eHealthExchange&use_case=chlamydia`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's chlamydia case. For example, the returned results include a Patient resource and relevant Observation, Condition, Medication Request, and Encounter resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a chlamydia query will only return observation resources that contain LOINC codes that are pertinent to a chlamydia case investigation. If a resource is not present, e.g., if there are no Observation resources with chlamydia relevant LOINC codes, the response will not contain any Observation resources.\n\n## Expected resources returned from chlamydia query\n\n- Patient\n \n- Conditions\n \n- Diagnostic Reports\n \n- Encounters\n \n- Medication Requests\n \n- Observations\n \n\n## LOINC codes included in chlamydia query\n\n| **Code** | **Value** |\n| --- | --- |\n| 24111-7 | Neisseria gonorrhoeae DNA \\[Presence\\] in Unspecified specimen by NAA with probe detection |\n| 72828-7 | Chlamydia trachomatis and Neisseria gonorrhoeae DNA panel - Unspecified specimen |\n| 21613-5 | Chlamydia trachomatis DNA \\[Presence\\] in Unspecified specimen by NAA with probe detection |\n| 82810-3 | Pregnancy status |\n| 11350-6 | History of Sexual behavior Narrative |\n| 83317-8 | Sexual activity with anonymous partner in the past year |\n\n## SNOMED codes included in chlamydia query\n\n| **Code** | **Value** |\n| --- | --- |\n| 2339001 | Sexual overexposure |\n| 72531000052105 | Contraceptive counseling |\n| 102874004 | Possible pregnancy |\n| A74.9 | HLA-Aw74 antigen |\n\n## RxNorm codes included in chlamydia query\n\n| **Code** | **Value** |\n| --- | --- |\n| 434692 | azithromycin 1000 MG |\n| 82122 | levofloxacin |\n| 1649987 | doxycycline hyclate 100 MG |\n| 1665005 | ceftriaxone 500 MG Injection |" }, "response": [] }, @@ -155,8 +175,13 @@ }, "url": { "raw": "{{base_url}}/api/query?fhir_server=JMC Meld: Direct&use_case=gonorrhea", - "host": ["{{base_url}}"], - "path": ["api", "query"], + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "query" + ], "query": [ { "key": "fhir_server", @@ -168,7 +193,7 @@ } ] }, - "description": "# Set Up\n\nThis API request demonstrates the TEFCA Query Connector's ability to directly query a server for a given patient and return data relevant to a case investigation. The direct query represents a point-to-point connection between a public health agency and a healthcare organization.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the TEFCA Query Connector. In addition to the FHIR patient resource, the TEFCA Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a direct query to the JMC Meld server. The request is for data relevant to a gonorrhea case investigation for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=JMC Meld: Direct&use_case=gonorrhea`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's gonorrhea case. For example, the returned results include a Patient resource and relevant Observation, Condition, Medication Request, and Encounter resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a gonorrhea query will only return observation resources that contain LOINC codes that are pertinent to a gonorrhea case investigation. If a resource is not present, e.g., if there are no Observation resources with gonorrhea-relevant LOINC codes, the response will not contain any Observation resources.\n\n## Expected resources returned from gonorrhea query\n\n- Patient\n \n- Conditions\n \n- Diagnostic Reports\n \n- Encounters\n \n- Medication Requests\n \n- Observations\n \n\n## LOINC codes included in gonorrhea query\n\n| **Code** | **Value** |\n| --- | --- |\n| 24111-7 | Neisseria gonorrhoeae DNA \\[Presence\\] in Unspecified specimen by NAA with probe detection |\n| 11350-6 | History of Sexual behavior Narrative |\n| 21613-5 | Chlamydia trachomatis DNA \\[Presence\\] in Unspecified specimen by NAA with probe detection |\n| 82810-3 | Pregnancy status |\n| 83317-8 | Sexual activity with anonymous partner in the past year |\n\n## SNOMED codes included in gonorrhea query\n\n| **Code** | **Value** |\n| --- | --- |\n| 2339001 | Sexual overexposure |\n| 72531000052105 | Contraceptive counseling |\n| 102874004 | Possible pregnancy |\n| 15628003 | Gonorrhea |\n\n## RxNorm codes included in gonorrhea query\n\n| **Code** | **Value** |\n| --- | --- |\n| 434692 | azithromycin 1000 MG |\n| 1665005 | ceftriaxone 500 MG Injection |" + "description": "# Set Up\n\nThis API request demonstrates the Query Connector's ability to directly query a server for a given patient and return data relevant to a case investigation. The direct query represents a point-to-point connection between a public health agency and a healthcare organization.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the Query Connector. In addition to the FHIR patient resource, the Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a direct query to the JMC Meld server. The request is for data relevant to a gonorrhea case investigation for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=JMC Meld: Direct&use_case=gonorrhea`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's gonorrhea case. For example, the returned results include a Patient resource and relevant Observation, Condition, Medication Request, and Encounter resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a gonorrhea query will only return observation resources that contain LOINC codes that are pertinent to a gonorrhea case investigation. If a resource is not present, e.g., if there are no Observation resources with gonorrhea-relevant LOINC codes, the response will not contain any Observation resources.\n\n## Expected resources returned from gonorrhea query\n\n- Patient\n \n- Conditions\n \n- Diagnostic Reports\n \n- Encounters\n \n- Medication Requests\n \n- Observations\n \n\n## LOINC codes included in gonorrhea query\n\n| **Code** | **Value** |\n| --- | --- |\n| 24111-7 | Neisseria gonorrhoeae DNA \\[Presence\\] in Unspecified specimen by NAA with probe detection |\n| 11350-6 | History of Sexual behavior Narrative |\n| 21613-5 | Chlamydia trachomatis DNA \\[Presence\\] in Unspecified specimen by NAA with probe detection |\n| 82810-3 | Pregnancy status |\n| 83317-8 | Sexual activity with anonymous partner in the past year |\n\n## SNOMED codes included in gonorrhea query\n\n| **Code** | **Value** |\n| --- | --- |\n| 2339001 | Sexual overexposure |\n| 72531000052105 | Contraceptive counseling |\n| 102874004 | Possible pregnancy |\n| 15628003 | Gonorrhea |\n\n## RxNorm codes included in gonorrhea query\n\n| **Code** | **Value** |\n| --- | --- |\n| 434692 | azithromycin 1000 MG |\n| 1665005 | ceftriaxone 500 MG Injection |" }, "response": [] }, @@ -188,8 +213,13 @@ }, "url": { "raw": "{{base_url}}/api/query?fhir_server=JMC Meld: eHealthExchange&use_case=gonorrhea", - "host": ["{{base_url}}"], - "path": ["api", "query"], + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "query" + ], "query": [ { "key": "fhir_server", @@ -201,18 +231,18 @@ } ] }, - "description": "# Set Up\n\nThis API request demonstrates the TEFCA Query Connector's ability to query a Qualified Health Information Network (QHIN) for a given patient and return data relevant to a case investigation. The query represents a connection between a public health agency and a healthcare organization via a QHIN.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the TEFCA Query Connector. In addition to the FHIR patient resource, the TEFCA Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a query to the JMC Meld server via the eHealthExchange QHIN. The request is for data relevant to a gonorrhea case investigation for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=JMC Meld: eHealth Exchange&use_case=gonorrhea`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's gonorrhea case. For example, the returned results include a Patient resource and relevant Observation, Condition, Medication Request, and Encounter resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a gonorrhea query will only return observation resources that contain LOINC codes that are pertinent to a gonorrhea case investigation. If a resource is not present, e.g., if there are no Observation resources with gonorrhea-relevant LOINC codes, the response will not contain any Observation resources.\n\n## Expected resources returned from gonorrhea query\n\n- Patient\n \n- Conditions\n \n- Diagnostic Reports\n \n- Encounters\n \n- Medication Requests\n \n- Observations\n \n\n## LOINC codes included in gonorrhea query\n\n| **Code** | **Value** |\n| --- | --- |\n| 24111-7 | Neisseria gonorrhoeae DNA \\[Presence\\] in Unspecified specimen by NAA with probe detection |\n| 11350-6 | History of Sexual behavior Narrative |\n| 21613-5 | Chlamydia trachomatis DNA \\[Presence\\] in Unspecified specimen by NAA with probe detection |\n| 82810-3 | Pregnancy status |\n| 83317-8 | Sexual activity with anonymous partner in the past year |\n\n## SNOMED codes included in gonorrhea query\n\n| **Code** | **Value** |\n| --- | --- |\n| 2339001 | Sexual overexposure |\n| 72531000052105 | Contraceptive counseling |\n| 102874004 | Possible pregnancy |\n| 15628003 | Gonorrhea |\n\n## RxNorm codes included in gonorrhea query\n\n| **Code** | **Value** |\n| --- | --- |\n| 434692 | azithromycin 1000 MG |\n| 1665005 | ceftriaxone 500 MG Injection |" + "description": "# Set Up\n\nThis API request demonstrates the Query Connector's ability to query a Qualified Health Information Network (QHIN) for a given patient and return data relevant to a case investigation. The query represents a connection between a public health agency and a healthcare organization via a QHIN.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the Query Connector. In addition to the FHIR patient resource, the Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a query to the JMC Meld server via the eHealthExchange QHIN. The request is for data relevant to a gonorrhea case investigation for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=JMC Meld: eHealth Exchange&use_case=gonorrhea`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's gonorrhea case. For example, the returned results include a Patient resource and relevant Observation, Condition, Medication Request, and Encounter resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a gonorrhea query will only return observation resources that contain LOINC codes that are pertinent to a gonorrhea case investigation. If a resource is not present, e.g., if there are no Observation resources with gonorrhea-relevant LOINC codes, the response will not contain any Observation resources.\n\n## Expected resources returned from gonorrhea query\n\n- Patient\n \n- Conditions\n \n- Diagnostic Reports\n \n- Encounters\n \n- Medication Requests\n \n- Observations\n \n\n## LOINC codes included in gonorrhea query\n\n| **Code** | **Value** |\n| --- | --- |\n| 24111-7 | Neisseria gonorrhoeae DNA \\[Presence\\] in Unspecified specimen by NAA with probe detection |\n| 11350-6 | History of Sexual behavior Narrative |\n| 21613-5 | Chlamydia trachomatis DNA \\[Presence\\] in Unspecified specimen by NAA with probe detection |\n| 82810-3 | Pregnancy status |\n| 83317-8 | Sexual activity with anonymous partner in the past year |\n\n## SNOMED codes included in gonorrhea query\n\n| **Code** | **Value** |\n| --- | --- |\n| 2339001 | Sexual overexposure |\n| 72531000052105 | Contraceptive counseling |\n| 102874004 | Possible pregnancy |\n| 15628003 | Gonorrhea |\n\n## RxNorm codes included in gonorrhea query\n\n| **Code** | **Value** |\n| --- | --- |\n| 434692 | azithromycin 1000 MG |\n| 1665005 | ceftriaxone 500 MG Injection |" }, "response": [] }, { - "name": "Newborn Screening - CernerHelios: eHealthExchange", + "name": "Newborn Screening - HELIOS Meld: Direct", "request": { "method": "POST", "header": [], "body": { "mode": "raw", - "raw": "{\r\n \"resourceType\": \"Patient\",\r\n \"id\": \"12846634\",\r\n \"meta\": {\r\n \"versionId\": \"3\",\r\n \"lastUpdated\": \"2024-01-12T21:58:27.000Z\"\r\n },\r\n \"text\": {\r\n \"status\": \"generated\",\r\n \"div\": \"

Patient

Name: HILL, CUCUMBER

Status: Active

DOB: Aug 29, 2023

Administrative Gender: Female

Marital Status: Single

\"\r\n },\r\n \"extension\": [\r\n {\r\n \"extension\": [\r\n {\r\n \"valueCoding\": {\r\n \"system\": \"urn:oid:2.16.840.1.113883.6.238\",\r\n \"code\": \"2106-3\",\r\n \"display\": \"White\",\r\n \"userSelected\": false\r\n },\r\n \"url\": \"ombCategory\"\r\n },\r\n {\r\n \"valueString\": \"White\",\r\n \"url\": \"text\"\r\n }\r\n ],\r\n \"url\": \"http://hl7.org/fhir/us/core/StructureDefinition/us-core-race\"\r\n },\r\n {\r\n \"extension\": [\r\n {\r\n \"valueCoding\": {\r\n \"system\": \"urn:oid:2.16.840.1.113883.6.238\",\r\n \"code\": \"2186-5\",\r\n \"display\": \"Not Hispanic or Latino\",\r\n \"userSelected\": false\r\n },\r\n \"url\": \"ombCategory\"\r\n },\r\n {\r\n \"valueString\": \"Not Hispanic, Latino, or Spanish Origin\",\r\n \"url\": \"text\"\r\n }\r\n ],\r\n \"url\": \"http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity\"\r\n }\r\n ],\r\n \"identifier\": [\r\n {\r\n \"id\": \"CI-490339975-0\",\r\n \"use\": \"usual\",\r\n \"type\": {\r\n \"coding\": [\r\n {\r\n \"system\": \"https://fhir.cerner.com/e8a84236-c258-4952-98b7-a6ff8a9c587a/codeSet/4\",\r\n \"code\": \"10\",\r\n \"display\": \"MRN\",\r\n \"userSelected\": true\r\n },\r\n {\r\n \"system\": \"http://terminology.hl7.org/CodeSystem/v2-0203\",\r\n \"code\": \"MR\",\r\n \"display\": \"Medical record number\",\r\n \"userSelected\": false\r\n }\r\n ],\r\n \"text\": \"MRN\"\r\n },\r\n \"system\": \"urn:oid:2.16.840.1.113883.3.0.0.5\",\r\n \"value\": \"18091\",\r\n \"_value\": {\r\n \"extension\": [\r\n {\r\n \"valueString\": \"MX00018091\",\r\n \"url\": \"http://hl7.org/fhir/StructureDefinition/rendered-value\"\r\n }\r\n ]\r\n },\r\n \"period\": {\r\n \"start\": \"2023-08-29T16:00:27.000Z\"\r\n }\r\n },\r\n {\r\n \"id\": \"CI-490339977-1\",\r\n \"use\": \"usual\",\r\n \"type\": {\r\n \"coding\": [\r\n {\r\n \"system\": \"https://fhir.cerner.com/e8a84236-c258-4952-98b7-a6ff8a9c587a/codeSet/4\",\r\n \"code\": \"2553236785\",\r\n \"display\": \"MIllennium Person Identifier\",\r\n \"userSelected\": true\r\n }\r\n ],\r\n \"text\": \"MIllennium Person Identifier\"\r\n },\r\n \"_system\": {\r\n \"extension\": [\r\n {\r\n \"valueCode\": \"unknown\",\r\n \"url\": \"http://hl7.org/fhir/StructureDefinition/data-absent-reason\"\r\n }\r\n ]\r\n },\r\n \"value\": \"6155\",\r\n \"_value\": {\r\n \"extension\": [\r\n {\r\n \"valueString\": \"6155\",\r\n \"url\": \"http://hl7.org/fhir/StructureDefinition/rendered-value\"\r\n }\r\n ]\r\n },\r\n \"period\": {\r\n \"start\": \"2023-08-29T16:00:27.000Z\"\r\n }\r\n }\r\n ],\r\n \"active\": true,\r\n \"name\": [\r\n {\r\n \"id\": \"CI-12846634-0\",\r\n \"use\": \"official\",\r\n \"text\": \"HILL, CUCUMBER\",\r\n \"family\": \"HILL\",\r\n \"given\": [\r\n \"CUCUMBER\"\r\n ],\r\n \"period\": {\r\n \"start\": \"2023-08-29T16:00:28.000Z\"\r\n }\r\n }\r\n ],\r\n \"telecom\": [\r\n {\r\n \"id\": \"CI-PH-29877149-0\",\r\n \"extension\": [\r\n {\r\n \"valueUrl\": \"(816)111-2222\",\r\n \"url\": \"http://hl7.org/fhir/StructureDefinition/iso21090-TEL-address\"\r\n }\r\n ],\r\n \"system\": \"phone\",\r\n \"value\": \"8161112222\",\r\n \"use\": \"home\",\r\n \"rank\": 1,\r\n \"period\": {\r\n \"start\": \"2023-08-29T16:13:51.000Z\"\r\n }\r\n }\r\n ],\r\n \"gender\": \"female\",\r\n \"birthDate\": \"2023-08-29\",\r\n \"deceasedBoolean\": false,\r\n \"address\": [\r\n {\r\n \"id\": \"CI-24375992-0\",\r\n \"use\": \"home\",\r\n \"text\": \"551 MAIN ST\\nKANSAS CITY, MO 64003\\nUS\",\r\n \"line\": [\r\n \"551 MAIN ST\"\r\n ],\r\n \"city\": \"KANSAS CITY\",\r\n \"district\": \"Jackson\",\r\n \"state\": \"MO\",\r\n \"postalCode\": \"64003\",\r\n \"country\": \"US\",\r\n \"period\": {\r\n \"start\": \"2023-08-29T15:58:00.000Z\"\r\n }\r\n }\r\n ],\r\n \"maritalStatus\": {\r\n \"coding\": [\r\n {\r\n \"system\": \"https://fhir.cerner.com/e8a84236-c258-4952-98b7-a6ff8a9c587a/codeSet/38\",\r\n \"code\": \"309239\",\r\n \"display\": \"Single\",\r\n \"userSelected\": true\r\n },\r\n {\r\n \"system\": \"http://terminology.hl7.org/CodeSystem/v3-MaritalStatus\",\r\n \"code\": \"S\",\r\n \"display\": \"Never Married\",\r\n \"userSelected\": false\r\n }\r\n ],\r\n \"text\": \"Single\"\r\n },\r\n \"contact\": [\r\n {\r\n \"relationship\": [\r\n {\r\n \"coding\": [\r\n {\r\n \"system\": \"https://fhir.cerner.com/e8a84236-c258-4952-98b7-a6ff8a9c587a/codeSet/351\",\r\n \"code\": \"1159\",\r\n \"display\": \"Next of Kin\",\r\n \"userSelected\": true\r\n },\r\n {\r\n \"system\": \"http://terminology.hl7.org/CodeSystem/v2-0131\",\r\n \"code\": \"N\",\r\n \"display\": \"Next-of-Kin\",\r\n \"userSelected\": false\r\n }\r\n ],\r\n \"text\": \"Next of Kin\"\r\n }\r\n ],\r\n \"name\": {\r\n \"id\": \"CI-12846756-0\",\r\n \"use\": \"official\",\r\n \"text\": \"HILL, ORANGE\",\r\n \"family\": \"HILL\",\r\n \"given\": [\r\n \"ORANGE\"\r\n ],\r\n \"period\": {\r\n \"start\": \"2023-09-01T13:38:07.000Z\"\r\n }\r\n },\r\n \"telecom\": [\r\n {\r\n \"extension\": [\r\n {\r\n \"valueUrl\": \"(816)555-1234\",\r\n \"url\": \"http://hl7.org/fhir/StructureDefinition/iso21090-TEL-address\"\r\n }\r\n ],\r\n \"system\": \"phone\",\r\n \"value\": \"8165551234\",\r\n \"use\": \"home\",\r\n \"rank\": 1,\r\n \"period\": {\r\n \"start\": \"2023-09-01T13:38:07.000Z\"\r\n }\r\n },\r\n {\r\n \"extension\": [\r\n {\r\n \"valueUrl\": \"(816)111-2222\",\r\n \"url\": \"http://hl7.org/fhir/StructureDefinition/iso21090-TEL-address\"\r\n }\r\n ],\r\n \"system\": \"phone\",\r\n \"value\": \"8161112222\",\r\n \"use\": \"mobile\",\r\n \"rank\": 1,\r\n \"period\": {\r\n \"start\": \"2023-09-01T13:38:07.000Z\"\r\n }\r\n }\r\n ],\r\n \"address\": {\r\n \"use\": \"home\",\r\n \"text\": \"551 MAIN ST\\nKANSAS CITY, MO 64030\\nUS\",\r\n \"line\": [\r\n \"551 MAIN ST\"\r\n ],\r\n \"city\": \"KANSAS CITY\",\r\n \"district\": \"Jackson\",\r\n \"state\": \"MO\",\r\n \"postalCode\": \"64030\",\r\n \"country\": \"US\",\r\n \"period\": {\r\n \"start\": \"2023-08-29T14:57:48.000Z\"\r\n }\r\n },\r\n \"gender\": \"female\",\r\n \"period\": {\r\n \"start\": \"2023-09-01T13:38:07.000Z\"\r\n }\r\n },\r\n {\r\n \"relationship\": [\r\n {\r\n \"coding\": [\r\n {\r\n \"system\": \"https://fhir.cerner.com/e8a84236-c258-4952-98b7-a6ff8a9c587a/codeSet/351\",\r\n \"code\": \"1159\",\r\n \"display\": \"Next of Kin\",\r\n \"userSelected\": true\r\n },\r\n {\r\n \"system\": \"http://terminology.hl7.org/CodeSystem/v2-0131\",\r\n \"code\": \"N\",\r\n \"display\": \"Next-of-Kin\",\r\n \"userSelected\": false\r\n }\r\n ],\r\n \"text\": \"Next of Kin\"\r\n }\r\n ],\r\n \"name\": {\r\n \"id\": \"CI-12846635-1\",\r\n \"use\": \"official\",\r\n \"text\": \"HILL, ORANGE\",\r\n \"family\": \"HILL\",\r\n \"given\": [\r\n \"ORANGE\"\r\n ],\r\n \"period\": {\r\n \"start\": \"2023-08-29T16:00:28.000Z\"\r\n }\r\n },\r\n \"telecom\": [\r\n {\r\n \"extension\": [\r\n {\r\n \"valueUrl\": \"(816)111-2222\",\r\n \"url\": \"http://hl7.org/fhir/StructureDefinition/iso21090-TEL-address\"\r\n }\r\n ],\r\n \"system\": \"phone\",\r\n \"value\": \"8161112222\",\r\n \"use\": \"mobile\",\r\n \"rank\": 1,\r\n \"period\": {\r\n \"start\": \"2023-08-29T16:00:27.000Z\"\r\n }\r\n }\r\n ],\r\n \"address\": {\r\n \"use\": \"home\",\r\n \"text\": \"551 Main St\\nKansas City, MO 64030\\nUS\",\r\n \"line\": [\r\n \"551 Main St\"\r\n ],\r\n \"city\": \"Kansas City\",\r\n \"district\": \"Jackson\",\r\n \"state\": \"MO\",\r\n \"postalCode\": \"64030\",\r\n \"country\": \"US\",\r\n \"period\": {\r\n \"start\": \"2023-08-29T14:57:48.000Z\"\r\n }\r\n },\r\n \"gender\": \"female\",\r\n \"period\": {\r\n \"start\": \"2023-08-29T16:00:27.000Z\",\r\n \"end\": \"2023-09-01T13:38:07.000Z\"\r\n }\r\n }\r\n ],\r\n \"communication\": [\r\n {\r\n \"language\": {\r\n \"coding\": [\r\n {\r\n \"system\": \"https://fhir.cerner.com/e8a84236-c258-4952-98b7-a6ff8a9c587a/codeSet/36\",\r\n \"code\": \"151\",\r\n \"display\": \"English\",\r\n \"userSelected\": true\r\n },\r\n {\r\n \"system\": \"urn:ietf:bcp:47\",\r\n \"code\": \"en\",\r\n \"display\": \"English\",\r\n \"userSelected\": false\r\n }\r\n ],\r\n \"text\": \"English\"\r\n },\r\n \"preferred\": true\r\n }\r\n ],\r\n \"generalPractitioner\": [\r\n {\r\n \"id\": \"CI-490339987-0\",\r\n \"reference\": \"Practitioner/769942\",\r\n \"display\": \"Cerner Test, Physician - Neonatology Cerner\"\r\n }\r\n ]\r\n}", + "raw": "{\r\n \"resourceType\": \"Patient\",\r\n \"id\": \"475032B\",\r\n \"identifier\": [\r\n {\r\n \"use\": \"official\",\r\n \"system\": \"http://hospital.smarthealthit.org\",\r\n \"value\": \"67890\"\r\n },\r\n {\r\n \"use\": \"usual\",\r\n \"system\": \"http://hospital.smarthealthit.org/mrn\",\r\n \"value\": \"MRN123456\"\r\n }\r\n ],\r\n \"name\": [\r\n {\r\n \"use\": \"official\",\r\n \"family\": \"Smith\",\r\n \"given\": [\r\n \"Mango\"\r\n ]\r\n }\r\n ],\r\n \"telecom\": [\r\n {\r\n \"system\": \"phone\",\r\n \"value\": \"555-123-4567\",\r\n \"use\": \"home\"\r\n }\r\n ],\r\n \"address\": [\r\n {\r\n \"use\": \"home\",\r\n \"line\": [\r\n \"123 Fake Street\"\r\n ],\r\n \"city\": \"Faketown\",\r\n \"state\": \"CA\",\r\n \"postalCode\": \"12345\",\r\n \"country\": \"USA\"\r\n }\r\n ],\r\n \"gender\": \"female\",\r\n \"birthDate\": \"2024-07-12\"\r\n}", "options": { "raw": { "language": "json" @@ -220,13 +250,18 @@ } }, "url": { - "raw": "{{base_url}}/api/query?fhir_server=CernerHelios: eHealthExchange&use_case=newborn-screening", - "host": ["{{base_url}}"], - "path": ["api", "query"], + "raw": "{{base_url}}/api/query?fhir_server=HELIOS Meld: Direct&use_case=newborn-screening", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "query" + ], "query": [ { "key": "fhir_server", - "value": "CernerHelios: eHealthExchange" + "value": "HELIOS Meld: Direct" }, { "key": "use_case", @@ -234,7 +269,7 @@ } ] }, - "description": "# Set Up\n\nThis API request demonstrates the TEFCA Query Connector's ability to query a Qualified Health Information Network (QHIN) for a given patient and return data relevant to a case investigation. The query represents a connection between a public health agency and a healthcare organization via a QHIN.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the TEFCA Query Connector. In addition to the FHIR patient resource, the TEFCA Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a query to the CernerHelios server via the eHealthExchange QHIN. The request is for data relevant to a newborn screening for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=CernerHelios: eHealthExchange&use_case=newborn-screening`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's newborn screening. For example, the returned results include a Patient resource and relevant Observation resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a newborn screening query will only return observation resources that contain LOINC codes that are pertinent to a newborn screening query. If a resource is not present, e.g., if there are no Observation resources with newborn-screening-relevant LOINC codes, the response will not contain any Observation resources.\n\n## Expected resources returned from newborn screening query\n\n- Patient\n \n- Observations\n \n\n## LOINC codes included in newborn screening query\n\n| **Code** | **Value** |\n| --- | --- |\n| 73700-7 | CCHD newborn screening interpretation |\n| 73698-3 | Reason CCHD oxygen saturation screening not performed |\n| 54108-6 | Newborn hearing screen of Ear - left |\n| 54109-4 | Newborn hearing screen of Ear - right |\n| 58232-0 | Hearing loss risk indicators \\[Identifier\\] |\n| 57700-7 | Hearing loss newborn screening comment/discussion |\n| 73739-5 | Newborn hearing screen reason not performed of Ear - left |\n| 73742-9 | Newborn hearing screen reason not performed of Ear - right |\n| 2708-6 | Cannabinoids \\[Presence\\] in Vitreous fluid |\n| 8336-0 | Body weight \\[Percentile\\] Per age |\n\n## SNOMED codes included in newborn screening query\n\nNot applicable for this use case\n\n## RxNorm codes included in newborn screening query\n\nNot applicable for this use case" + "description": "# Set Up\n\nThis API request demonstrates the Query Connector's ability to directly query a server for a given patient and return data relevant to a case investigation. The direct query represents a point-to-point connection between a public health agency and a healthcare organization.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the Query Connector. In addition to the FHIR patient resource, the Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a direct query to the HELIOS Meld server. The request is for data relevant to a newborn screening for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=HELIOS Meld: Direct&use_case=newborn-screening`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's newborn screening. For example, the returned results include a Patient resource and relevant Observation resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a newborn screening query will only return observation resources that contain LOINC codes that are pertinent to a newborn screening query. If a resource is not present, e.g., if there are no Observation resources with newborn-screening-relevant LOINC codes, the response will not contain any Observation resources.\n\n## Expected resources returned from newborn screening query\n\n- Patient\n \n- Observations\n \n\n## LOINC codes included in newborn screening query\n\n| **Code** | **Value** |\n| --- | --- |\n| 73700-7 | CCHD newborn screening interpretation |\n| 73698-3 | Reason CCHD oxygen saturation screening not performed |\n| 54108-6 | Newborn hearing screen of Ear - left |\n| 54109-4 | Newborn hearing screen of Ear - right |\n| 58232-0 | Hearing loss risk indicators \\[Identifier\\] |\n| 57700-7 | Hearing loss newborn screening comment/discussion |\n| 73739-5 | Newborn hearing screen reason not performed of Ear - left |\n| 73742-9 | Newborn hearing screen reason not performed of Ear - right |\n| 2708-6 | Cannabinoids \\[Presence\\] in Vitreous fluid |\n| 8336-0 | Body weight \\[Percentile\\] Per age |\n\n## SNOMED codes included in newborn screening query\n\nNot applicable for this use case\n\n## RxNorm codes included in newborn screening query\n\nNot applicable for this use case" }, "response": [] }, @@ -253,46 +288,18 @@ } }, "url": { - "raw": "{{base_url}}/api/query?fhir_server=Helios Meld: eHealthExchange&use_case=newborn-screening", - "host": ["{{base_url}}"], - "path": ["api", "query"], + "raw": "{{base_url}}/api/query?fhir_server=HELIOS Meld: eHealthExchange&use_case=newborn-screening", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "query" + ], "query": [ { "key": "fhir_server", - "value": "Helios Meld: eHealthExchange" - }, - { - "key": "use_case", - "value": "newborn-screening" - } - ] - }, - "description": "# Set Up\n\nThis API request demonstrates the TEFCA Query Connector's ability to query a Qualified Health Information Network (QHIN) for a given patient and return data relevant to a case investigation. The query represents a connection between a public health agency and a healthcare organization via a QHIN.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the TEFCA Query Connector. In addition to the FHIR patient resource, the TEFCA Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a query to the HELIOS Meld server via the eHealthExchange QHIN. The request is for data relevant to a newborn screening for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=HELIOS Meld: eHealthExchange&use_case=newborn-screening`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's newborn screening. For example, the returned results include a Patient resource and relevant Observation resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a newborn screening query will only return observation resources that contain LOINC codes that are pertinent to a newborn screening query. If a resource is not present, e.g., if there are no Observation resources with newborn-screening-relevant LOINC codes, the response will not contain any Observation resources.\n\n## Expected resources returned from newborn screening query\n\n- Patient\n \n- Observations\n \n\n## LOINC codes included in newborn screening query\n\n| **Code** | **Value** |\n| --- | --- |\n| 73700-7 | CCHD newborn screening interpretation |\n| 73698-3 | Reason CCHD oxygen saturation screening not performed |\n| 54108-6 | Newborn hearing screen of Ear - left |\n| 54109-4 | Newborn hearing screen of Ear - right |\n| 58232-0 | Hearing loss risk indicators \\[Identifier\\] |\n| 57700-7 | Hearing loss newborn screening comment/discussion |\n| 73739-5 | Newborn hearing screen reason not performed of Ear - left |\n| 73742-9 | Newborn hearing screen reason not performed of Ear - right |\n| 2708-6 | Cannabinoids \\[Presence\\] in Vitreous fluid |\n| 8336-0 | Body weight \\[Percentile\\] Per age |\n\n## SNOMED codes included in newborn screening query\n\nNot applicable for this use case\n\n## RxNorm codes included in newborn screening query\n\nNot applicable for this use case" - }, - "response": [] - }, - { - "name": "Newborn Screening - HELIOS Meld: Direct", - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"resourceType\": \"Patient\",\r\n \"id\": \"475032B\",\r\n \"identifier\": [\r\n {\r\n \"use\": \"official\",\r\n \"system\": \"http://hospital.smarthealthit.org\",\r\n \"value\": \"67890\"\r\n },\r\n {\r\n \"use\": \"usual\",\r\n \"system\": \"http://hospital.smarthealthit.org/mrn\",\r\n \"value\": \"MRN123456\"\r\n }\r\n ],\r\n \"name\": [\r\n {\r\n \"use\": \"official\",\r\n \"family\": \"Smith\",\r\n \"given\": [\r\n \"Mango\"\r\n ]\r\n }\r\n ],\r\n \"telecom\": [\r\n {\r\n \"system\": \"phone\",\r\n \"value\": \"555-123-4567\",\r\n \"use\": \"home\"\r\n }\r\n ],\r\n \"address\": [\r\n {\r\n \"use\": \"home\",\r\n \"line\": [\r\n \"123 Fake Street\"\r\n ],\r\n \"city\": \"Faketown\",\r\n \"state\": \"CA\",\r\n \"postalCode\": \"12345\",\r\n \"country\": \"USA\"\r\n }\r\n ],\r\n \"gender\": \"female\",\r\n \"birthDate\": \"2024-07-12\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{base_url}}/api/query?fhir_server=HELIOS Meld: Direct&use_case=newborn-screening", - "host": ["{{base_url}}"], - "path": ["api", "query"], - "query": [ - { - "key": "fhir_server", - "value": "HELIOS Meld: Direct" + "value": "HELIOS Meld: eHealthExchange" }, { "key": "use_case", @@ -300,7 +307,7 @@ } ] }, - "description": "# Set Up\n\nThis API request demonstrates the TEFCA Query Connector's ability to query a Qualified Health Information Network (QHIN) for a given patient and return data relevant to a case investigation. The direct query represents a point-to-point connection between a public health agency and a healthcare organization.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the TEFCA Query Connector. In addition to the FHIR patient resource, the TEFCA Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a query to the HELIOS Meld server directly. The request is for data relevant to a newborn screening for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=HELIOS Meld:Direct&use_case=newborn-screening`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's newborn screening. For example, the returned results include a Patient resource and relevant Observation resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a newborn screening query will only return observation resources that contain LOINC codes that are pertinent to a newborn screening query. If a resource is not present, e.g., if there are no Observation resources with newborn-screening-relevant LOINC codes, the response will not contain any Observation resources.\n\n## Expected resources returned from newborn screening query\n\n- Patient\n \n- Observations\n \n\n## LOINC codes included in newborn screening query\n\n| **Code** | **Value** |\n| --- | --- |\n| 73700-7 | CCHD newborn screening interpretation |\n| 73698-3 | Reason CCHD oxygen saturation screening not performed |\n| 54108-6 | Newborn hearing screen of Ear - left |\n| 54109-4 | Newborn hearing screen of Ear - right |\n| 58232-0 | Hearing loss risk indicators \\[Identifier\\] |\n| 57700-7 | Hearing loss newborn screening comment/discussion |\n| 73739-5 | Newborn hearing screen reason not performed of Ear - left |\n| 73742-9 | Newborn hearing screen reason not performed of Ear - right |\n| 2708-6 | Cannabinoids \\[Presence\\] in Vitreous fluid |\n| 8336-0 | Body weight \\[Percentile\\] Per age |\n\n## SNOMED codes included in newborn screening query\n\nNot applicable for this use case\n\n## RxNorm codes included in newborn screening query\n\nNot applicable for this use case" + "description": "# Set Up\n\nThis API request demonstrates the Query Connector's ability to query a Qualified Health Information Network (QHIN) for a given patient and return data relevant to a case investigation. The query represents a connection between a public health agency and a healthcare organization via a QHIN.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the Query Connector. In addition to the FHIR patient resource, the Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a query to the HELIOS Meld server via the eHealthExchange QHIN. The request is for data relevant to a newborn screening for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=HELIOS Meld: eHealthExchange&use_case=newborn-screening`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's newborn screening. For example, the returned results include a Patient resource and relevant Observation resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a newborn screening query will only return observation resources that contain LOINC codes that are pertinent to a newborn screening query. If a resource is not present, e.g., if there are no Observation resources with newborn-screening-relevant LOINC codes, the response will not contain any Observation resources.\n\n## Expected resources returned from newborn screening query\n\n- Patient\n \n- Observations\n \n\n## LOINC codes included in newborn screening query\n\n| **Code** | **Value** |\n| --- | --- |\n| 73700-7 | CCHD newborn screening interpretation |\n| 73698-3 | Reason CCHD oxygen saturation screening not performed |\n| 54108-6 | Newborn hearing screen of Ear - left |\n| 54109-4 | Newborn hearing screen of Ear - right |\n| 58232-0 | Hearing loss risk indicators \\[Identifier\\] |\n| 57700-7 | Hearing loss newborn screening comment/discussion |\n| 73739-5 | Newborn hearing screen reason not performed of Ear - left |\n| 73742-9 | Newborn hearing screen reason not performed of Ear - right |\n| 2708-6 | Cannabinoids \\[Presence\\] in Vitreous fluid |\n| 8336-0 | Body weight \\[Percentile\\] Per age |\n\n## SNOMED codes included in newborn screening query\n\nNot applicable for this use case\n\n## RxNorm codes included in newborn screening query\n\nNot applicable for this use case" }, "response": [] }, @@ -320,8 +327,13 @@ }, "url": { "raw": "{{base_url}}/api/query?fhir_server=HELIOS Meld: Direct&use_case=social-determinants", - "host": ["{{base_url}}"], - "path": ["api", "query"], + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "query" + ], "query": [ { "key": "fhir_server", @@ -333,7 +345,7 @@ } ] }, - "description": "# Set Up\n\nThis API request demonstrates the TEFCA Query Connector's ability to directly query a server for a given patient and return data relevant to a case investigation. The direct query represents a point-to-point connection between a public health agency and a healthcare organization.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the TEFCA Query Connector. In addition to the FHIR patient resource, the TEFCA Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a direct query to the Helios Meld server. The request is for data relevant to a cancer query for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=HELIOS Meld: Direct&use_case=social-determinants`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's social determinants of health follow-up. For example, the returned results include a Patient resource and relevant Observation resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. In the case of social determinants of health queries, the query returns Observation resources where the category is `social-history` only. If an Observation resource does not have the category label `social-history`, it will not be returned as part of the response.\n\n## Expected resources returned from social determinants query\n\n- Patient\n \n- Observations where the `category` = `social-history`\n \n\n## LOINC codes included in social determinants query\n\nNot applicable for this use case\n\n## SNOMED codes included in social determinants query\n\nNot applicable for this use case\n\n## RxNorm codes included in social determinants query\n\nNot applicable for this use case" + "description": "# Set Up\n\nThis API request demonstrates the Query Connector's ability to directly query a server for a given patient and return data relevant to a case investigation. The direct query represents a point-to-point connection between a public health agency and a healthcare organization.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the Query Connector. In addition to the FHIR patient resource, the Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a direct query to the Helios Meld server. The request is for data relevant to a cancer query for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=HELIOS Meld: Direct&use_case=social-determinants`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's social determinants of health follow-up. For example, the returned results include a Patient resource and relevant Observation resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. In the case of social determinants of health queries, the query returns Observation resources where the category is `social-history` only. If an Observation resource does not have the category label `social-history`, it will not be returned as part of the response.\n\n## Expected resources returned from social determinants query\n\n- Patient\n \n- Observations where the `category` = `social-history`\n \n\n## LOINC codes included in social determinants query\n\nNot applicable for this use case\n\n## SNOMED codes included in social determinants query\n\nNot applicable for this use case\n\n## RxNorm codes included in social determinants query\n\nNot applicable for this use case" }, "response": [] }, @@ -353,8 +365,13 @@ }, "url": { "raw": "{{base_url}}/api/query?fhir_server=HELIOS Meld: eHealthExchange&use_case=social-determinants", - "host": ["{{base_url}}"], - "path": ["api", "query"], + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "query" + ], "query": [ { "key": "fhir_server", @@ -366,7 +383,7 @@ } ] }, - "description": "StartFragment\n\n# Set Up\n\nThis API request demonstrates the TEFCA Query Connector's ability to query a Qualified Health Information Network (QHIN) for a given patient and return data relevant to a case investigation. The query represents a connection between a public health agency and a healthcare organization via a QHIN.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the TEFCA Query Connector. In addition to the FHIR patient resource, the TEFCA Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a query to the HELIOS Meld server via the eHealthExchange QHIN. The request is for data relevant to a cancer query for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=HELIOS Meld: eHealthExchange&use_case=social-determinants`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's cancer follow-up. For example, the returned results include a Patient resource and relevant Observation resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. In the case of social determinants of health queries, the query returns Observation resources where the category is `social-history` only. If an Observation resource does not have the category label `social-history`, it will not be returned as part of the response.\n\n## Expected resources returned from cancer query\n\n- Patient\n \n- Observations where the `category` = `social-history`\n \n\n## LOINC codes included in cancer query\n\nNot applicable for this use case\n\n## SNOMED codes included in cancer query\n\nNot applicable for this use case\n\n## RxNorm codes included in cancer query\n\nNot applicable for this use case" + "description": "StartFragment\n\n# Set Up\n\nThis API request demonstrates the Query Connector's ability to query a Qualified Health Information Network (QHIN) for a given patient and return data relevant to a case investigation. The query represents a connection between a public health agency and a healthcare organization via a QHIN.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the Query Connector. In addition to the FHIR patient resource, the Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a query to the HELIOS Meld server via the eHealthExchange QHIN. The request is for data relevant to a cancer query for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=HELIOS Meld: eHealthExchange&use_case=social-determinants`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's cancer follow-up. For example, the returned results include a Patient resource and relevant Observation resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. In the case of social determinants of health queries, the query returns Observation resources where the category is `social-history` only. If an Observation resource does not have the category label `social-history`, it will not be returned as part of the response.\n\n## Expected resources returned from cancer query\n\n- Patient\n \n- Observations where the `category` = `social-history`\n \n\n## LOINC codes included in cancer query\n\nNot applicable for this use case\n\n## SNOMED codes included in cancer query\n\nNot applicable for this use case\n\n## RxNorm codes included in cancer query\n\nNot applicable for this use case" }, "response": [] }, @@ -386,8 +403,13 @@ }, "url": { "raw": "{{base_url}}/api/query?fhir_server=HELIOS Meld: Direct&use_case=syphilis", - "host": ["{{base_url}}"], - "path": ["api", "query"], + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "query" + ], "query": [ { "key": "fhir_server", @@ -399,7 +421,7 @@ } ] }, - "description": "# Set Up\n\nThis API request demonstrates the TEFCA Query Connector's ability to directly query a server for a given patient and return data relevant to a case investigation. The direct query represents a point-to-point connection between a public health agency and a healthcare organization.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the TEFCA Query Connector. In addition to the FHIR patient resource, the TEFCA Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a direct query to the Helios Meld server. The request is for data relevant to a cancer query for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=HELIOS Meld: Direct&use_case=syphilis`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's cancer follow-up. For example, the returned results include a Patient resource and relevant Observation resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a syphilis query will only return observation resources that contain LOINC codes that are pertinent to a syphilis case investigation. If a resource is not present, e.g., if there are no Observation resources with syphilis -relevant LOINC codes, the response will not contain any Observation resources.\n\n## Expected resources returned from syphilis query\n\n- Patient\n \n- Conditions\n \n- Diagnostic Reports\n \n- Encounters\n \n- Medication Requests\n \n- Observations\n \n\n## LOINC codes included in syphilis query\n\n| **Code** | **Value** |\n|-----------|------------------------------------------------------------------------|\n| LP70657-9 | RPR | \n| 53605-2 | Treponema pallidum DNA [Presence] in Blood by NAA with probe detection |\n\n\n## SNOMED codes included in syphilis query\n\n| **Code** | **Value** |\n|-----------|------------------------------------------------------------------------|\n| 76272004 | Syphilis |\n| 186847001 | Primary genital syphilis |\n\n\n## RxNorm codes included in syphilis query\n\nNot applicable for this use case\n" + "description": "# Set Up\n\nThis API request demonstrates the Query Connector's ability to directly query a server for a given patient and return data relevant to a case investigation. The direct query represents a point-to-point connection between a public health agency and a healthcare organization.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the Query Connector. In addition to the FHIR patient resource, the Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a direct query to the Helios Meld server. The request is for data relevant to a cancer query for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=HELIOS Meld: Direct&use_case=syphilis`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's cancer follow-up. For example, the returned results include a Patient resource and relevant Observation resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a syphilis query will only return observation resources that contain LOINC codes that are pertinent to a syphilis case investigation. If a resource is not present, e.g., if there are no Observation resources with syphilis -relevant LOINC codes, the response will not contain any Observation resources.\n\n## Expected resources returned from syphilis query\n\n- Patient\n \n- Conditions\n \n- Diagnostic Reports\n \n- Encounters\n \n- Medication Requests\n \n- Observations\n \n\n## LOINC codes included in syphilis query\n\n| **Code** | **Value** |\n|-----------|------------------------------------------------------------------------|\n| LP70657-9 | RPR | \n| 53605-2 | Treponema pallidum DNA [Presence] in Blood by NAA with probe detection |\n\n\n## SNOMED codes included in syphilis query\n\n| **Code** | **Value** |\n|-----------|------------------------------------------------------------------------|\n| 76272004 | Syphilis |\n| 186847001 | Primary genital syphilis |\n\n\n## RxNorm codes included in syphilis query\n\nNot applicable for this use case\n" }, "response": [] }, @@ -418,9 +440,14 @@ } }, "url": { - "raw": "dibbs.cloud/api/query?fhir_server=HELIOS Meld: eHealthExchange&use_case=syphilis", - "host": ["dibbs", "cloud"], - "path": ["api", "query"], + "raw": "{{base_url}}/api/query?fhir_server=HELIOS Meld: eHealthExchange&use_case=syphilis", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "query" + ], "query": [ { "key": "fhir_server", @@ -432,7 +459,7 @@ } ] }, - "description": "# Set Up\n\nThis API request demonstrates the TEFCA Query Connector's ability to query a Qualified Health Information Network (QHIN) for a given patient and return data relevant to a case investigation. The query represents a connection between a public health agency and a healthcare organization via a QHIN.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the TEFCA Query Connector. In addition to the FHIR patient resource, the TEFCA Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a query to the HELIOS Meld server via the eHealthExchange QHIN. The request is for data relevant to a cancer query for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=HELIOS Meld: eHealthExchange&use_case=syphilis`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's syphilis case investigation. For example, the returned results include a Patient resource and relevant Observation resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a syphilis query will only return observation resources that contain LOINC codes that are pertinent to a syphilis case investigation. If a resource is not present, e.g., if there are no Encounter resources with syphilis-relevant SNOMED codes, the response will not contain any Encounter resources.\n\n## Expected resources returned from syphilis query\n\n- Patient\n \n- Conditions\n \n- Diagnostic Reports\n \n- Encounters\n \n- Medication Requests\n \n- Observations\n \n\n## LOINC codes included in syphilis query\n\n| **Code** | **Value** |\n| --- | --- |\n| LP70657-9 | RPR |\n| 53605-2 | Treponema pallidum DNA \\[Presence\\] in Blood by NAA with probe detection |\n\n## SNOMED codes included in syphilis query\n\n| **Code** | **Value** |\n| --- | --- |\n| 76272004 | Syphilis |\n| 186847001 | Primary genital syphilis |\n\n## RxNorm codes included in syphilis query\n\nNot applicable for this use case" + "description": "# Set Up\n\nThis API request demonstrates the Query Connector's ability to query a Qualified Health Information Network (QHIN) for a given patient and return data relevant to a case investigation. The query represents a connection between a public health agency and a healthcare organization via a QHIN.\n\nThe **Body** tab shows FHIR patient resource to be submitted to the Query Connector. In addition to the FHIR patient resource, the Query Connector requires users to submit `fhir_server` and `use_case` parameters to specify where to make the query and to determine which relevant data should be returned to the user.\n\nFor this example API call, the user wants to make a query to the HELIOS Meld server via the eHealthExchange QHIN. The request is for data relevant to a cancer query for a particular patient whose demographic data is sent in the Body of the request. To make this request, the API includes the following query parameters: `?fhir_server=HELIOS Meld: eHealthExchange&use_case=syphilis`. This information is also viewable in the **Params** tab.\n\nAfter hitting **Send** on the request, we can check the **Response** at the bottom of the page to see the returned FHIR resources that are relevant to this patient's syphilis case investigation. For example, the returned results include a Patient resource and relevant Observation resources.\n\n# Expected Response\n\nThe expected response of a query is a FHIR bundle containing a Patient resource and resources that are specific to the use case query as indicated by the presence of a relevant LOINC, SNOMED, and/or RxNorm code. For example, a syphilis query will only return observation resources that contain LOINC codes that are pertinent to a syphilis case investigation. If a resource is not present, e.g., if there are no Encounter resources with syphilis-relevant SNOMED codes, the response will not contain any Encounter resources.\n\n## Expected resources returned from syphilis query\n\n- Patient\n \n- Conditions\n \n- Diagnostic Reports\n \n- Encounters\n \n- Medication Requests\n \n- Observations\n \n\n## LOINC codes included in syphilis query\n\n| **Code** | **Value** |\n| --- | --- |\n| LP70657-9 | RPR |\n| 53605-2 | Treponema pallidum DNA \\[Presence\\] in Blood by NAA with probe detection |\n\n## SNOMED codes included in syphilis query\n\n| **Code** | **Value** |\n| --- | --- |\n| 76272004 | Syphilis |\n| 186847001 | Primary genital syphilis |\n\n## RxNorm codes included in syphilis query\n\nNot applicable for this use case" }, "response": [] } @@ -443,7 +470,9 @@ "script": { "type": "text/javascript", "packages": {}, - "exec": [""] + "exec": [ + "" + ] } }, { @@ -451,7 +480,9 @@ "script": { "type": "text/javascript", "packages": {}, - "exec": [""] + "exec": [ + "" + ] } } ], @@ -462,4 +493,4 @@ "type": "string" } ] -} +} \ No newline at end of file From 8a5ade3e4514cdd9e2e4cf39f6d24e4d8ed4f4c3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 21 Nov 2024 08:58:37 -0500 Subject: [PATCH 3/9] [pre-commit.ci] pre-commit autoupdate (#164) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Rob Mitchell <40571882+robertandremitchell@users.noreply.github.com> Co-authored-by: Rob Mitchell --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e4b19fa07..c12b941cc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,7 @@ repos: name: Pretty Format JSON args: [--autofix, --no-sort-keys] - repo: https://github.com/pre-commit/mirrors-eslint - rev: "v9.14.0" + rev: "v9.15.0" hooks: - id: eslint name: ESLint From 58a40677aa5994f14b4890f4cd0bd77ddbfda37d Mon Sep 17 00:00:00 2001 From: Katie Campbell Downie Date: Thu, 21 Nov 2024 12:01:48 -0600 Subject: [PATCH 4/9] Save condition selections on template builder page (#161) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .../app/query/components/header/header.tsx | 6 +- .../query/designSystem/checkbox/Checkbox.tsx | 4 + .../ConditionColumnDisplay.tsx | 63 +++++++++++- .../buildFromTemplates/ConditionOption.tsx | 6 +- .../queryBuilding/buildFromTemplates/page.tsx | 98 ++++++++++++++++--- 5 files changed, 162 insertions(+), 15 deletions(-) diff --git a/query-connector/src/app/query/components/header/header.tsx b/query-connector/src/app/query/components/header/header.tsx index 381494b76..eb4b7fc39 100644 --- a/query-connector/src/app/query/components/header/header.tsx +++ b/query-connector/src/app/query/components/header/header.tsx @@ -136,4 +136,8 @@ export default function HeaderComponent() { ); } -const LOGGED_IN_PATHS = ["/query", "/queryBuilding"]; +const LOGGED_IN_PATHS = [ + "/query", + "/queryBuilding", + "/queryBuilding/buildFromTemplates", +]; diff --git a/query-connector/src/app/query/designSystem/checkbox/Checkbox.tsx b/query-connector/src/app/query/designSystem/checkbox/Checkbox.tsx index 6997ae131..e74225961 100644 --- a/query-connector/src/app/query/designSystem/checkbox/Checkbox.tsx +++ b/query-connector/src/app/query/designSystem/checkbox/Checkbox.tsx @@ -7,6 +7,7 @@ type CheckboxProps = { label: string; className?: string; onClick?: () => void; + checked: boolean; }; /** @@ -16,6 +17,7 @@ type CheckboxProps = { * @param root0.id HTML id used to reference the checkbox * @param root0.className Optional styling classes * @param root0.onClick Event listener for checkbox click + * @param root0.checked Boolean indicating whether the checkbox is checked * @returns A checkbox styled according to our design system */ const Checkbox: React.FC = ({ @@ -23,6 +25,7 @@ const Checkbox: React.FC = ({ id, className, onClick, + checked, }) => { return ( = ({ name={id} className={classNames(styles.checkbox, className)} onClick={onClick} + defaultChecked={checked} > ); }; diff --git a/query-connector/src/app/queryBuilding/buildFromTemplates/ConditionColumnDisplay.tsx b/query-connector/src/app/queryBuilding/buildFromTemplates/ConditionColumnDisplay.tsx index 782925ece..fa2269da8 100644 --- a/query-connector/src/app/queryBuilding/buildFromTemplates/ConditionColumnDisplay.tsx +++ b/query-connector/src/app/queryBuilding/buildFromTemplates/ConditionColumnDisplay.tsx @@ -6,13 +6,20 @@ import { import styles from "./buildfromTemplate.module.scss"; import ConditionOption from "./ConditionOption"; import classNames from "classnames"; +import { FormError } from "./page"; type ConditionColumnDisplayProps = { fetchedConditions: CategoryNameToConditionOptionMap; searchFilter: string | undefined; + selectedConditions: CategoryNameToConditionOptionMap; setFetchedConditions: Dispatch< SetStateAction >; + setSelectedConditions: Dispatch< + SetStateAction + >; + setFormError: Dispatch>; + formError: FormError; }; /** * Column display component for the query building page @@ -20,15 +27,27 @@ type ConditionColumnDisplayProps = { * @param root0.fetchedConditions - conditions queried from backend to display * @param root0.searchFilter - filter grabbed from search field to filter fetched * components against + * @param root0.selectedConditions - conditions the user has marked to included in + * their query * @param root0.setFetchedConditions - state function that updates the include / * exclude of the queryset + * @param root0.setSelectedConditions - state function that updates the subset of + * fetched conditions to be included in the query + * @param root0.setFormError - state function that updates the subset of + * fetched conditions to be included in the query + * @param root0.formError - state function that updates the subset of + * fetched conditions to be included in the query * @returns Conditions split out into two columns that will filter themselves * at both the category and condition levels if a valid search filter is applied. */ export const ConditionColumnDisplay: React.FC = ({ fetchedConditions, searchFilter, + selectedConditions, setFetchedConditions, + setSelectedConditions, + formError, + setFormError, }) => { const [conditionsToDisplay, setConditionsToDisplay] = useState(fetchedConditions); @@ -46,19 +65,60 @@ export const ConditionColumnDisplay: React.FC = ({ } }, [searchFilter]); - function toggleFetchedConditionSelection( + async function toggleFetchedConditionSelection( category: string, conditionId: string, ) { + const prevSelected = selectedConditions?.[category]?.[conditionId]?.include; const prevFetch = structuredClone(fetchedConditions); const prevValues = prevFetch[category][conditionId]; prevFetch[category][conditionId] = { name: prevValues.name, include: !prevValues.include, }; + + const shouldRemove = + // prevSelected being undefined means we've never added anything to selectedConditions, + // so we shouldn't remove anything + prevSelected == undefined + ? false + : // otherwise, if include was previously true and now its false, we should remove it + prevFetch[category][conditionId].include == true && + prevValues.include == false; + + updateSelectedConditions(shouldRemove, category, conditionId, prevFetch); setFetchedConditions(prevFetch); } + const updateSelectedConditions = ( + shouldRemove: boolean, + category: string, + conditionId: string, + prevFetch: CategoryNameToConditionOptionMap, + ) => { + if (shouldRemove) { + delete selectedConditions[category][conditionId]; + // if there are no more entries for a given category, remove the category + if (Object.values(selectedConditions[category]).length == 0) { + delete selectedConditions[category]; + } + // if there are no entries at all, set an error (to disable the button) + if (Object.values(selectedConditions).length < 1) { + setFormError({ ...formError, ...{ selectedConditions: true } }); + } + } else { + setSelectedConditions((prevState) => { + return { + ...prevState, + [category]: { + ...prevState?.[category], + [conditionId]: prevFetch[category]?.[conditionId], + }, + }; + }); + } + }; + const columnOneEntries = Object.entries(conditionsToDisplay).filter( (_, i) => i % 2 === 0, ); @@ -92,6 +152,7 @@ export const ConditionColumnDisplay: React.FC = ({ ([conditionId, conditionNameAndInclude]) => { return ( void; + checked: boolean; }; /** @@ -12,14 +13,16 @@ type ConditionOptionProps = { * @param root0 - params * @param root0.conditionId - ID of the condition to reference * @param root0.conditionName - name of condition to display - * @param root0.handleConditionSelection - listner function for checkbox + * @param root0.handleConditionSelection - listener function for checkbox * selection + * @param root0.checked - current checkbox selection status * @returns A component for display to redner on the query building page */ const ConditionOption: React.FC = ({ conditionId, conditionName, handleConditionSelection, + checked, }) => { return (
@@ -29,6 +32,7 @@ const ConditionOption: React.FC = ({ }} id={conditionId} label={formatDiseaseDisplay(conditionName)} + checked={checked} />
); diff --git a/query-connector/src/app/queryBuilding/buildFromTemplates/page.tsx b/query-connector/src/app/queryBuilding/buildFromTemplates/page.tsx index e4c64911b..38618299d 100644 --- a/query-connector/src/app/queryBuilding/buildFromTemplates/page.tsx +++ b/query-connector/src/app/queryBuilding/buildFromTemplates/page.tsx @@ -4,7 +4,7 @@ import Backlink from "@/app/query/components/backLink/Backlink"; import styles from "./buildfromTemplate.module.scss"; import { useRouter } from "next/navigation"; import { Button, Label, TextInput } from "@trussworks/react-uswds"; -import { useEffect, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import classNames from "classnames"; import { getConditionsData } from "@/app/database-service"; import { @@ -15,20 +15,49 @@ import ConditionColumnDisplay from "./ConditionColumnDisplay"; import SearchField from "@/app/query/designSystem/searchField/SearchField"; import SiteAlert from "@/app/query/designSystem/SiteAlert"; +export type FormError = { + queryName: boolean; + selectedConditions: boolean; +}; + /** * The query building page * @returns the component for the query building page */ export default function QueryTemplateSelection() { const router = useRouter(); - const [queryName, setQueryName] = useState(); + const focusRef = useRef(null); + + const [queryName, setQueryName] = useState(""); const [searchFilter, setSearchFilter] = useState(); const [fetchedConditions, setFetchedConditions] = useState(); + const [selectedConditions, setSelectedConditions] = + useState(); + const [formError, setFormError] = useState({ + queryName: false, + selectedConditions: false, + }); useEffect(() => { let isSubscribed = true; + if (queryName == "" || queryName == undefined) { + focusRef?.current?.focus(); + } + + // enables/disables the Create Query button based on selectedConditions + if (!selectedConditions || Object.values(selectedConditions).length < 1) { + setFormError({ ...formError, ...{ selectedConditions: true } }); + } else { + setFormError({ ...formError, ...{ selectedConditions: false } }); + } + + // clear the error when the user enters a query name + if (formError.queryName && !!queryName) { + validateForm(); + } + async function fetchConditionsAndUpdateState() { const { categoryToConditionArrayMap } = await getConditionsData(); @@ -44,14 +73,36 @@ export default function QueryTemplateSelection() { return () => { isSubscribed = false; }; - }, []); + }, [selectedConditions, queryName]); - const noTemplateSelected = - fetchedConditions && - Object.values(Object.values(fetchedConditions)) - .map((arr) => Object.values(arr).flatMap((e) => e.include)) - .flatMap((e) => e.some(Boolean)) - .some(Boolean); + function handleCreateQueryClick(event: React.MouseEvent) { + event.preventDefault(); + + validateForm(); + if (!!queryName && !formError.queryName && !formError.selectedConditions) { + submitForm(); + } + } + + const validateForm = () => { + if (!queryName || queryName == "") { + focusRef?.current?.focus(); + } + + return setFormError({ + ...formError, + ...{ queryName: !queryName, selectedConditions: !atLeastOneItemSelected }, + }); + }; + + const submitForm = () => { + // TODO: do something with selectedConditions on next step/page + // will be addressed in https://linear.app/skylight-cdc/issue/QUE-65/create-the-valueset-selection-page + console.log(selectedConditions); + }; + + const atLeastOneItemSelected = + selectedConditions && Object.values(selectedConditions).length > 0; return ( <> @@ -65,18 +116,31 @@ export default function QueryTemplateSelection() { />

Custom query

{ setQueryName(event.target.value); }} /> - +
Create query @@ -108,9 +178,13 @@ export default function QueryTemplateSelection() { {fetchedConditions && ( )}
From bcb1f3e09c994cdd13bac7df76afabc82796fba4 Mon Sep 17 00:00:00 2001 From: Nick Clyde Date: Thu, 21 Nov 2024 15:08:17 -0800 Subject: [PATCH 5/9] Add Keycloak OAuth login (#159) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Marcelle <53578688+m-goggins@users.noreply.github.com> --- query-connector/.env.sample | 7 + query-connector/README.md | 23 +- query-connector/docker-compose-dev.yaml | 12 + query-connector/keycloak/master-realm.json | 2005 +++++++++++++++++ query-connector/package-lock.json | 119 + query-connector/package.json | 1 + .../src/app/api/auth/[...nextauth]/route.ts | 2 + query-connector/src/app/layout.tsx | 17 +- query-connector/src/app/middleware.js | 2 + .../app/query/components/header/header.tsx | 12 +- query-connector/src/auth.ts | 6 + 11 files changed, 2194 insertions(+), 12 deletions(-) create mode 100644 query-connector/.env.sample create mode 100644 query-connector/keycloak/master-realm.json create mode 100644 query-connector/src/app/api/auth/[...nextauth]/route.ts create mode 100644 query-connector/src/auth.ts diff --git a/query-connector/.env.sample b/query-connector/.env.sample new file mode 100644 index 000000000..4009e51b1 --- /dev/null +++ b/query-connector/.env.sample @@ -0,0 +1,7 @@ +DATABASE_URL=postgresql://postgres@localhost:5432/tefca_db +AUTH_SECRET="ido5D/uybeAB3AmMQwn+ubw2zYC4t2h7RJlW2R79598=" +AUTH_KEYCLOAK_ID=query-connector +AUTH_KEYCLOAK_SECRET=ZG3f7R1J3qIwBaw8QtttJnJMinpERQKs +AUTH_KEYCLOAK_ISSUER=http://localhost:8080/realms/master +ERSD_API_KEY= +UMLS_API_KEY= diff --git a/query-connector/README.md b/query-connector/README.md index d6ecac366..89428b708 100644 --- a/query-connector/README.md +++ b/query-connector/README.md @@ -12,7 +12,28 @@ The Query Connector app can be run using Docker (or any other OCI container runt Before running the Query Connector locally, you will need to obtain an API key for the electronic Reporting and Surveillance Distribution (eRSD). With the API key, you have access to 200+ pre-built queries for reportable conditions, e.g., chlamydia, influenza, hepatitis A, etc. These queries can be used and modified in the Query Connector app. -To obtain a free API key, please visit https://ersd.aimsplatform.org/#/api-keys and follow the sign up instructions. Add your API key as an environment variable called `ERSD_API_KEY` in an `.env` file that can be accessed when running the Query Connector app. +To obtain a free API key, please visit and follow the sign up instructions. + +Next, set up your `.env` file with the following command: `cp .env.sample .env` + +Adjust your `DATABASE_URL` as needed. + +Add your API keys as an environment variables called `ERSD_API_KEY` and `UMLS_API_KEY` in the `.env` file so that they can be accessed when running the Query Connector app. + +#### Running Keycloak for Authentication + +``` +docker compose up -f docker-compose-dev.yaml up keycloak +``` + +To login via Keycloak, make sure your `.env` is updated using `cp` command above and use the following credentials to login at `localhost:8080` after spinning up the container: + +``` +Username: qc-admin +Password: QcDev2024! +``` + +Next, run the app with `npm run dev` or `npm run dev-win`. You should see a sign in button at . Click it and login with the above credentials, and it should redirect back to ! #### Running with Docker (Recommended) diff --git a/query-connector/docker-compose-dev.yaml b/query-connector/docker-compose-dev.yaml index 4a0d4df4f..d6287142c 100644 --- a/query-connector/docker-compose-dev.yaml +++ b/query-connector/docker-compose-dev.yaml @@ -45,3 +45,15 @@ services: command: ["sh", "post_e2e_data_hapi.sh"] depends_on: - hapi-fhir-server + + # Keycloak for authentication + keycloak: + image: quay.io/keycloak/keycloak:26.0.2 + ports: + - 8080:8080 + volumes: + - ./keycloak:/opt/keycloak/data/import + restart: always + command: + - start-dev + - --import-realm diff --git a/query-connector/keycloak/master-realm.json b/query-connector/keycloak/master-realm.json new file mode 100644 index 000000000..ca43a59df --- /dev/null +++ b/query-connector/keycloak/master-realm.json @@ -0,0 +1,2005 @@ +{ + "id" : "c05ec7e6-dc6c-45da-bc02-2b20bd3e1047", + "realm" : "master", + "displayName" : "Keycloak", + "displayNameHtml" : "
Keycloak
", + "notBefore" : 0, + "defaultSignatureAlgorithm" : "RS256", + "revokeRefreshToken" : false, + "refreshTokenMaxReuse" : 0, + "accessTokenLifespan" : 60, + "accessTokenLifespanForImplicitFlow" : 900, + "ssoSessionIdleTimeout" : 1800, + "ssoSessionMaxLifespan" : 36000, + "ssoSessionIdleTimeoutRememberMe" : 0, + "ssoSessionMaxLifespanRememberMe" : 0, + "offlineSessionIdleTimeout" : 2592000, + "offlineSessionMaxLifespanEnabled" : false, + "offlineSessionMaxLifespan" : 5184000, + "clientSessionIdleTimeout" : 0, + "clientSessionMaxLifespan" : 0, + "clientOfflineSessionIdleTimeout" : 0, + "clientOfflineSessionMaxLifespan" : 0, + "accessCodeLifespan" : 60, + "accessCodeLifespanUserAction" : 300, + "accessCodeLifespanLogin" : 1800, + "actionTokenGeneratedByAdminLifespan" : 43200, + "actionTokenGeneratedByUserLifespan" : 300, + "oauth2DeviceCodeLifespan" : 600, + "oauth2DevicePollingInterval" : 5, + "enabled" : true, + "sslRequired" : "external", + "registrationAllowed" : false, + "registrationEmailAsUsername" : false, + "rememberMe" : false, + "verifyEmail" : false, + "loginWithEmailAllowed" : true, + "duplicateEmailsAllowed" : false, + "resetPasswordAllowed" : false, + "editUsernameAllowed" : false, + "bruteForceProtected" : false, + "permanentLockout" : false, + "maxTemporaryLockouts" : 0, + "maxFailureWaitSeconds" : 900, + "minimumQuickLoginWaitSeconds" : 60, + "waitIncrementSeconds" : 60, + "quickLoginCheckMilliSeconds" : 1000, + "maxDeltaTimeSeconds" : 43200, + "failureFactor" : 30, + "roles" : { + "realm" : [ { + "id" : "f58b8fb0-102c-466c-8dfd-ddf90314e285", + "name" : "offline_access", + "description" : "${role_offline-access}", + "composite" : false, + "clientRole" : false, + "containerId" : "c05ec7e6-dc6c-45da-bc02-2b20bd3e1047", + "attributes" : { } + }, { + "id" : "06ce55a5-14ac-4e19-9a36-c3f0b66b73a6", + "name" : "admin", + "description" : "${role_admin}", + "composite" : true, + "composites" : { + "realm" : [ "create-realm" ], + "client" : { + "master-realm" : [ "manage-identity-providers", "manage-clients", "manage-users", "query-users", "view-authorization", "query-clients", "query-realms", "impersonation", "manage-events", "create-client", "view-realm", "query-groups", "view-clients", "manage-authorization", "view-identity-providers", "view-events", "manage-realm", "view-users" ] + } + }, + "clientRole" : false, + "containerId" : "c05ec7e6-dc6c-45da-bc02-2b20bd3e1047", + "attributes" : { } + }, { + "id" : "2690d8c9-8a5e-4c80-abc5-6e561166f48e", + "name" : "create-realm", + "description" : "${role_create-realm}", + "composite" : false, + "clientRole" : false, + "containerId" : "c05ec7e6-dc6c-45da-bc02-2b20bd3e1047", + "attributes" : { } + }, { + "id" : "3a9513eb-880e-432f-b238-950f52df2762", + "name" : "default-roles-master", + "description" : "${role_default-roles}", + "composite" : true, + "composites" : { + "realm" : [ "offline_access", "uma_authorization" ], + "client" : { + "account" : [ "view-profile", "manage-account" ] + } + }, + "clientRole" : false, + "containerId" : "c05ec7e6-dc6c-45da-bc02-2b20bd3e1047", + "attributes" : { } + }, { + "id" : "11cb6e0a-9da0-4ac4-8d45-89c3a63990c5", + "name" : "uma_authorization", + "description" : "${role_uma_authorization}", + "composite" : false, + "clientRole" : false, + "containerId" : "c05ec7e6-dc6c-45da-bc02-2b20bd3e1047", + "attributes" : { } + } ], + "client" : { + "security-admin-console" : [ ], + "query-connector" : [ ], + "admin-cli" : [ ], + "account-console" : [ ], + "broker" : [ { + "id" : "f71df5da-e540-43e8-a1d1-627edb612f96", + "name" : "read-token", + "description" : "${role_read-token}", + "composite" : false, + "clientRole" : true, + "containerId" : "7763f79f-5a69-4b34-97fb-8796eacab988", + "attributes" : { } + } ], + "master-realm" : [ { + "id" : "4b5598d5-52bc-4dab-b575-3e2805c09965", + "name" : "manage-identity-providers", + "description" : "${role_manage-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "attributes" : { } + }, { + "id" : "5223c4f1-6d17-4dd9-96d2-bf5ca6bc332b", + "name" : "manage-clients", + "description" : "${role_manage-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "attributes" : { } + }, { + "id" : "a41fea43-5e0f-48ac-8f35-65f28da40e04", + "name" : "manage-users", + "description" : "${role_manage-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "attributes" : { } + }, { + "id" : "562803cf-8985-4023-9081-5228464cea3c", + "name" : "query-clients", + "description" : "${role_query-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "attributes" : { } + }, { + "id" : "64021a42-6271-46e5-848a-8e20eaef8c06", + "name" : "query-realms", + "description" : "${role_query-realms}", + "composite" : false, + "clientRole" : true, + "containerId" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "attributes" : { } + }, { + "id" : "161a26a7-2345-4e6e-bf7a-cf03f33593d4", + "name" : "query-users", + "description" : "${role_query-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "attributes" : { } + }, { + "id" : "45b7051b-b81a-41ab-93c5-eec977cbe898", + "name" : "view-authorization", + "description" : "${role_view-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "attributes" : { } + }, { + "id" : "5f4bdda4-ab50-4b9e-8b9a-7c7da87939d7", + "name" : "impersonation", + "description" : "${role_impersonation}", + "composite" : false, + "clientRole" : true, + "containerId" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "attributes" : { } + }, { + "id" : "2907b59d-7548-45ee-bcdb-91a4848d027f", + "name" : "manage-events", + "description" : "${role_manage-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "attributes" : { } + }, { + "id" : "770127ff-8cac-4dca-a686-9b16fd7e32bf", + "name" : "create-client", + "description" : "${role_create-client}", + "composite" : false, + "clientRole" : true, + "containerId" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "attributes" : { } + }, { + "id" : "f51bbc22-02d9-4bfe-94c8-9e287409df4f", + "name" : "view-realm", + "description" : "${role_view-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "attributes" : { } + }, { + "id" : "1811c279-3fad-4f47-9a76-a21842dde33f", + "name" : "query-groups", + "description" : "${role_query-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "attributes" : { } + }, { + "id" : "eecf09ab-7944-4ecd-8a73-b02c8c63798c", + "name" : "view-clients", + "description" : "${role_view-clients}", + "composite" : true, + "composites" : { + "client" : { + "master-realm" : [ "query-clients" ] + } + }, + "clientRole" : true, + "containerId" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "attributes" : { } + }, { + "id" : "29ee9107-c1c2-4ae3-8cc1-74d7a3eb1157", + "name" : "manage-authorization", + "description" : "${role_manage-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "attributes" : { } + }, { + "id" : "28453021-0fa4-499d-8d2f-f2e909582a3f", + "name" : "view-identity-providers", + "description" : "${role_view-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "attributes" : { } + }, { + "id" : "73055d88-3b66-42f8-91c4-2e59a7e73101", + "name" : "manage-realm", + "description" : "${role_manage-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "attributes" : { } + }, { + "id" : "04b3bda9-7af1-4b87-a1a7-dbe3af49484e", + "name" : "view-events", + "description" : "${role_view-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "attributes" : { } + }, { + "id" : "a726e5d0-cd38-459f-9b64-e816053d2773", + "name" : "view-users", + "description" : "${role_view-users}", + "composite" : true, + "composites" : { + "client" : { + "master-realm" : [ "query-groups", "query-users" ] + } + }, + "clientRole" : true, + "containerId" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "attributes" : { } + } ], + "account" : [ { + "id" : "d21c97a7-3d13-4c6d-9d59-7f76b12409a1", + "name" : "manage-consent", + "description" : "${role_manage-consent}", + "composite" : true, + "composites" : { + "client" : { + "account" : [ "view-consent" ] + } + }, + "clientRole" : true, + "containerId" : "81fd58cd-0309-4691-9c2e-150c2112de36", + "attributes" : { } + }, { + "id" : "08b288f3-03b6-4c1a-ab55-1549e5a9d070", + "name" : "delete-account", + "description" : "${role_delete-account}", + "composite" : false, + "clientRole" : true, + "containerId" : "81fd58cd-0309-4691-9c2e-150c2112de36", + "attributes" : { } + }, { + "id" : "74437bc8-b912-4a9e-8397-ba6f172c645c", + "name" : "view-profile", + "description" : "${role_view-profile}", + "composite" : false, + "clientRole" : true, + "containerId" : "81fd58cd-0309-4691-9c2e-150c2112de36", + "attributes" : { } + }, { + "id" : "f0a6772d-f386-48fe-9f2e-a1a679f32f0f", + "name" : "view-consent", + "description" : "${role_view-consent}", + "composite" : false, + "clientRole" : true, + "containerId" : "81fd58cd-0309-4691-9c2e-150c2112de36", + "attributes" : { } + }, { + "id" : "e6d8cbd3-86a9-49f6-99ee-846478a395ae", + "name" : "manage-account-links", + "description" : "${role_manage-account-links}", + "composite" : false, + "clientRole" : true, + "containerId" : "81fd58cd-0309-4691-9c2e-150c2112de36", + "attributes" : { } + }, { + "id" : "b6e67042-4989-4cde-9251-06ca5a953dbc", + "name" : "manage-account", + "description" : "${role_manage-account}", + "composite" : true, + "composites" : { + "client" : { + "account" : [ "manage-account-links" ] + } + }, + "clientRole" : true, + "containerId" : "81fd58cd-0309-4691-9c2e-150c2112de36", + "attributes" : { } + }, { + "id" : "6ac2300b-f117-4c56-8eb5-3700bce31148", + "name" : "view-groups", + "description" : "${role_view-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "81fd58cd-0309-4691-9c2e-150c2112de36", + "attributes" : { } + }, { + "id" : "cd09e665-a90d-4a74-8baf-1faf90ea86d3", + "name" : "view-applications", + "description" : "${role_view-applications}", + "composite" : false, + "clientRole" : true, + "containerId" : "81fd58cd-0309-4691-9c2e-150c2112de36", + "attributes" : { } + } ] + } + }, + "groups" : [ ], + "defaultRole" : { + "id" : "3a9513eb-880e-432f-b238-950f52df2762", + "name" : "default-roles-master", + "description" : "${role_default-roles}", + "composite" : true, + "clientRole" : false, + "containerId" : "c05ec7e6-dc6c-45da-bc02-2b20bd3e1047" + }, + "requiredCredentials" : [ "password" ], + "otpPolicyType" : "totp", + "otpPolicyAlgorithm" : "HmacSHA1", + "otpPolicyInitialCounter" : 0, + "otpPolicyDigits" : 6, + "otpPolicyLookAheadWindow" : 1, + "otpPolicyPeriod" : 30, + "otpPolicyCodeReusable" : false, + "otpSupportedApplications" : [ "totpAppFreeOTPName", "totpAppGoogleName", "totpAppMicrosoftAuthenticatorName" ], + "localizationTexts" : { }, + "webAuthnPolicyRpEntityName" : "keycloak", + "webAuthnPolicySignatureAlgorithms" : [ "ES256", "RS256" ], + "webAuthnPolicyRpId" : "", + "webAuthnPolicyAttestationConveyancePreference" : "not specified", + "webAuthnPolicyAuthenticatorAttachment" : "not specified", + "webAuthnPolicyRequireResidentKey" : "not specified", + "webAuthnPolicyUserVerificationRequirement" : "not specified", + "webAuthnPolicyCreateTimeout" : 0, + "webAuthnPolicyAvoidSameAuthenticatorRegister" : false, + "webAuthnPolicyAcceptableAaguids" : [ ], + "webAuthnPolicyExtraOrigins" : [ ], + "webAuthnPolicyPasswordlessRpEntityName" : "keycloak", + "webAuthnPolicyPasswordlessSignatureAlgorithms" : [ "ES256", "RS256" ], + "webAuthnPolicyPasswordlessRpId" : "", + "webAuthnPolicyPasswordlessAttestationConveyancePreference" : "not specified", + "webAuthnPolicyPasswordlessAuthenticatorAttachment" : "not specified", + "webAuthnPolicyPasswordlessRequireResidentKey" : "not specified", + "webAuthnPolicyPasswordlessUserVerificationRequirement" : "not specified", + "webAuthnPolicyPasswordlessCreateTimeout" : 0, + "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister" : false, + "webAuthnPolicyPasswordlessAcceptableAaguids" : [ ], + "webAuthnPolicyPasswordlessExtraOrigins" : [ ], + "users" : [ { + "id" : "1c3b6114-3c12-4ef7-95ba-a0091f506ed6", + "username" : "qc-admin", + "firstName" : "QC", + "lastName" : "Admin", + "emailVerified" : true, + "createdTimestamp" : 1732143781841, + "enabled" : true, + "totp" : false, + "credentials" : [ { + "id" : "c28534a5-f006-4c8d-9b2a-d1aa9b257abf", + "type" : "password", + "userLabel" : "My password", + "createdDate" : 1732143832208, + "secretData" : "{\"value\":\"nKm/mAhnoweR4G3KwvAKFCXphWk/WjHxUUnSPnPa60o=\",\"salt\":\"kH4es8IIgcLN5AGABkEd9g==\",\"additionalParameters\":{}}", + "credentialData" : "{\"hashIterations\":5,\"algorithm\":\"argon2\",\"additionalParameters\":{\"hashLength\":[\"32\"],\"memory\":[\"7168\"],\"type\":[\"id\"],\"version\":[\"1.3\"],\"parallelism\":[\"1\"]}}" + } ], + "disableableCredentialTypes" : [ ], + "requiredActions" : [ ], + "realmRoles" : [ "admin", "default-roles-master" ], + "notBefore" : 0, + "groups" : [ ] + }, { + "id" : "01428450-f98d-43a8-8432-8a9f4abdc12f", + "username" : "service-account-query-connector", + "emailVerified" : false, + "createdTimestamp" : 1730763661133, + "enabled" : true, + "totp" : false, + "serviceAccountClientId" : "query-connector", + "credentials" : [ ], + "disableableCredentialTypes" : [ ], + "requiredActions" : [ ], + "realmRoles" : [ "default-roles-master" ], + "notBefore" : 0, + "groups" : [ ] + } ], + "scopeMappings" : [ { + "clientScope" : "offline_access", + "roles" : [ "offline_access" ] + } ], + "clientScopeMappings" : { + "account" : [ { + "client" : "account-console", + "roles" : [ "manage-account", "view-groups" ] + } ] + }, + "clients" : [ { + "id" : "81fd58cd-0309-4691-9c2e-150c2112de36", + "clientId" : "account", + "name" : "${client_account}", + "rootUrl" : "${authBaseUrl}", + "baseUrl" : "/realms/master/account/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "/realms/master/account/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "realm_client" : "false", + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ], + "optionalClientScopes" : [ "address", "phone", "organization", "offline_access", "microprofile-jwt" ] + }, { + "id" : "e3376c73-ebde-4f70-9e53-57a858fef0a4", + "clientId" : "account-console", + "name" : "${client_account-console}", + "rootUrl" : "${authBaseUrl}", + "baseUrl" : "/realms/master/account/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "/realms/master/account/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "realm_client" : "false", + "post.logout.redirect.uris" : "+", + "pkce.code.challenge.method" : "S256" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "d8f5aa53-ff9b-40f7-9c14-c7e2c8f76da1", + "name" : "audience resolve", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-resolve-mapper", + "consentRequired" : false, + "config" : { } + } ], + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ], + "optionalClientScopes" : [ "address", "phone", "organization", "offline_access", "microprofile-jwt" ] + }, { + "id" : "162237d0-389f-4d55-8a3d-c1da48fcab44", + "clientId" : "admin-cli", + "name" : "${client_admin-cli}", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : false, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : true, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "realm_client" : "false", + "client.use.lightweight.access.token.enabled" : "true" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ], + "optionalClientScopes" : [ "address", "phone", "organization", "offline_access", "microprofile-jwt" ] + }, { + "id" : "7763f79f-5a69-4b34-97fb-8796eacab988", + "clientId" : "broker", + "name" : "${client_broker}", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : true, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "realm_client" : "true" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ], + "optionalClientScopes" : [ "address", "phone", "organization", "offline_access", "microprofile-jwt" ] + }, { + "id" : "32e1cfa3-b448-422c-b270-c169d28cee53", + "clientId" : "master-realm", + "name" : "master Realm", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : true, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "attributes" : { + "realm_client" : "true" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ], + "optionalClientScopes" : [ "address", "phone", "organization", "offline_access", "microprofile-jwt" ] + }, { + "id" : "d2e8ce4e-a19e-44c6-97b4-3fefa586d5e1", + "clientId" : "query-connector", + "name" : "Query Connector", + "description" : "", + "rootUrl" : "http://localhost:3000", + "adminUrl" : "http://localhost:3000", + "baseUrl" : "http://localhost:3000", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : true, + "clientAuthenticatorType" : "client-secret", + "secret" : "ZG3f7R1J3qIwBaw8QtttJnJMinpERQKs", + "redirectUris" : [ "http://localhost:3000/api/auth/callback/keycloak" ], + "webOrigins" : [ "http://localhost:3000" ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : true, + "serviceAccountsEnabled" : true, + "publicClient" : false, + "frontchannelLogout" : true, + "protocol" : "openid-connect", + "attributes" : { + "realm_client" : "false", + "oidc.ciba.grant.enabled" : "false", + "client.secret.creation.time" : "1730763661", + "backchannel.logout.session.required" : "true", + "oauth2.device.authorization.grant.enabled" : "false", + "display.on.consent.screen" : "false", + "backchannel.logout.revoke.offline.tokens" : "false" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : -1, + "protocolMappers" : [ { + "id" : "6615be63-278a-48f6-85a3-1b733a8867ae", + "name" : "Client Host", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "clientHost", + "id.token.claim" : "true", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "clientHost", + "jsonType.label" : "String" + } + }, { + "id" : "af640dcc-11b4-4da7-9cb9-306230fe0ff1", + "name" : "Client ID", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "client_id", + "id.token.claim" : "true", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "client_id", + "jsonType.label" : "String" + } + }, { + "id" : "8a2cd1e4-a8fd-47b7-9f72-9dceba461378", + "name" : "Client IP Address", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "clientAddress", + "id.token.claim" : "true", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "clientAddress", + "jsonType.label" : "String" + } + } ], + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ], + "optionalClientScopes" : [ "address", "phone", "organization", "offline_access", "microprofile-jwt" ] + }, { + "id" : "d6da601c-7de6-4091-a67b-d21989ec41ec", + "clientId" : "security-admin-console", + "name" : "${client_security-admin-console}", + "rootUrl" : "${authAdminUrl}", + "baseUrl" : "/admin/master/console/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "/admin/master/console/*" ], + "webOrigins" : [ "+" ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "realm_client" : "false", + "client.use.lightweight.access.token.enabled" : "true", + "post.logout.redirect.uris" : "+", + "pkce.code.challenge.method" : "S256" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "06098eef-6f09-4a1d-bba4-62e01736a7bc", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + } ], + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "basic", "email" ], + "optionalClientScopes" : [ "address", "phone", "organization", "offline_access", "microprofile-jwt" ] + } ], + "clientScopes" : [ { + "id" : "ac560a5d-0cc9-4850-a430-cff9dd068bda", + "name" : "address", + "description" : "OpenID Connect built-in scope: address", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "consent.screen.text" : "${addressScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "d45c19a4-1714-4062-b57f-c3f707e9d2f8", + "name" : "address", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-address-mapper", + "consentRequired" : false, + "config" : { + "user.attribute.formatted" : "formatted", + "user.attribute.country" : "country", + "introspection.token.claim" : "true", + "user.attribute.postal_code" : "postal_code", + "userinfo.token.claim" : "true", + "user.attribute.street" : "street", + "id.token.claim" : "true", + "user.attribute.region" : "region", + "access.token.claim" : "true", + "user.attribute.locality" : "locality" + } + } ] + }, { + "id" : "8565cc2c-3857-4a95-bae7-f348cd8ccbc6", + "name" : "phone", + "description" : "OpenID Connect built-in scope: phone", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "consent.screen.text" : "${phoneScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "3a290afe-86fc-441a-93f4-60dc5e2dabd3", + "name" : "phone number verified", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "phoneNumberVerified", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "phone_number_verified", + "jsonType.label" : "boolean" + } + }, { + "id" : "ea2b870d-9e5e-4251-bec6-92478ee0d8ce", + "name" : "phone number", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "phoneNumber", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "phone_number", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "d27844e6-b730-43e4-a163-29bea0453cef", + "name" : "basic", + "description" : "OpenID Connect scope for add all basic claims to the token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "display.on.consent.screen" : "false" + }, + "protocolMappers" : [ { + "id" : "786ff462-148d-446a-985e-181508a16796", + "name" : "sub", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-sub-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "701d4ef9-35bb-4a56-8808-3d507ef91cec", + "name" : "auth_time", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "AUTH_TIME", + "id.token.claim" : "true", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "auth_time", + "jsonType.label" : "long" + } + } ] + }, { + "id" : "e8a6d225-e9d5-42fd-b27e-500bff96fe8d", + "name" : "web-origins", + "description" : "OpenID Connect scope for add allowed web origins to the access token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "consent.screen.text" : "", + "display.on.consent.screen" : "false" + }, + "protocolMappers" : [ { + "id" : "5d5b5664-ddc8-43d3-a7a5-30067c2433f9", + "name" : "allowed web origins", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-allowed-origins-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "access.token.claim" : "true" + } + } ] + }, { + "id" : "7c9b65d9-b713-40b9-b639-54f87662dce0", + "name" : "role_list", + "description" : "SAML role list", + "protocol" : "saml", + "attributes" : { + "consent.screen.text" : "${samlRoleListScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "ec37a554-02f8-46bd-92e4-c4c05e711ba5", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + } ] + }, { + "id" : "3351f7dc-dce5-414c-84be-119dc16d410b", + "name" : "saml_organization", + "description" : "Organization Membership", + "protocol" : "saml", + "attributes" : { + "display.on.consent.screen" : "false" + }, + "protocolMappers" : [ { + "id" : "92d82caa-b3bb-4266-8086-12c4a62bc6b8", + "name" : "organization", + "protocol" : "saml", + "protocolMapper" : "saml-organization-membership-mapper", + "consentRequired" : false, + "config" : { } + } ] + }, { + "id" : "1efc85c5-d419-45c3-b3b7-680b4f1edd0e", + "name" : "acr", + "description" : "OpenID Connect scope for add acr (authentication context class reference) to the token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "display.on.consent.screen" : "false" + }, + "protocolMappers" : [ { + "id" : "6db984af-b37f-4c13-ac3d-558c29f0f5a2", + "name" : "acr loa level", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-acr-mapper", + "consentRequired" : false, + "config" : { + "id.token.claim" : "true", + "introspection.token.claim" : "true", + "access.token.claim" : "true" + } + } ] + }, { + "id" : "03c40c20-a7d9-4582-bc11-0658e82aca03", + "name" : "profile", + "description" : "OpenID Connect built-in scope: profile", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "consent.screen.text" : "${profileScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "26c0021a-6908-4950-add6-86bc6fe0bf77", + "name" : "zoneinfo", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "zoneinfo", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "zoneinfo", + "jsonType.label" : "String" + } + }, { + "id" : "dc00f7a1-8b9b-4112-81f1-1edc9d9b3fbf", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "33317d2d-6e44-405a-b084-25f6d753f24e", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : false, + "config" : { + "id.token.claim" : "true", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "userinfo.token.claim" : "true" + } + }, { + "id" : "7e01d5c9-a321-4368-87e2-18b7ee8c8e70", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + }, { + "id" : "c73a8688-96a2-401b-83bd-9458868f0025", + "name" : "website", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "website", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "website", + "jsonType.label" : "String" + } + }, { + "id" : "0785bc9b-d9c3-4534-9db9-f64b17026382", + "name" : "profile", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "profile", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "profile", + "jsonType.label" : "String" + } + }, { + "id" : "dd361577-cb1f-4478-a3cd-7fc78c17224e", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "7de15910-7e08-4a79-9a1a-222266c2429a", + "name" : "middle name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "middleName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "middle_name", + "jsonType.label" : "String" + } + }, { + "id" : "99647def-ca5a-49b8-8636-7fac74ad1024", + "name" : "updated at", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "updatedAt", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "updated_at", + "jsonType.label" : "long" + } + }, { + "id" : "b712e9bb-f49a-4a4a-a2eb-668e2054b93a", + "name" : "nickname", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "nickname", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "nickname", + "jsonType.label" : "String" + } + }, { + "id" : "694e09c9-9a88-49c5-8daa-1a35543e33d2", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "6c1e645d-59dc-4942-ad59-36dee9b1cc1c", + "name" : "birthdate", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "birthdate", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "birthdate", + "jsonType.label" : "String" + } + }, { + "id" : "c819bcf9-8150-4745-a8e5-0534cb6f944b", + "name" : "gender", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "gender", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "gender", + "jsonType.label" : "String" + } + }, { + "id" : "a8394182-4ece-4765-a194-1a5740350076", + "name" : "picture", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "picture", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "picture", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "13129c95-e3c8-42aa-81ff-aabf54cfe482", + "name" : "email", + "description" : "OpenID Connect built-in scope: email", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "consent.screen.text" : "${emailScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "5185b633-d194-4d23-a39a-c779706b9908", + "name" : "email verified", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "emailVerified", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email_verified", + "jsonType.label" : "boolean" + } + }, { + "id" : "96bd1a25-c00f-4655-ad52-2deaef8350b4", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "924dbfa3-49c0-44fd-a5cf-d474174c1f90", + "name" : "organization", + "description" : "Additional claims about the organization a subject belongs to", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "consent.screen.text" : "${organizationScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "d8794734-81ad-4c34-8184-d61aa28fe8fd", + "name" : "organization", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-organization-membership-mapper", + "consentRequired" : false, + "config" : { + "id.token.claim" : "true", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "organization", + "jsonType.label" : "String", + "multivalued" : "true" + } + } ] + }, { + "id" : "8732ea27-8fa4-4620-998d-0425bd85843b", + "name" : "microprofile-jwt", + "description" : "Microprofile - JWT built-in scope", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "false" + }, + "protocolMappers" : [ { + "id" : "344c365e-d23d-4a5b-bfa5-380b65dc49b8", + "name" : "upn", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "upn", + "jsonType.label" : "String" + } + }, { + "id" : "43cc6016-4e98-4810-8d21-91dd7d013ccd", + "name" : "groups", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-realm-role-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "multivalued" : "true", + "user.attribute" : "foo", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "groups", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "652c0abb-f9fb-42cd-a22f-4a9f3a1cd867", + "name" : "roles", + "description" : "OpenID Connect scope for add user roles to the access token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "consent.screen.text" : "${rolesScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "54941a29-dc12-4690-b353-1e7f661f9a0e", + "name" : "audience resolve", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-resolve-mapper", + "consentRequired" : false, + "config" : { + "introspection.token.claim" : "true", + "access.token.claim" : "true" + } + }, { + "id" : "07c73dcf-ea8a-4994-a03c-194ac3a6806d", + "name" : "realm roles", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-realm-role-mapper", + "consentRequired" : false, + "config" : { + "user.attribute" : "foo", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "realm_access.roles", + "jsonType.label" : "String", + "multivalued" : "true" + } + }, { + "id" : "72944b9a-87ca-4318-a08f-4bca7b1290ec", + "name" : "client roles", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-client-role-mapper", + "consentRequired" : false, + "config" : { + "user.attribute" : "foo", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "resource_access.${client_id}.roles", + "jsonType.label" : "String", + "multivalued" : "true" + } + } ] + }, { + "id" : "73087c1f-1db6-4c0f-85e5-bde145b62a9d", + "name" : "offline_access", + "description" : "OpenID Connect built-in scope: offline_access", + "protocol" : "openid-connect", + "attributes" : { + "consent.screen.text" : "${offlineAccessScopeConsentText}", + "display.on.consent.screen" : "true" + } + } ], + "defaultDefaultClientScopes" : [ "role_list", "saml_organization", "profile", "email", "roles", "web-origins", "acr", "basic" ], + "defaultOptionalClientScopes" : [ "offline_access", "address", "phone", "microprofile-jwt", "organization" ], + "browserSecurityHeaders" : { + "contentSecurityPolicyReportOnly" : "", + "xContentTypeOptions" : "nosniff", + "referrerPolicy" : "no-referrer", + "xRobotsTag" : "none", + "xFrameOptions" : "SAMEORIGIN", + "xXSSProtection" : "1; mode=block", + "contentSecurityPolicy" : "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", + "strictTransportSecurity" : "max-age=31536000; includeSubDomains" + }, + "smtpServer" : { }, + "eventsEnabled" : false, + "eventsListeners" : [ "jboss-logging" ], + "enabledEventTypes" : [ ], + "adminEventsEnabled" : false, + "adminEventsDetailsEnabled" : false, + "identityProviders" : [ ], + "identityProviderMappers" : [ ], + "components" : { + "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ { + "id" : "53e6c9b5-456d-42bf-bc9f-5b13ac920a79", + "name" : "Full Scope Disabled", + "providerId" : "scope", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "23a2b6b5-89e7-4b28-92ac-5e774a8193cd", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "oidc-full-name-mapper", "oidc-usermodel-property-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-property-mapper", "saml-role-list-mapper", "oidc-usermodel-attribute-mapper", "saml-user-attribute-mapper", "oidc-address-mapper" ] + } + }, { + "id" : "bfb33137-be0e-408f-8201-56d8de5044c1", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "oidc-address-mapper", "saml-role-list-mapper", "saml-user-attribute-mapper", "oidc-full-name-mapper", "saml-user-property-mapper", "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper", "oidc-sha256-pairwise-sub-mapper" ] + } + }, { + "id" : "d73f7100-a923-4c1a-8a63-227998c18990", + "name" : "Trusted Hosts", + "providerId" : "trusted-hosts", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "host-sending-registration-request-must-match" : [ "true" ], + "client-uris-must-match" : [ "true" ] + } + }, { + "id" : "ad16d2c6-6ed1-425c-9119-152475c37ddd", + "name" : "Allowed Client Scopes", + "providerId" : "allowed-client-templates", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allow-default-scopes" : [ "true" ] + } + }, { + "id" : "a72cbd05-c9ea-462e-bc43-c5722615ce4c", + "name" : "Consent Required", + "providerId" : "consent-required", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "231c54c6-a953-4268-9047-3f3e0287cd54", + "name" : "Allowed Client Scopes", + "providerId" : "allowed-client-templates", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allow-default-scopes" : [ "true" ] + } + }, { + "id" : "900dfb8b-62b8-4c0d-bdcf-5cbb1ec123f7", + "name" : "Max Clients Limit", + "providerId" : "max-clients", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "max-clients" : [ "200" ] + } + } ], + "org.keycloak.userprofile.UserProfileProvider" : [ { + "id" : "a897285d-5b76-47ad-974c-1af3e9295280", + "providerId" : "declarative-user-profile", + "subComponents" : { }, + "config" : { + "kc.user.profile.config" : [ "{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"validations\":{\"length\":{\"min\":3,\"max\":255},\"username-prohibited-characters\":{},\"up-username-not-idn-homograph\":{}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"email\",\"displayName\":\"${email}\",\"validations\":{\"email\":{},\"length\":{\"max\":255}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false}],\"groups\":[{\"name\":\"user-metadata\",\"displayHeader\":\"User metadata\",\"displayDescription\":\"Attributes, which refer to user metadata\"}]}" ] + } + } ], + "org.keycloak.keys.KeyProvider" : [ { + "id" : "6ba12340-e111-457b-b65c-49c5a9fc591f", + "name" : "hmac-generated-hs512", + "providerId" : "hmac-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "a392e492-66be-4648-9d98-1078a824cc62" ], + "secret" : [ "hOHQHy6pt4koiU54WNXgsS478s2PUZxk4qCniTNeAoSd-wQUjal0Xme_MGd5bUGn5QdppE0Kqtqt4Z1EZ_epUkEQistvVihCJILSfS9oRlwhPXxdQ2WWR2kje1z2uqb2K_zr3EeUUcTS3BDW50cE9FVFy0U2I9UpOEtdj2c6O1c" ], + "priority" : [ "100" ], + "algorithm" : [ "HS512" ] + } + }, { + "id" : "0dd897b2-d5f4-4bcf-94c0-ab3a32c5756d", + "name" : "rsa-generated", + "providerId" : "rsa-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEpAIBAAKCAQEAv1RimhBcPG+zq9fj7Yf2fomr9rYdf0bxmCgO5cjZeQVkPyTAEH/PT503P3OdtFMK+OBcBmwiwbt+jYn0MmKL5tZANT6WyoqMiSZTCQJ1220zcgSVr6B+Pt2WilEvNSPwc8BncHAGyx0lgyd2ah6cd2gSwAhFdp2UIMtGpSJX6L8EKaWmGzfjjiEH6CoDNdRTCjdF9FiHCYGHmnneQpVGInCjAa74RIv0hj/R2L3GF86hZuO1rJ/735Rzgc+wxbvPTKdtIGdn35lTHcDJHz9HtjahPEzQdvURhfflH+XOa+9gQrOxla62Y2P4m3tb7INRv2eZ4aY6NxZvwG3NFCmFAQIDAQABAoIBABKBVD1tHP6wxG1NJuZvzWTVEU9+CGxUWERMhjmuAMVhGB5jV5BA9wl5k0ENKvuoly8VxCYligG4OLfygoPntCWneJ5YZ2KU8/LFRNK3l4lEOULrM+8V/sqQdAxSEywjRbvBqD+Ka53JkTnridsfCtMhuxkyXkWSss5ZMC6t8QK5trfu2KT5fYYwcWRYfqVWx+Thi4xWgy6vFNwzNxwdVbymFOQMUkoVijox6PKlzmQbxHWkm3ZZSp5ARE+ZZ4ygKQ9RLDJFLN8if5hxcOUl6IuryLL1p/wwDP8DQbAzGDo+gg2RwA3XXwyQ4tL6dOEnuqWbmJWpsP0piwYX+73sAGECgYEA6Kq5gFF8MZ14GvPUFoNBrzK0UOr+salPB0V+hXno3oyRtc0XEIfD5XPLbogTB2Y1TF6Bv7gYWyR/NMoK3nKa4wdug4o04AIrGgspnyVM5JkPNZhG3vTKjXiEMR7otff4yEujO6m2t14MBCtXXTg7d0bbtnPl8+z4tF4L0UeVyq8CgYEA0oRn3sSVyrlG78bPgN7w4WfFER+rRe0w9USbysGZ6dIitvJq2LlXjg9FoKCFp5GiCGbmK5PW9no9UCujJXCmWPWmg/7TQICDD2HQnv6EvDmE8SFX5BRP1ukls274qaF2lOR+hF6w7tCS5AT7gYUjTDNd+VkyRjplxmJedo15108CgYEA4SP7NuEi1Xv0MdiJ/XLrx5XACKEs7kvQTk//+zcZkOjjQtH/pJ5LgKgJTZ7dEwbjQlAdK6D/6IorkbCEzfaGTHPvi9fcDHvsq1nr37UfcAFwR0NgKPUlX7oj6MhpFVSr513RybUTOuMFq68o7eqxGF131FjYRq6jhx2OP+gOWb8CgYEAv7nU+77giXP6VhAkFcN1cGRYx0KncxUVnJsypBN0gM5fzWy0wNL0Ga5xBFyNvVJWVv6YLCIGCg7EXoqPmF6jMavwTpC7hyhDtLOqE9PLwb1FBXMPn+qb2CgYrPWpRJyH6gy76QRwcd/FmCOth4Vg41p5AMoqjmlLHcWjMKeiyuMCgYBNetrakZ7VwN5m6U5gcy7L6YY/invkPbiflLoXLwQVdAHinKyTohBNv4Ys3iIqVZtkN/9TF9FvfXtCWYW1y+eFJfrTIrFneQIXL9vxwGyfdVzKVZN+r71EzfvFaVCQ57PwTcTHQNBO8UIe7zoE7RB4Zvf1177wShSGwgwyzihfQw==" ], + "keyUse" : [ "SIG" ], + "certificate" : [ "MIICmzCCAYMCBgGS+Yr1pDANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjQxMTA0MjMzNjI2WhcNMzQxMTA0MjMzODA2WjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC/VGKaEFw8b7Or1+Pth/Z+iav2th1/RvGYKA7lyNl5BWQ/JMAQf89PnTc/c520Uwr44FwGbCLBu36NifQyYovm1kA1PpbKioyJJlMJAnXbbTNyBJWvoH4+3ZaKUS81I/BzwGdwcAbLHSWDJ3ZqHpx3aBLACEV2nZQgy0alIlfovwQppaYbN+OOIQfoKgM11FMKN0X0WIcJgYeaed5ClUYicKMBrvhEi/SGP9HYvcYXzqFm47Wsn/vflHOBz7DFu89Mp20gZ2ffmVMdwMkfP0e2NqE8TNB29RGF9+Uf5c5r72BCs7GVrrZjY/ibe1vsg1G/Z5nhpjo3Fm/Abc0UKYUBAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAA/uUwSbJSjyXWLLBFU5vejLcETUDnSm0KnGF8AEmL6kaU9uhfkjT4y9gxCTrUVzQ9otFggsvsBd1ZBtQk5uyTO/pAymucfV85fJOD24TrZb7XEK8PneP1Twd+aC0xshWrAfNdD5O+N2YYiito4KK4SGnCpxgoKMVnc1JUIbp3iTCWsS/Ljqqj68bclJd4QR4S/JF667DSGdrv9HYY2pxmjdX8EtBHIIX7qa+MtuDRI5SrycyHpRCbcefJLkP1isU9FIRviEdULb13cuisnYvX9aSRHCL8NoleN7preOIvutLS+uBak1+H5bV2bEIapgTz4B3vRAypwB5KMO1vYFmHs=" ], + "priority" : [ "100" ] + } + }, { + "id" : "718f1976-f3a0-40d2-b85c-0d3ba2d1e341", + "name" : "rsa-enc-generated", + "providerId" : "rsa-enc-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEpAIBAAKCAQEAsh8CaQP/Gfr3Qa9QJ/yRTGrfvkE6Rw/TNyP4wEicYdORaGIn0E9bDCYQu0wUAc/yL5UgxJcUQxKIUTDhQcjO/wbe1P0ChMmdKayjf7ROLao4m37kokKixrZDapdspTDdYyqa7ZfJEzM+EjdYvMgYOwVO4yjBrtu3+aGAw/cYgZFAa410N3vaLEPmVkxP6dhWk4VDb7iOBbcFyO+p3w+lJ7XUD4rm609Jn8diApLlhDMRku5AhErFvQ1sruHGlZ25Lje/T9WBZoYSMGIaM6icJFlrRMqjjlf7NKPQSi5FQHxlPLIiqoFiQqJyKrx2bU0YX7pDwtxBr13iDwlcw9B3gQIDAQABAoIBABbZfy59P+yTcxmUMEpY45jJKFet4sMlRrlO84T91kB/FVWt1cwAChQruT9rBIaw/YauG5cshwG4Wbq0nwjt246qpnZDLgoJGmYItVass3oMg+4qn+YoJIfXmhwNPczj0QVSJ1rC+x1BQxKvfUIxFwP8loCchLAg6TUW9epDA1FHhnbFKhE504yBy+HR5NaP6rAU5OIvYuZDayT2LrVgoqp5JLBSitHvswtUxBpYGi78eDJIuLj8soyoR/XuNIgxeNo827/LzLJ6CNYBvxcXvnRYPwKbNrh8H3Cxr8/tWIprQdypke7rOmHUiL1HCLXYFNY6d4GDdQEzCDFaPhYPpDMCgYEA4zRSfWc/KZbtDbza0V/9PD6epX/+rxg6l+XBC0PmyWIbDnlR8hqQV+IIUwO4eX8xbeJnECb68InEqS3bvM5wAv2nfR2uJO6NQOiPkl1UvUgxx9SDeeqQpDKkbPvr87e8BsxWvpf8ltftDcUkMXrRrl+xi1d1yuXD70z5UCmLE38CgYEAyLIsmgUOYw6fP/q5Le7cknPkP3o7FCE5/BAoQquFbQGFa9ngNbxk9uqzobDuEQqyKKcgZNWBn3R+Um+Yj4ifoS2AfafIDBOljAUx31IL+zI/J84ZMXRPwlR/o5FBPlpGfQs2r3J1FVFV/+wGL0+a7K2M6GOtW0vdwlScg0nN9P8CgYEA2NlZWeMu/6zS9+emGWu6MMO7e04ccFV5pvxcMTpPjSmblUbplV8RIS/UrhbA/QUO0kfiAiKSIv36u1XPgfauJcyfDOVFDm64VpkgXpvBgx7ilE0aZ0QfZPgIwxP2cZiNVxe0OxiotffEgv4Du03zzq/6rnl9LXf6d+1Jjt73pFUCgYBJH1HM1CbHxJ4VK36o06yd14fD8P7xeKGtyx1AHUpByxoXj4x3R6rpo93K/bHfl6wNz8antnrB5CnaUzqcoUS37uIv5h+m9smMWKAxI62l2krUb+0R7bTZsvvGVrgUxcOE777+8Y7jM31H/3DJcBGcRidezGJvLxcfJMDZvNxDdQKBgQDUibI22vbSZXDyQ2kV4WUeKZjyXAHqyIGQgsGNpzDONZ//oiGPESSidk8iDRdF/ApKY0rLWMrU4jnJ+vd8wspoT56THL9KJ5lWkept035BqIyeBIBvz13gUoNH1cnAzgmzHM8j5iGqwKUbnpAR6B0jVFH568OoXN8TZhTfQNMwwQ==" ], + "keyUse" : [ "ENC" ], + "certificate" : [ "MIICmzCCAYMCBgGS+Yr21DANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjQxMTA0MjMzNjI2WhcNMzQxMTA0MjMzODA2WjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCyHwJpA/8Z+vdBr1An/JFMat++QTpHD9M3I/jASJxh05FoYifQT1sMJhC7TBQBz/IvlSDElxRDEohRMOFByM7/Bt7U/QKEyZ0prKN/tE4tqjibfuSiQqLGtkNql2ylMN1jKprtl8kTMz4SN1i8yBg7BU7jKMGu27f5oYDD9xiBkUBrjXQ3e9osQ+ZWTE/p2FaThUNvuI4FtwXI76nfD6UntdQPiubrT0mfx2ICkuWEMxGS7kCESsW9DWyu4caVnbkuN79P1YFmhhIwYhozqJwkWWtEyqOOV/s0o9BKLkVAfGU8siKqgWJConIqvHZtTRhfukPC3EGvXeIPCVzD0HeBAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAKStF5kbDrCUByQPI302I1JkMABZWzzX3seIHg5lXENap99w6fk+IrR1qHkmGqgtXdZ5nrxVsQAbAchhwJEii0KLf+Cu3cZQKZ0ENr6XGysv+esBJw4w6c8JDpoF4Zw6ORebMAneZcYKDqJmCWQMQxWFuPlYDKkbMoSQt4teukOenayPiSnqPhnz7NR0NuoYB55gvatF3EFQTThE+01UeAMsc4ub/gv1FIfCQDO793DSGtmf0PnNwuw+Mbj7WZSzUo8m1oDaj77ctb4N58JgT/R4i5HF6r/vxHfGWFhAAMN8q2tBrVH0v8yUaxXg5Jn6qEeiDJ0jpDbv4ZEZwhYnyPM=" ], + "priority" : [ "100" ], + "algorithm" : [ "RSA-OAEP" ] + } + }, { + "id" : "06f026a6-14cc-48ed-be67-176a87651086", + "name" : "aes-generated", + "providerId" : "aes-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "2e88d3f1-3ffd-49de-9567-28fcbe5f58d1" ], + "secret" : [ "ff2Cp0-rURcw7JQtoHaoWA" ], + "priority" : [ "100" ] + } + } ] + }, + "internationalizationEnabled" : false, + "supportedLocales" : [ ], + "authenticationFlows" : [ { + "id" : "b944d215-3a5f-45cc-8857-0600c62762e7", + "alias" : "Account verification options", + "description" : "Method with which to verity the existing account", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-email-verification", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "ALTERNATIVE", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "Verify Existing Account by Re-authentication", + "userSetupAllowed" : false + } ] + }, { + "id" : "ca3726ed-43a7-42ad-a63b-45a5737bcaaf", + "alias" : "Browser - Conditional OTP", + "description" : "Flow to determine if the OTP is required for the authentication", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "conditional-user-configured", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "auth-otp-form", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "5c301c8e-5841-4a21-95a3-4c3f01f1cd59", + "alias" : "Direct Grant - Conditional OTP", + "description" : "Flow to determine if the OTP is required for the authentication", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "conditional-user-configured", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "direct-grant-validate-otp", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "c196fa59-90fc-4eda-9ac3-0fe76df24755", + "alias" : "First broker login - Conditional OTP", + "description" : "Flow to determine if the OTP is required for the authentication", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "conditional-user-configured", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "auth-otp-form", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "8982eddc-3682-4738-b7b3-8104e9696c3d", + "alias" : "Handle Existing Account", + "description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-confirm-link", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "Account verification options", + "userSetupAllowed" : false + } ] + }, { + "id" : "bea16161-336d-4fb5-99ac-088391b6796d", + "alias" : "Reset - Conditional OTP", + "description" : "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "conditional-user-configured", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "reset-otp", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "4337db51-713b-4be5-8dee-81b43a87655c", + "alias" : "User creation or linking", + "description" : "Flow for the existing/non-existing user alternatives", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticatorConfig" : "create unique user config", + "authenticator" : "idp-create-user-if-unique", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "ALTERNATIVE", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "Handle Existing Account", + "userSetupAllowed" : false + } ] + }, { + "id" : "e8fb22f3-0139-4cad-ac10-e0e6295b5a39", + "alias" : "Verify Existing Account by Re-authentication", + "description" : "Reauthentication of existing account", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-username-password-form", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "CONDITIONAL", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "First broker login - Conditional OTP", + "userSetupAllowed" : false + } ] + }, { + "id" : "617bac5d-bd09-49f3-89e8-b00c2ac388fb", + "alias" : "browser", + "description" : "Browser based authentication", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "auth-cookie", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "auth-spnego", + "authenticatorFlow" : false, + "requirement" : "DISABLED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "identity-provider-redirector", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 25, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "ALTERNATIVE", + "priority" : 30, + "autheticatorFlow" : true, + "flowAlias" : "forms", + "userSetupAllowed" : false + } ] + }, { + "id" : "50232ecc-13ec-4f78-9740-159608bfde8e", + "alias" : "clients", + "description" : "Base authentication for clients", + "providerId" : "client-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "client-secret", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "client-jwt", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "client-secret-jwt", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 30, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "client-x509", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 40, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "eae16001-930c-402a-92d6-2e844084404b", + "alias" : "direct grant", + "description" : "OpenID Connect Resource Owner Grant", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "direct-grant-validate-username", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "direct-grant-validate-password", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "CONDITIONAL", + "priority" : 30, + "autheticatorFlow" : true, + "flowAlias" : "Direct Grant - Conditional OTP", + "userSetupAllowed" : false + } ] + }, { + "id" : "180f3c4b-3151-4af8-b296-780f2e5e4c2b", + "alias" : "docker auth", + "description" : "Used by Docker clients to authenticate against the IDP", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "docker-http-basic-authenticator", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "8728c1ef-5467-4f7e-8d22-9f40b4e1cfd5", + "alias" : "first broker login", + "description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticatorConfig" : "review profile config", + "authenticator" : "idp-review-profile", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "User creation or linking", + "userSetupAllowed" : false + } ] + }, { + "id" : "363c2005-5ff7-4253-a968-cfc8e4a4b77b", + "alias" : "forms", + "description" : "Username, password, otp and other auth forms.", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "auth-username-password-form", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "CONDITIONAL", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "Browser - Conditional OTP", + "userSetupAllowed" : false + } ] + }, { + "id" : "59159700-bda4-4787-8023-7b4bcc59c2ba", + "alias" : "registration", + "description" : "Registration flow", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "registration-page-form", + "authenticatorFlow" : true, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : true, + "flowAlias" : "registration form", + "userSetupAllowed" : false + } ] + }, { + "id" : "c13c6073-4a38-439a-869b-639d9b3a549d", + "alias" : "registration form", + "description" : "Registration form", + "providerId" : "form-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "registration-user-creation", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "registration-password-action", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 50, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "registration-recaptcha-action", + "authenticatorFlow" : false, + "requirement" : "DISABLED", + "priority" : 60, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "registration-terms-and-conditions", + "authenticatorFlow" : false, + "requirement" : "DISABLED", + "priority" : 70, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "e98a761c-a40c-4c9f-ae03-c51d247968a1", + "alias" : "reset credentials", + "description" : "Reset credentials for a user if they forgot their password or something", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "reset-credentials-choose-user", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "reset-credential-email", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "reset-password", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 30, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "CONDITIONAL", + "priority" : 40, + "autheticatorFlow" : true, + "flowAlias" : "Reset - Conditional OTP", + "userSetupAllowed" : false + } ] + }, { + "id" : "95510082-58a1-4bf3-99b8-e87f3b6958ab", + "alias" : "saml ecp", + "description" : "SAML ECP Profile Authentication Flow", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "http-basic-authenticator", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + } ], + "authenticatorConfig" : [ { + "id" : "083e6406-4119-4e29-90a1-40d3c4aa920b", + "alias" : "create unique user config", + "config" : { + "require.password.update.after.registration" : "false" + } + }, { + "id" : "1df2a359-12db-4c2c-9913-298bde3b473e", + "alias" : "review profile config", + "config" : { + "update.profile.on.first.login" : "missing" + } + } ], + "requiredActions" : [ { + "alias" : "CONFIGURE_TOTP", + "name" : "Configure OTP", + "providerId" : "CONFIGURE_TOTP", + "enabled" : true, + "defaultAction" : false, + "priority" : 10, + "config" : { } + }, { + "alias" : "TERMS_AND_CONDITIONS", + "name" : "Terms and Conditions", + "providerId" : "TERMS_AND_CONDITIONS", + "enabled" : false, + "defaultAction" : false, + "priority" : 20, + "config" : { } + }, { + "alias" : "UPDATE_PASSWORD", + "name" : "Update Password", + "providerId" : "UPDATE_PASSWORD", + "enabled" : true, + "defaultAction" : false, + "priority" : 30, + "config" : { } + }, { + "alias" : "UPDATE_PROFILE", + "name" : "Update Profile", + "providerId" : "UPDATE_PROFILE", + "enabled" : true, + "defaultAction" : false, + "priority" : 40, + "config" : { } + }, { + "alias" : "VERIFY_EMAIL", + "name" : "Verify Email", + "providerId" : "VERIFY_EMAIL", + "enabled" : true, + "defaultAction" : false, + "priority" : 50, + "config" : { } + }, { + "alias" : "delete_account", + "name" : "Delete Account", + "providerId" : "delete_account", + "enabled" : false, + "defaultAction" : false, + "priority" : 60, + "config" : { } + }, { + "alias" : "webauthn-register", + "name" : "Webauthn Register", + "providerId" : "webauthn-register", + "enabled" : true, + "defaultAction" : false, + "priority" : 70, + "config" : { } + }, { + "alias" : "webauthn-register-passwordless", + "name" : "Webauthn Register Passwordless", + "providerId" : "webauthn-register-passwordless", + "enabled" : true, + "defaultAction" : false, + "priority" : 80, + "config" : { } + }, { + "alias" : "VERIFY_PROFILE", + "name" : "Verify Profile", + "providerId" : "VERIFY_PROFILE", + "enabled" : true, + "defaultAction" : false, + "priority" : 90, + "config" : { } + }, { + "alias" : "delete_credential", + "name" : "Delete Credential", + "providerId" : "delete_credential", + "enabled" : true, + "defaultAction" : false, + "priority" : 100, + "config" : { } + }, { + "alias" : "update_user_locale", + "name" : "Update User Locale", + "providerId" : "update_user_locale", + "enabled" : true, + "defaultAction" : false, + "priority" : 1000, + "config" : { } + } ], + "browserFlow" : "browser", + "registrationFlow" : "registration", + "directGrantFlow" : "direct grant", + "resetCredentialsFlow" : "reset credentials", + "clientAuthenticationFlow" : "clients", + "dockerAuthenticationFlow" : "docker auth", + "firstBrokerLoginFlow" : "first broker login", + "attributes" : { + "cibaBackchannelTokenDeliveryMode" : "poll", + "cibaExpiresIn" : "120", + "cibaAuthRequestedUserHint" : "login_hint", + "parRequestUriLifespan" : "60", + "cibaInterval" : "5", + "realmReusableOtpCode" : "false" + }, + "keycloakVersion" : "26.0.2", + "userManagedAccessAllowed" : false, + "organizationsEnabled" : false, + "clientProfiles" : { + "profiles" : [ ] + }, + "clientPolicies" : { + "policies" : [ ] + } +} \ No newline at end of file diff --git a/query-connector/package-lock.json b/query-connector/package-lock.json index c27ed92e6..9cb36eb64 100644 --- a/query-connector/package-lock.json +++ b/query-connector/package-lock.json @@ -27,6 +27,7 @@ "jose": "5.2.2", "js-yaml": "4.1.0", "next": "14.2.10", + "next-auth": "^5.0.0-beta.25", "node-fetch": "^2.7.0", "pg": "^8.12.0", "pg-promise": "^11.5.4", @@ -97,6 +98,44 @@ "node": ">=6.0.0" } }, + "node_modules/@auth/core": { + "version": "0.37.2", + "resolved": "https://registry.npmjs.org/@auth/core/-/core-0.37.2.tgz", + "integrity": "sha512-kUvzyvkcd6h1vpeMAojK2y7+PAV5H+0Cc9+ZlKYDFhDY31AlvsB+GW5vNO4qE3Y07KeQgvNO9U0QUx/fN62kBw==", + "dependencies": { + "@panva/hkdf": "^1.2.1", + "@types/cookie": "0.6.0", + "cookie": "0.7.1", + "jose": "^5.9.3", + "oauth4webapi": "^3.0.0", + "preact": "10.11.3", + "preact-render-to-string": "5.2.3" + }, + "peerDependencies": { + "@simplewebauthn/browser": "^9.0.1", + "@simplewebauthn/server": "^9.0.2", + "nodemailer": "^6.8.0" + }, + "peerDependenciesMeta": { + "@simplewebauthn/browser": { + "optional": true + }, + "@simplewebauthn/server": { + "optional": true + }, + "nodemailer": { + "optional": true + } + } + }, + "node_modules/@auth/core/node_modules/jose": { + "version": "5.9.6", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.9.6.tgz", + "integrity": "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/@aws-crypto/crc32": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", @@ -4559,6 +4598,14 @@ "node": ">=12.4.0" } }, + "node_modules/@panva/hkdf": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.2.1.tgz", + "integrity": "sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/@parcel/watcher": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.4.1.tgz", @@ -6008,6 +6055,11 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" + }, "node_modules/@types/docker-modem": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/@types/docker-modem/-/docker-modem-3.0.6.tgz", @@ -8262,6 +8314,14 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "license": "MIT" }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cookiejar": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", @@ -13999,6 +14059,32 @@ } } }, + "node_modules/next-auth": { + "version": "5.0.0-beta.25", + "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-5.0.0-beta.25.tgz", + "integrity": "sha512-2dJJw1sHQl2qxCrRk+KTQbeH+izFbGFPuJj5eGgBZFYyiYYtvlrBeUw1E/OJJxTRjuxbSYGnCTkUIRsIIW0bog==", + "dependencies": { + "@auth/core": "0.37.2" + }, + "peerDependencies": { + "@simplewebauthn/browser": "^9.0.1", + "@simplewebauthn/server": "^9.0.2", + "next": "^14.0.0-0 || ^15.0.0-0", + "nodemailer": "^6.6.5", + "react": "^18.2.0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@simplewebauthn/browser": { + "optional": true + }, + "@simplewebauthn/server": { + "optional": true + }, + "nodemailer": { + "optional": true + } + } + }, "node_modules/next/node_modules/postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", @@ -14148,6 +14234,14 @@ "integrity": "sha512-cTGB9ptp9dY9A5VbMSe7fQBcl/tt22Vcqdq8+eN93rblOuE0aCFu4aZ2vMwct/2t+lFnosm8RkQW1I0Omb1UtQ==", "license": "MIT" }, + "node_modules/oauth4webapi": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.1.2.tgz", + "integrity": "sha512-KQZkNU+xn02lWrFu5Vjqg9E81yPtDSxUZorRHlLWVoojD+H/0GFbH59kcnz5Thdjj7c4/mYMBPj/mhvGe/kKXA==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -14950,6 +15044,31 @@ "dev": true, "license": "MIT" }, + "node_modules/preact": { + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.11.3.tgz", + "integrity": "sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/preact-render-to-string": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz", + "integrity": "sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==", + "dependencies": { + "pretty-format": "^3.8.0" + }, + "peerDependencies": { + "preact": ">=10" + } + }, + "node_modules/preact-render-to-string/node_modules/pretty-format": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", + "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==" + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", diff --git a/query-connector/package.json b/query-connector/package.json index 8b6056700..a28de63fb 100644 --- a/query-connector/package.json +++ b/query-connector/package.json @@ -41,6 +41,7 @@ "jose": "5.2.2", "js-yaml": "4.1.0", "next": "14.2.10", + "next-auth": "^5.0.0-beta.25", "node-fetch": "^2.7.0", "pg": "^8.12.0", "pg-promise": "^11.5.4", diff --git a/query-connector/src/app/api/auth/[...nextauth]/route.ts b/query-connector/src/app/api/auth/[...nextauth]/route.ts new file mode 100644 index 000000000..00db783ea --- /dev/null +++ b/query-connector/src/app/api/auth/[...nextauth]/route.ts @@ -0,0 +1,2 @@ +import { handlers } from "@/auth"; // Referring to the auth.ts we just created +export const { GET, POST } = handlers; diff --git a/query-connector/src/app/layout.tsx b/query-connector/src/app/layout.tsx index 8dcc653f9..3f9afa065 100644 --- a/query-connector/src/app/layout.tsx +++ b/query-connector/src/app/layout.tsx @@ -2,6 +2,7 @@ import "../styles/styles.scss"; import Header from "./query/components/header/header"; import Footer from "./query/components/footer/footer"; import { DataProvider } from "./utils"; +import { SessionProvider } from "next-auth/react"; /** * Establishes the layout for the application. @@ -16,13 +17,15 @@ export default function RootLayout({ }) { return ( - -
-
- {children} -
-