ethyca-fides 2.69.0rc9__py2.py3-none-any.whl → 2.69.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ethyca-fides might be problematic. Click here for more details.
- {ethyca_fides-2.69.0rc9.dist-info → ethyca_fides-2.69.1.dist-info}/METADATA +2 -2
- {ethyca_fides-2.69.0rc9.dist-info → ethyca_fides-2.69.1.dist-info}/RECORD +204 -195
- fides/_version.py +3 -3
- fides/api/alembic/migrations/versions/78dbe23d8204_adding_privacy_request_redaction_patterns.py +52 -0
- fides/api/api/v1/api.py +2 -0
- fides/api/api/v1/endpoints/dsr_package_link.py +2 -2
- fides/api/api/v1/endpoints/oauth_endpoints.py +20 -6
- fides/api/api/v1/endpoints/privacy_request_redaction_patterns_endpoints.py +95 -0
- fides/api/api/v1/endpoints/user_endpoints.py +28 -1
- fides/api/app_setup.py +16 -2
- fides/api/db/base.py +3 -0
- fides/api/main.py +22 -0
- fides/api/models/client.py +1 -0
- fides/api/models/privacy_request_redaction_pattern.py +64 -0
- fides/api/oauth/utils.py +117 -6
- fides/api/schemas/privacy_request_redaction_patterns.py +55 -0
- fides/api/service/privacy_request/dsr_package/dsr_data_preprocessor.py +231 -0
- fides/api/service/privacy_request/dsr_package/dsr_report_builder.py +286 -120
- fides/api/service/privacy_request/dsr_package/templates/attachments_index.html +4 -2
- fides/api/service/privacy_request/dsr_package/templates/collection_index.html +3 -1
- fides/api/service/privacy_request/dsr_package/templates/dataset_index.html +1 -1
- fides/api/service/privacy_request/dsr_package/utils.py +268 -0
- fides/api/service/privacy_request/request_runner_service.py +8 -2
- fides/api/service/storage/streaming/smart_open_streaming_storage.py +107 -170
- fides/api/service/storage/util.py +579 -0
- fides/api/task/manual/manual_task_graph_task.py +11 -9
- fides/api/tasks/storage.py +2 -2
- fides/api/util/endpoint_utils.py +0 -13
- fides/api/util/rate_limit.py +194 -0
- fides/common/api/scope_registry.py +8 -0
- fides/common/api/v1/urn_registry.py +3 -0
- fides/config/redis_settings.py +27 -3
- fides/config/security_settings.py +31 -9
- fides/ui-build/static/admin/404.html +1 -1
- fides/ui-build/static/admin/_next/static/1TigfgzjzHeoVqRLNIMYa/_buildManifest.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4831-fd99c0b3784de128.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{_app-ef8e1c986bc5b795.js → _app-fcdad91f6f66292b.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/privacy-requests-2ecc073f41628f62.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-de8cb3739ab99c09.js → new-92f52c43f522a350.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-05d61c80a556b2d5.js → [id]-64452dfae2c5e614.js} +1 -1
- fides/ui-build/static/admin/add-systems/manual.html +1 -1
- fides/ui-build/static/admin/add-systems/multiple.html +1 -1
- fides/ui-build/static/admin/add-systems.html +1 -1
- fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
- fides/ui-build/static/admin/consent/configure.html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
- fides/ui-build/static/admin/consent/properties.html +1 -1
- fides/ui-build/static/admin/consent/reporting.html +1 -1
- fides/ui-build/static/admin/consent.html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
- fides/ui-build/static/admin/data-catalog.html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
- fides/ui-build/static/admin/data-discovery/activity.html +1 -1
- fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-discovery/detection.html +1 -1
- fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
- fides/ui-build/static/admin/datamap.html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
- fides/ui-build/static/admin/dataset/new.html +1 -1
- fides/ui-build/static/admin/dataset.html +1 -1
- fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
- fides/ui-build/static/admin/datastore-connection/new.html +1 -1
- fides/ui-build/static/admin/datastore-connection.html +1 -1
- fides/ui-build/static/admin/index.html +1 -1
- fides/ui-build/static/admin/integrations/[id].html +1 -1
- fides/ui-build/static/admin/integrations.html +1 -1
- fides/ui-build/static/admin/login/[provider].html +1 -1
- fides/ui-build/static/admin/login.html +1 -1
- fides/ui-build/static/admin/messaging/[id].html +1 -1
- fides/ui-build/static/admin/messaging/add-template.html +1 -1
- fides/ui-build/static/admin/messaging.html +1 -1
- fides/ui-build/static/admin/poc/ant-components.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
- fides/ui-build/static/admin/poc/forms.html +1 -1
- fides/ui-build/static/admin/poc/table-migration.html +1 -1
- fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure/messaging.html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
- fides/ui-build/static/admin/privacy-requests.html +1 -1
- fides/ui-build/static/admin/properties/[id].html +1 -1
- fides/ui-build/static/admin/properties/add-property.html +1 -1
- fides/ui-build/static/admin/properties.html +1 -1
- fides/ui-build/static/admin/reporting/datamap.html +1 -1
- fides/ui-build/static/admin/settings/about/alpha.html +1 -1
- fides/ui-build/static/admin/settings/about.html +1 -1
- fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
- fides/ui-build/static/admin/settings/consent.html +1 -1
- fides/ui-build/static/admin/settings/custom-fields.html +1 -1
- fides/ui-build/static/admin/settings/domain-records.html +1 -1
- fides/ui-build/static/admin/settings/domains.html +1 -1
- fides/ui-build/static/admin/settings/email-templates.html +1 -1
- fides/ui-build/static/admin/settings/locations.html +1 -1
- fides/ui-build/static/admin/settings/organization.html +1 -1
- fides/ui-build/static/admin/settings/privacy-requests.html +1 -0
- fides/ui-build/static/admin/settings/regulations.html +1 -1
- fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
- fides/ui-build/static/admin/systems/configure/[id].html +1 -1
- fides/ui-build/static/admin/systems.html +1 -1
- fides/ui-build/static/admin/taxonomy.html +1 -1
- fides/ui-build/static/admin/user-management/new.html +1 -1
- fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
- fides/ui-build/static/admin/user-management.html +1 -1
- fides/ui-build/static/admin/_next/static/XiHm-6CdVChTC5rbN9GtT/_buildManifest.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4121-c8d5d717e31899e1.js +0 -1
- {ethyca_fides-2.69.0rc9.dist-info → ethyca_fides-2.69.1.dist-info}/WHEEL +0 -0
- {ethyca_fides-2.69.0rc9.dist-info → ethyca_fides-2.69.1.dist-info}/entry_points.txt +0 -0
- {ethyca_fides-2.69.0rc9.dist-info → ethyca_fides-2.69.1.dist-info}/licenses/LICENSE +0 -0
- {ethyca_fides-2.69.0rc9.dist-info → ethyca_fides-2.69.1.dist-info}/top_level.txt +0 -0
- /fides/ui-build/static/admin/_next/static/{XiHm-6CdVChTC5rbN9GtT → 1TigfgzjzHeoVqRLNIMYa}/_ssgManifest.js +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{1817-3d9e110e007853f0.js → 1817-0ca16d288fad916d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{3620-31ebb43dba84cbbd.js → 3620-602eb74dc896d556.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{3729-a1ca1608efc11ac4.js → 3729-c17ac8031a4c4fd1.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{3872-a91143aa35fa8ef8.js → 3872-f78dec02f0d959ae.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{4608-23bbd4c3c4a59f42.js → 4608-be8cba73f5d7c326.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{4786-0827aae7aceadd22.js → 4786-61154adf88e448e1.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{4808-78ca630f2d2503cd.js → 4808-dd4157aa72648068.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{5487-8c635883dcaa9c2a.js → 5487-02d00bad7c6830e0.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{6084-0096d7de64ef8015.js → 6084-c153669d5567e242.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{6954-9d46e2276c461c26.js → 6954-5296188c19d7d0ac.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{7476-d1b0af9ade392e5b.js → 7476-45c5088baa8b66af.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{7630-da0a7ce4e3a0d62c.js → 7630-7ed6c6117775dffe.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{787-3499983fa346b380.js → 787-a8c7eab617e2fceb.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{79-f197fc4db8d530e5.js → 79-65674011d455af4d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{796-db1e30119ea973c7.js → 796-9e1ca1a4030707c5.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{8002-971e29181f72edd1.js → 8002-24af20d679efc04e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{9826-b0b3d3cfb13bfbc1.js → 9826-dbae8dee941a7fac.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-9dc7e70ab5b05723.js → manual-ace203dfacacbdc4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-4b79a1652297ed9a.js → multiple-920fb469e0dda1d2.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{add-systems-1632a59203fe8eab.js → add-systems-bd0d82078e67cac3.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-1ca9df7ca91bd101.js → add-vendors-406170eaae4329c6.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{configure-07bdbc9ae4137db4.js → configure-7207ab23bdb36ce8.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-2795cd4115a77c94.js → privacy-experience-9dda4de5ec580279.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-e02921dc82dccbb1.js → [id]-b378576cba255609.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-98f9e4ba3610628a.js → new-2ca1de7b88094ab0.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-notices-17ed82777810d1c6.js → privacy-notices-0d4844d0b808e6e4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{consent-09610b10923d9268.js → consent-3e8bdefe714254ec.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-da1a48336daff6f8.js → [resourceUrn]-2c29ff7a01198f30.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-d8e776f1e64e4ba8.js → [projectUrn]-04cfe2cfba7b7cd8.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{projects-75b9629b0d9cdf96.js → projects-5f2d7b24804f861f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-470da05db63767cd.js → [resourceUrn]-8eb581024bc0172f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{resources-6c3714ee97a718c1.js → resources-de704de849960f01.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{data-catalog-6984c033b8fe3a13.js → data-catalog-30108b00ac769fc3.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/{[systemId]-2f0a33ef9ba1f1da.js → [systemId]-e1ba213fb666b3f4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/{[monitorId]-e9d4f25b20ff6781.js → [monitorId]-6d133580045abdda.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{action-center-9c428d3ef0985915.js → action-center-9a81d42a474e1e48.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-c3a97e6721ca0abe.js → [resourceUrn]-8f736b078e9842da.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-a0a7de552ef71f5b.js → detection-eb814e3c22807871.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-109754fec0755339.js → [resourceUrn]-6875b7783fcfda2f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-88654783b06b3b21.js → discovery-172dbd7740e212ca.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{datamap-89136e6800dc9369.js → datamap-c7390e046b2e2b7f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-8f58192dcb54883d.js → [...subfieldNames]-dfd71c1e9c458b89.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-dcb4ab380a77aa1e.js → [collectionName]-7cdc42ec5493b83d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{[datasetId]-6f16d43071fb9c11.js → [datasetId]-e12b11ba15bc3fc1.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{new-97f06e21580f1f6a.js → new-e32fccc4ca520d2b.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{dataset-674bb3940f088ecc.js → dataset-7c59a6abf6ba6207.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{[id]-6f77d8647fca71e0.js → [id]-927b7e476c4b47d0.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{new-821dd1269834cfa2.js → new-cbe100d50df34285.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{datastore-connection-23e4caf79faa8106.js → datastore-connection-cce20440b177050b.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{index-23eb64eed81dcb69.js → index-6cd8708106331b8d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/integrations/{[id]-3a4cd3fe9094fba3.js → [id]-4c3c413a2668df53.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{integrations-57e618d7b16ac69a.js → integrations-95402b5001c07ef2.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{[id]-c9a323eb6a929476.js → [id]-3c6dc2f6e6bae960.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{add-template-b9bb09e46921a590.js → add-template-4a6d4023a7791be8.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{messaging-82c631a12b5a008c.js → messaging-76b204c9b98d656f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{table-migration-38360083348c3d6c.js → table-migration-48500551fd6a7602.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{[id]-0d0bb9eb004a3336.js → [id]-0f25a76dd18c5e20.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/{messaging-f9320a58f489f5b7.js → messaging-ad6ad3e5bd72765d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/{storage-d0cfa8aeddd43a40.js → storage-6032d82f0fc2893d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{configure-72ca94ec5ed85733.js → configure-d83e5bd52a638234.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{privacy-requests-5a5edc8a4aa7c30a.js → privacy-requests-baf31c3e4b081046.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-5ec775c4904fdbfe.js → [id]-e784c05d056b2371.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-a6812c0916f2949e.js → add-property-0a7a2db148a7561a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/{alpha-3e72e9f91991c119.js → alpha-a82f3df840d5c1b5.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{about-6aab092f4871cecb.js → about-d06fb16487705b9d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{consent-be47008304106395.js → consent-93a978443bf299db.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{custom-fields-ae1b57589da7b175.js → custom-fields-9ecb803099082bf4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-23a6d7a921150188.js → domain-records-16fdd91a81074dd1.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domains-2a9e8859ab4d9de6.js → domains-4cdd6001e7cb9aee.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{email-templates-4f9f0fdf9925ae90.js → email-templates-1914de830ce5cfc4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-46f7af35cee4a8bb.js → locations-2e635dcd11b78224.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{organization-a596a96cb8d0aa8e.js → organization-f547f1f33c12faf3.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-6ed5fc2410e00857.js → regulations-7c02e469d8c5bd74.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/{test-datasets-86811e3cda277e77.js → test-datasets-20b1193ed76c56b0.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-5a43f108d8047d5b.js → [id]-6e15332935f6b538.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{systems-045a841e22e85ea8.js → systems-fbc8761ef4d55516.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{taxonomy-1b3f2d4bcb0e164d.js → taxonomy-4d7827fc9c46b6b8.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-2cab41659f1ee7da.js → user-management-9cec020f89544426.js} +0 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from ipaddress import ip_address
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
from fastapi import Request
|
|
7
|
+
from fastapi.responses import JSONResponse
|
|
8
|
+
from loguru import logger
|
|
9
|
+
from slowapi import Limiter
|
|
10
|
+
from slowapi.util import get_remote_address # type: ignore
|
|
11
|
+
from starlette.middleware.base import BaseHTTPMiddleware
|
|
12
|
+
|
|
13
|
+
from fides.config import CONFIG
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class InvalidClientIPError(Exception):
|
|
17
|
+
def __init__(self, detail: str, header_value: str, header_name: str):
|
|
18
|
+
self.detail = detail
|
|
19
|
+
self.header_value = header_value
|
|
20
|
+
self.header_name = header_name
|
|
21
|
+
super().__init__(detail)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def validate_client_ip(ip: Optional[str]) -> bool:
|
|
25
|
+
"""
|
|
26
|
+
Returns true if the provided ip is valid and not from a reserved range.
|
|
27
|
+
Returns false otherwise.
|
|
28
|
+
"""
|
|
29
|
+
if not ip:
|
|
30
|
+
return False
|
|
31
|
+
try:
|
|
32
|
+
ip_obj = ip_address(ip)
|
|
33
|
+
if (
|
|
34
|
+
ip_obj.is_loopback
|
|
35
|
+
or ip_obj.is_link_local
|
|
36
|
+
or ip_obj.is_reserved
|
|
37
|
+
or ip_obj.is_multicast
|
|
38
|
+
or ip_obj.is_private
|
|
39
|
+
):
|
|
40
|
+
return False
|
|
41
|
+
return True
|
|
42
|
+
except ValueError:
|
|
43
|
+
return False
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _extract_hostname_from_ip(ip: str) -> Optional[str]:
|
|
47
|
+
"""
|
|
48
|
+
Extract hostname/IP address from header value, stripping port if present.
|
|
49
|
+
|
|
50
|
+
Simple string-based approach following the reference implementation pattern.
|
|
51
|
+
Does not validate whether the result is a valid IP address.
|
|
52
|
+
|
|
53
|
+
Examples:
|
|
54
|
+
# IPv4 cases
|
|
55
|
+
_extract_hostname_from_ip("192.168.1.1") -> "192.168.1.1"
|
|
56
|
+
_extract_hostname_from_ip("192.168.1.1:8080") -> "192.168.1.1"
|
|
57
|
+
|
|
58
|
+
# IPv6 cases
|
|
59
|
+
_extract_hostname_from_ip("2001:db8::1") -> "2001:db8::1"
|
|
60
|
+
_extract_hostname_from_ip("[2001:db8::1]:8080") -> "2001:db8::1"
|
|
61
|
+
|
|
62
|
+
# Edge cases (alidation will later reject)
|
|
63
|
+
_extract_hostname_from_ip("192.168.1.1, 192.168.1.2") -> "192.168.1.1, 192.168.1.2"
|
|
64
|
+
_extract_hostname_from_ip("not-an-ip:8080") -> "not-an-ip"
|
|
65
|
+
|
|
66
|
+
# Error
|
|
67
|
+
_extract_hostname_from_ip("") -> raises ValueError
|
|
68
|
+
|
|
69
|
+
Raises:
|
|
70
|
+
ValueError: If no hostname can be extracted from the input
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
clean_ip = ip.strip()
|
|
74
|
+
|
|
75
|
+
if not clean_ip:
|
|
76
|
+
raise ValueError("Could not parse IP from header value")
|
|
77
|
+
|
|
78
|
+
# Handle IPv6 with port: [IPv6]:port
|
|
79
|
+
if "]:" in clean_ip:
|
|
80
|
+
return clean_ip.split("]:")[0].replace("[", "").strip()
|
|
81
|
+
|
|
82
|
+
# Handle IPv4 with port: IPv4:port
|
|
83
|
+
if ":" in clean_ip and "::" not in clean_ip:
|
|
84
|
+
return clean_ip.split(":")[0].strip()
|
|
85
|
+
|
|
86
|
+
# Return as-is (IPv6 without port, IPv4 without port, or other values)
|
|
87
|
+
return clean_ip
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _resolve_client_ip_from_header(request: Request, strict: bool) -> str:
|
|
91
|
+
"""Shared resolver for client IP from the configured header.
|
|
92
|
+
|
|
93
|
+
- When strict=True: raise InvalidClientIPError on invalid/malformed header values.
|
|
94
|
+
- When strict=False: never raise; fall back to the connection source IP.
|
|
95
|
+
"""
|
|
96
|
+
header_name = CONFIG.security.rate_limit_client_ip_header
|
|
97
|
+
if not header_name:
|
|
98
|
+
# This line should never be reached when rate limiting is enabled
|
|
99
|
+
logger.warning(
|
|
100
|
+
"Rate limit client IP header not configured. Falling back to source IP.",
|
|
101
|
+
header_name,
|
|
102
|
+
)
|
|
103
|
+
return get_remote_address(request)
|
|
104
|
+
|
|
105
|
+
ip_address_from_header = request.headers.get(header_name)
|
|
106
|
+
if not ip_address_from_header:
|
|
107
|
+
logger.debug(
|
|
108
|
+
"Rate limit header '{}' not found. Falling back to source IP.",
|
|
109
|
+
header_name,
|
|
110
|
+
)
|
|
111
|
+
return get_remote_address(request)
|
|
112
|
+
|
|
113
|
+
# Extract and validate IP
|
|
114
|
+
try:
|
|
115
|
+
extracted_ip = _extract_hostname_from_ip(ip_address_from_header)
|
|
116
|
+
if extracted_ip and validate_client_ip(extracted_ip):
|
|
117
|
+
return extracted_ip
|
|
118
|
+
raise ValueError("IP failed validation")
|
|
119
|
+
except ValueError:
|
|
120
|
+
if strict:
|
|
121
|
+
logger.error(
|
|
122
|
+
"Invalid IP '{}' in header '{}'. Rejecting request.",
|
|
123
|
+
ip_address_from_header,
|
|
124
|
+
header_name,
|
|
125
|
+
)
|
|
126
|
+
raise InvalidClientIPError(
|
|
127
|
+
detail="Invalid IP address format",
|
|
128
|
+
header_value=ip_address_from_header,
|
|
129
|
+
header_name=header_name,
|
|
130
|
+
)
|
|
131
|
+
# Non-strict path: fall back silently to source IP
|
|
132
|
+
return get_remote_address(request)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def get_client_ip_from_header(request: Request) -> str:
|
|
136
|
+
"""
|
|
137
|
+
Extracts the client IP from the configured CDN header.
|
|
138
|
+
|
|
139
|
+
If the header is not configured or is missing, it falls back to the
|
|
140
|
+
source IP on the request.
|
|
141
|
+
|
|
142
|
+
Raises InvalidClientIPError if header contains invalid IP format.
|
|
143
|
+
"""
|
|
144
|
+
return _resolve_client_ip_from_header(request, strict=True)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def safe_rate_limit_key(request: Request) -> str:
|
|
148
|
+
"""
|
|
149
|
+
Safe key function for SlowAPI limiter.
|
|
150
|
+
|
|
151
|
+
Must never raise. If the configured header is missing or malformed,
|
|
152
|
+
fall back to the connection source IP for rate limiting purposes.
|
|
153
|
+
"""
|
|
154
|
+
return _resolve_client_ip_from_header(request, strict=False)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class RateLimitIPValidationMiddleware(BaseHTTPMiddleware):
|
|
158
|
+
"""
|
|
159
|
+
Pre-validate the configured client IP header when rate limiting is enabled.
|
|
160
|
+
|
|
161
|
+
If the header is present but invalid, short-circuit the request with 422.
|
|
162
|
+
This keeps SlowAPI's middleware path free of exceptions from the key function.
|
|
163
|
+
"""
|
|
164
|
+
|
|
165
|
+
async def dispatch(self, request: Request, call_next): # type: ignore
|
|
166
|
+
if is_rate_limit_enabled:
|
|
167
|
+
try:
|
|
168
|
+
# Triggers parsing/validation; raises on invalid header
|
|
169
|
+
get_client_ip_from_header(request)
|
|
170
|
+
except InvalidClientIPError:
|
|
171
|
+
return JSONResponse(
|
|
172
|
+
status_code=422, content={"detail": "Invalid client IP header"}
|
|
173
|
+
)
|
|
174
|
+
return await call_next(request)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
# Used for rate limiting with Slow API
|
|
178
|
+
# Decorate individual routes to deviate from the default rate limits
|
|
179
|
+
is_rate_limit_enabled = (
|
|
180
|
+
CONFIG.security.rate_limit_client_ip_header is not None
|
|
181
|
+
and CONFIG.security.rate_limit_client_ip_header != ""
|
|
182
|
+
)
|
|
183
|
+
fides_limiter = Limiter(
|
|
184
|
+
storage_uri=CONFIG.redis.connection_url_unencoded,
|
|
185
|
+
application_limits=[
|
|
186
|
+
CONFIG.security.request_rate_limit
|
|
187
|
+
], # Creates ONE shared bucket for all endpoints
|
|
188
|
+
headers_enabled=True,
|
|
189
|
+
key_prefix=CONFIG.security.rate_limit_prefix,
|
|
190
|
+
key_func=safe_rate_limit_key,
|
|
191
|
+
retry_after="http-date",
|
|
192
|
+
in_memory_fallback_enabled=False, # Fall back to no rate limiting if Redis unavailable
|
|
193
|
+
enabled=is_rate_limit_enabled,
|
|
194
|
+
)
|
|
@@ -30,6 +30,7 @@ DATA_SUBJECT = "data_subject"
|
|
|
30
30
|
DATA_USE = "data_use"
|
|
31
31
|
DATASET = "dataset"
|
|
32
32
|
DELETE = "delete"
|
|
33
|
+
PRIVACY_REQUEST_REDACTION_PATTERNS = "privacy-request-redaction-patterns"
|
|
33
34
|
ENCRYPTION = "encryption"
|
|
34
35
|
MESSAGING_TEMPLATE = "messaging-template"
|
|
35
36
|
EVALUATION = "evaluation"
|
|
@@ -134,6 +135,11 @@ DATA_USE_UPDATE = f"{DATA_USE}:{UPDATE}"
|
|
|
134
135
|
DATA_USE_DELETE = f"{DATA_USE}:{DELETE}"
|
|
135
136
|
|
|
136
137
|
DATASET_CREATE_OR_UPDATE = f"{DATASET}:{CREATE_OR_UPDATE}"
|
|
138
|
+
|
|
139
|
+
PRIVACY_REQUEST_REDACTION_PATTERNS_READ = f"{PRIVACY_REQUEST_REDACTION_PATTERNS}:{READ}"
|
|
140
|
+
PRIVACY_REQUEST_REDACTION_PATTERNS_UPDATE = (
|
|
141
|
+
f"{PRIVACY_REQUEST_REDACTION_PATTERNS}:{UPDATE}"
|
|
142
|
+
)
|
|
137
143
|
DATASET_DELETE = f"{DATASET}:{DELETE}"
|
|
138
144
|
DATASET_READ = f"{DATASET}:{READ}"
|
|
139
145
|
DATASET_TEST = f"{DATASET}:{TEST}"
|
|
@@ -288,6 +294,8 @@ SCOPE_DOCS = {
|
|
|
288
294
|
DATA_USE_UPDATE: "Update data uses",
|
|
289
295
|
DATASET_CREATE_OR_UPDATE: "Create or modify datasets",
|
|
290
296
|
DATASET_DELETE: "Delete datasets",
|
|
297
|
+
PRIVACY_REQUEST_REDACTION_PATTERNS_READ: "View privacy request redaction patterns",
|
|
298
|
+
PRIVACY_REQUEST_REDACTION_PATTERNS_UPDATE: "Update privacy request redaction patterns",
|
|
291
299
|
DATASET_READ: "View datasets",
|
|
292
300
|
DATASET_TEST: "Run a standalone privacy request test for a dataset",
|
|
293
301
|
ENCRYPTION_EXEC: "Encrypt data",
|
|
@@ -116,6 +116,9 @@ PRIVACY_REQUEST_TRANSFER_TO_PARENT = (
|
|
|
116
116
|
"/privacy-request/transfer/{privacy_request_id}/{rule_key}"
|
|
117
117
|
)
|
|
118
118
|
|
|
119
|
+
# Privacy Request Redaction Patterns URLs
|
|
120
|
+
PRIVACY_REQUEST_REDACTION_PATTERNS = "/privacy-request/redaction-patterns"
|
|
121
|
+
|
|
119
122
|
# Privacy Request pre-approve URLs
|
|
120
123
|
PRIVACY_REQUEST_PRE_APPROVE = "/privacy-request/{privacy_request_id}/pre-approve"
|
|
121
124
|
PRIVACY_REQUEST_PRE_APPROVE_ELIGIBLE = PRIVACY_REQUEST_PRE_APPROVE + "/eligible"
|
fides/config/redis_settings.py
CHANGED
|
@@ -181,8 +181,24 @@ class RedisSettings(FidesSettings):
|
|
|
181
181
|
description="A full connection URL to the read-only Redis cache. If not specified, this URL is automatically assembled from the read_only_host, read_only_port, read_only_password and read_only_db_index specified above.",
|
|
182
182
|
exclude=True,
|
|
183
183
|
)
|
|
184
|
+
connection_url_unencoded: Optional[str] = Field(
|
|
185
|
+
default=None,
|
|
186
|
+
description="A full connection URL to the Redis cache with the password unencoded. If not specified, this URL is automatically assembled from the host, port, password and db_index specified above.",
|
|
187
|
+
exclude=True,
|
|
188
|
+
)
|
|
189
|
+
read_only_connection_url_unencoded: Optional[str] = Field(
|
|
190
|
+
default=None,
|
|
191
|
+
description="A full connection URL to the read-only Redis cache with the password unencoded. If not specified, this URL is automatically assembled from the read_only_host, read_only_port, read_only_password and read_only_db_index specified above.",
|
|
192
|
+
exclude=True,
|
|
193
|
+
)
|
|
184
194
|
|
|
185
|
-
@field_validator(
|
|
195
|
+
@field_validator(
|
|
196
|
+
"connection_url",
|
|
197
|
+
"read_only_connection_url",
|
|
198
|
+
"connection_url_unencoded",
|
|
199
|
+
"read_only_connection_url_unencoded",
|
|
200
|
+
mode="before",
|
|
201
|
+
)
|
|
186
202
|
@classmethod
|
|
187
203
|
def assemble_connection_url(
|
|
188
204
|
cls,
|
|
@@ -195,7 +211,14 @@ class RedisSettings(FidesSettings):
|
|
|
195
211
|
return v
|
|
196
212
|
|
|
197
213
|
# Determine which set of settings to use based on field name
|
|
198
|
-
is_read_only = info.field_name
|
|
214
|
+
is_read_only = info.field_name in (
|
|
215
|
+
"read_only_connection_url",
|
|
216
|
+
"read_only_connection_url_unencoded",
|
|
217
|
+
)
|
|
218
|
+
is_unencoded = info.field_name in (
|
|
219
|
+
"connection_url_unencoded",
|
|
220
|
+
"read_only_connection_url_unencoded",
|
|
221
|
+
)
|
|
199
222
|
|
|
200
223
|
# Extract settings - fallbacks already resolved by field validators for read-only fields
|
|
201
224
|
user = (
|
|
@@ -244,7 +267,8 @@ class RedisSettings(FidesSettings):
|
|
|
244
267
|
# redis://<user>:<password>@<host>
|
|
245
268
|
auth_prefix = ""
|
|
246
269
|
if password or user:
|
|
247
|
-
|
|
270
|
+
encoded_password = password if is_unencoded else quote_plus(password)
|
|
271
|
+
auth_prefix = f"{quote_plus(user)}:{encoded_password}@"
|
|
248
272
|
|
|
249
273
|
# For host, we don't have a fallback - read replica should be a different host
|
|
250
274
|
host = (
|
|
@@ -89,18 +89,22 @@ class SecuritySettings(FidesSettings):
|
|
|
89
89
|
default=None,
|
|
90
90
|
description="When using a parent/child Fides deployment, this username will be used by the child server to access the parent server.",
|
|
91
91
|
)
|
|
92
|
-
public_request_rate_limit: str = Field(
|
|
93
|
-
default="2000/minute",
|
|
94
|
-
description="The number of requests from a single IP address allowed to hit a public endpoint within the specified time period",
|
|
95
|
-
)
|
|
96
92
|
rate_limit_prefix: str = Field(
|
|
97
|
-
default="
|
|
93
|
+
default="rate-limit",
|
|
98
94
|
description="The prefix given to keys in the Redis cache used by the rate limiter.",
|
|
99
95
|
)
|
|
96
|
+
rate_limit_client_ip_header: Optional[str] = Field(
|
|
97
|
+
default=None,
|
|
98
|
+
description="The header used to determine the client IP address for rate limiting. If not set or set to empty string, rate limiting will be disabled.",
|
|
99
|
+
)
|
|
100
100
|
request_rate_limit: str = Field(
|
|
101
|
-
default="
|
|
101
|
+
default="2000/minute",
|
|
102
102
|
description="The number of requests from a single IP address allowed to hit an endpoint within a rolling 60 second period.",
|
|
103
103
|
)
|
|
104
|
+
auth_rate_limit: str = Field(
|
|
105
|
+
default="10/minute",
|
|
106
|
+
description="The number of authentication requests from a single IP address allowed to hit authentication endpoints (login, OAuth token) within the specified time period.",
|
|
107
|
+
)
|
|
104
108
|
root_user_scopes: List[str] = Field(
|
|
105
109
|
default=SCOPE_REGISTRY,
|
|
106
110
|
description="The list of scopes that are given to the root user.",
|
|
@@ -213,13 +217,31 @@ class SecuritySettings(FidesSettings):
|
|
|
213
217
|
oauth_root_client_secret_hash = (hashed_client_id, salt.encode(encoding)) # type: ignore
|
|
214
218
|
return oauth_root_client_secret_hash
|
|
215
219
|
|
|
216
|
-
@field_validator("
|
|
220
|
+
@field_validator("rate_limit_client_ip_header")
|
|
221
|
+
@classmethod
|
|
222
|
+
def validate_rate_limit_client_ip_header(
|
|
223
|
+
cls,
|
|
224
|
+
v: str,
|
|
225
|
+
) -> Optional[str]:
|
|
226
|
+
"""Validate supported `rate_limit_client_ip_header`"""
|
|
227
|
+
insecure_headers = ["x-forwarded-for"]
|
|
228
|
+
|
|
229
|
+
if not v:
|
|
230
|
+
return None
|
|
231
|
+
|
|
232
|
+
if v.lower() in insecure_headers:
|
|
233
|
+
raise ValueError(
|
|
234
|
+
"The rate_limit_client_ip_header cannot be set to a header that is not secure."
|
|
235
|
+
)
|
|
236
|
+
return v
|
|
237
|
+
|
|
238
|
+
@field_validator("request_rate_limit", "auth_rate_limit")
|
|
217
239
|
@classmethod
|
|
218
|
-
def
|
|
240
|
+
def validate_rate_limits(
|
|
219
241
|
cls,
|
|
220
242
|
v: str,
|
|
221
243
|
) -> str:
|
|
222
|
-
"""Validate the formatting of
|
|
244
|
+
"""Validate the formatting of rate limit fields"""
|
|
223
245
|
try:
|
|
224
246
|
# Defer to `limits.parse_many` https://limits.readthedocs.io/en/stable/api.html#limits.parse_many
|
|
225
247
|
parse_many(v)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link data-next-font="" rel="preconnect" href="/" crossorigin="anonymous"/><link rel="preload" href="/_next/static/css/650df9c348000a26.css" as="style"/><link rel="stylesheet" href="/_next/static/css/650df9c348000a26.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-678e89d68dbcd94f.js" defer=""></script><script src="/_next/static/chunks/framework-c92fc3344e6fd165.js" defer=""></script><script src="/_next/static/chunks/main-090643377c8254e6.js" defer=""></script><script src="/_next/static/chunks/pages/_app-
|
|
1
|
+
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link data-next-font="" rel="preconnect" href="/" crossorigin="anonymous"/><link rel="preload" href="/_next/static/css/650df9c348000a26.css" as="style"/><link rel="stylesheet" href="/_next/static/css/650df9c348000a26.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-678e89d68dbcd94f.js" defer=""></script><script src="/_next/static/chunks/framework-c92fc3344e6fd165.js" defer=""></script><script src="/_next/static/chunks/main-090643377c8254e6.js" defer=""></script><script src="/_next/static/chunks/pages/_app-fcdad91f6f66292b.js" defer=""></script><script src="/_next/static/chunks/pages/404-471a6b18e712f050.js" defer=""></script><script src="/_next/static/1TigfgzjzHeoVqRLNIMYa/_buildManifest.js" defer=""></script><script src="/_next/static/1TigfgzjzHeoVqRLNIMYa/_ssgManifest.js" defer=""></script><style>.data-ant-cssinjs-cache-path{content:"";}</style></head><body><div id="__next"><div style="height:100%;display:flex"></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/404","query":{},"buildId":"1TigfgzjzHeoVqRLNIMYa","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
self.__BUILD_MANIFEST=function(s,e,t,a,c,n,i,d,o,r,p,u,g,f,m,b,j,k,h,y,l,v,I,F,x,_,U,q,w,N,A,S,B,C,z,D,E,L,M,T,P,G,H,J,K,O,Q,R){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/":[F,"static/chunks/pages/index-6cd8708106331b8d.js"],"/404":["static/chunks/pages/404-471a6b18e712f050.js"],"/_error":["static/chunks/pages/_error-bede3a8288930dcf.js"],"/add-systems":[s,e,F,"static/chunks/pages/add-systems-bd0d82078e67cac3.js"],"/add-systems/manual":[s,t,a,c,n,g,e,d,f,m,h,x,_,"static/chunks/pages/add-systems/manual-ace203dfacacbdc4.js"],"/add-systems/multiple":[d,b,U,"static/chunks/pages/add-systems/multiple-920fb469e0dda1d2.js"],"/consent":["static/chunks/pages/consent-3e8bdefe714254ec.js"],"/consent/configure":[d,b,"static/chunks/pages/consent/configure-7207ab23bdb36ce8.js"],"/consent/configure/add-vendors":[d,b,U,"static/chunks/pages/consent/configure/add-vendors-406170eaae4329c6.js"],"/consent/privacy-experience":[g,q,"static/chunks/pages/consent/privacy-experience-9dda4de5ec580279.js"],"/consent/privacy-experience/new":[t,o,j,k,w,"static/chunks/pages/consent/privacy-experience/new-e74cb5ea87f15b40.js"],"/consent/privacy-experience/[id]":[t,o,j,k,w,"static/chunks/pages/consent/privacy-experience/[id]-f80cf2d3966816fd.js"],"/consent/privacy-notices":[q,"static/chunks/pages/consent/privacy-notices-0d4844d0b808e6e4.js"],"/consent/privacy-notices/new":[t,o,j,k,N,"static/chunks/pages/consent/privacy-notices/new-2ca1de7b88094ab0.js"],"/consent/privacy-notices/[id]":[t,o,j,k,N,"static/chunks/pages/consent/privacy-notices/[id]-b378576cba255609.js"],"/consent/properties":[A,"static/chunks/pages/consent/properties-226efa1dcd41437f.js"],"/consent/reporting":[s,"static/chunks/2150-930ffaf2c4718edc.js","static/chunks/pages/consent/reporting-28b192e2c074b0f3.js"],"/data-catalog":[t,a,c,"static/css/95ac327e5d70148d.css","static/chunks/pages/data-catalog-30108b00ac769fc3.js"],"/data-catalog/[systemId]/projects":[t,a,c,p,y,i,"static/chunks/pages/data-catalog/[systemId]/projects-5f2d7b24804f861f.js"],"/data-catalog/[systemId]/projects/[projectUrn]":[S,"static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]-04cfe2cfba7b7cd8.js"],"/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn]":[s,t,a,c,e,p,y,B,i,"static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn]-2c29ff7a01198f30.js"],"/data-catalog/[systemId]/resources":[S,"static/chunks/pages/data-catalog/[systemId]/resources-de704de849960f01.js"],"/data-catalog/[systemId]/resources/[resourceUrn]":[s,t,a,c,e,p,y,B,i,"static/chunks/pages/data-catalog/[systemId]/resources/[resourceUrn]-8eb581024bc0172f.js"],"/data-discovery/action-center":["static/chunks/pages/data-discovery/action-center-9a81d42a474e1e48.js"],"/data-discovery/action-center/[monitorId]":[s,t,a,c,e,C,l,"static/chunks/pages/data-discovery/action-center/[monitorId]-6d133580045abdda.js"],"/data-discovery/action-center/[monitorId]/[systemId]":[s,t,a,c,e,d,h,C,"static/css/23cf870196941c9a.css","static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-e1ba213fb666b3f4.js"],"/data-discovery/activity":[s,e,u,"static/chunks/pages/data-discovery/activity-b6ae7adb8ef0b525.js"],"/data-discovery/detection":[s,e,u,z,"static/chunks/pages/data-discovery/detection-eb814e3c22807871.js"],"/data-discovery/detection/[resourceUrn]":[s,e,u,z,"static/chunks/pages/data-discovery/detection/[resourceUrn]-8f736b078e9842da.js"],"/data-discovery/discovery":[s,t,a,c,e,u,p,D,i,"static/chunks/pages/data-discovery/discovery-172dbd7740e212ca.js"],"/data-discovery/discovery/[resourceUrn]":[s,t,a,c,e,u,p,D,i,"static/chunks/pages/data-discovery/discovery/[resourceUrn]-6875b7783fcfda2f.js"],"/datamap":[s,c,"static/chunks/255-1bc0cbef7a59cdc6.js",e,f,E,"static/chunks/pages/datamap-c7390e046b2e2b7f.js"],"/dataset":[r,"static/chunks/pages/dataset-7c59a6abf6ba6207.js"],"/dataset/new":[s,r,e,"static/chunks/pages/dataset/new-e32fccc4ca520d2b.js"],"/dataset/[datasetId]":["static/chunks/9729-fcf6ff4e3534e4a8.js",v,"static/chunks/pages/dataset/[datasetId]-e12b11ba15bc3fc1.js"],"/dataset/[datasetId]/[collectionName]":[t,a,c,n,v,L,i,"static/chunks/pages/dataset/[datasetId]/[collectionName]-7cdc42ec5493b83d.js"],"/dataset/[datasetId]/[collectionName]/[...subfieldNames]":[t,a,c,n,v,L,i,"static/chunks/pages/dataset/[datasetId]/[collectionName]/[...subfieldNames]-dfd71c1e9c458b89.js"],"/datastore-connection":["static/css/5f393dea1c0d031c.css","static/chunks/pages/datastore-connection-cce20440b177050b.js"],"/datastore-connection/new":[s,t,n,r,g,M,e,T,"static/chunks/pages/datastore-connection/new-cbe100d50df34285.js"],"/datastore-connection/[id]":[s,t,n,r,M,e,T,"static/chunks/pages/datastore-connection/[id]-927b7e476c4b47d0.js"],"/fides-js-docs":["static/chunks/2fbcc6de-a6c61724c327e9fa.js","static/chunks/e3251fe7-5777b5d778e6fffa.js",t,a,c,n,r,"static/chunks/5619-9b50cec521203989.js",P,"static/css/0b4b1b65cc874774.css","static/chunks/5596-bb601cbf40e47a0f.js","static/chunks/pages/fides-js-docs-1f4335dca5c09860.js"],"/integrations":[s,t,a,c,n,o,G,e,m,H,i,"static/chunks/pages/integrations-95402b5001c07ef2.js"],"/integrations/[id]":[s,t,a,c,n,o,G,e,m,H,i,"static/chunks/pages/integrations/[id]-4c3c413a2668df53.js"],"/login":["static/chunks/pages/login-0cb0eb44bf2dd24c.js"],"/login/[provider]":["static/chunks/pages/login/[provider]-c58beef131c3a82d.js"],"/messaging":[t,a,"static/chunks/346-aa3b88efb85f2e28.js","static/chunks/pages/messaging-76b204c9b98d656f.js"],"/messaging/add-template":[J,"static/chunks/pages/messaging/add-template-4a6d4023a7791be8.js"],"/messaging/[id]":[J,"static/chunks/pages/messaging/[id]-3c6dc2f6e6bae960.js"],"/poc/ant-components":["static/chunks/pages/poc/ant-components-bc0e2adf6e0d3ac7.js"],"/poc/form-experiments/AntForm":["static/chunks/pages/poc/form-experiments/AntForm-86ffcc1ad3fa912e.js"],"/poc/form-experiments/FormikAntFormItem":["static/chunks/pages/poc/form-experiments/FormikAntFormItem-ec04f595465bdf69.js"],"/poc/form-experiments/FormikControlled":["static/chunks/pages/poc/form-experiments/FormikControlled-41d309754ff0c1de.js"],"/poc/form-experiments/FormikField":["static/chunks/pages/poc/form-experiments/FormikField-cab1f78cec7808f9.js"],"/poc/form-experiments/FormikSpreadField":[K,"static/chunks/pages/poc/form-experiments/FormikSpreadField-af097d661f6abcf4.js"],"/poc/forms":[K,"static/chunks/pages/poc/forms-eb6058221403b156.js"],"/poc/table-migration":[d,b,"static/chunks/pages/poc/table-migration-48500551fd6a7602.js"],"/privacy-requests":[s,t,"static/chunks/3550-d04125c828d591a1.js",e,"static/chunks/pages/privacy-requests-baf31c3e4b081046.js"],"/privacy-requests/configure":["static/chunks/pages/privacy-requests/configure-d83e5bd52a638234.js"],"/privacy-requests/configure/messaging":[s,e,"static/chunks/pages/privacy-requests/configure/messaging-ad6ad3e5bd72765d.js"],"/privacy-requests/configure/storage":[s,e,"static/chunks/pages/privacy-requests/configure/storage-6032d82f0fc2893d.js"],"/privacy-requests/[id]":[s,e,"static/css/073713cd1eddda79.css","static/chunks/pages/privacy-requests/[id]-0f25a76dd18c5e20.js"],"/properties":[A,"static/chunks/pages/properties-da734840e4f9d04b.js"],"/properties/add-property":[O,"static/chunks/pages/properties/add-property-0a7a2db148a7561a.js"],"/properties/[id]":[O,"static/chunks/pages/properties/[id]-e784c05d056b2371.js"],"/reporting/datamap":[s,t,a,c,P,e,f,E,"static/chunks/pages/reporting/datamap-6903f42a0412bfa6.js"],"/settings/about":["static/chunks/pages/settings/about-d06fb16487705b9d.js"],"/settings/about/alpha":["static/chunks/pages/settings/about/alpha-a82f3df840d5c1b5.js"],"/settings/consent":["static/chunks/pages/settings/consent-93a978443bf299db.js"],"/settings/consent/[configuration_id]/[purpose_id]":["static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-9495e2eb506606c7.js"],"/settings/custom-fields":[s,e,"static/chunks/pages/settings/custom-fields-9ecb803099082bf4.js"],"/settings/domain-records":["static/chunks/pages/settings/domain-records-16fdd91a81074dd1.js"],"/settings/domains":["static/chunks/pages/settings/domains-4cdd6001e7cb9aee.js"],"/settings/email-templates":["static/chunks/pages/settings/email-templates-1914de830ce5cfc4.js"],"/settings/locations":[Q,l,"static/chunks/pages/settings/locations-2e635dcd11b78224.js"],"/settings/organization":["static/chunks/pages/settings/organization-f547f1f33c12faf3.js"],"/settings/privacy-requests":[s,e,"static/chunks/pages/settings/privacy-requests-2ecc073f41628f62.js"],"/settings/regulations":[Q,l,"static/chunks/pages/settings/regulations-7c02e469d8c5bd74.js"],"/systems":["static/chunks/pages/systems-fbc8761ef4d55516.js"],"/systems/configure/[id]":[s,t,a,c,n,g,e,d,f,m,h,x,_,"static/chunks/pages/systems/configure/[id]-6e15332935f6b538.js"],"/systems/configure/[id]/test-datasets":[r,"static/chunks/pages/systems/configure/[id]/test-datasets-20b1193ed76c56b0.js"],"/taxonomy":["static/chunks/678d4732-50255cc09048e643.js",s,t,a,o,"static/chunks/6148-59a59d5c5925344f.js",e,"static/css/34a7eb08b86ddb57.css","static/chunks/pages/taxonomy-4d7827fc9c46b6b8.js"],"/user-management":[I,"static/chunks/pages/user-management-9cec020f89544426.js"],"/user-management/new":[I,R,"static/chunks/pages/user-management/new-92f52c43f522a350.js"],"/user-management/profile/[id]":[I,R,"static/chunks/pages/user-management/profile/[id]-64452dfae2c5e614.js"],sortedPages:["/","/404","/_app","/_error","/add-systems","/add-systems/manual","/add-systems/multiple","/consent","/consent/configure","/consent/configure/add-vendors","/consent/privacy-experience","/consent/privacy-experience/new","/consent/privacy-experience/[id]","/consent/privacy-notices","/consent/privacy-notices/new","/consent/privacy-notices/[id]","/consent/properties","/consent/reporting","/data-catalog","/data-catalog/[systemId]/projects","/data-catalog/[systemId]/projects/[projectUrn]","/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn]","/data-catalog/[systemId]/resources","/data-catalog/[systemId]/resources/[resourceUrn]","/data-discovery/action-center","/data-discovery/action-center/[monitorId]","/data-discovery/action-center/[monitorId]/[systemId]","/data-discovery/activity","/data-discovery/detection","/data-discovery/detection/[resourceUrn]","/data-discovery/discovery","/data-discovery/discovery/[resourceUrn]","/datamap","/dataset","/dataset/new","/dataset/[datasetId]","/dataset/[datasetId]/[collectionName]","/dataset/[datasetId]/[collectionName]/[...subfieldNames]","/datastore-connection","/datastore-connection/new","/datastore-connection/[id]","/fides-js-docs","/integrations","/integrations/[id]","/login","/login/[provider]","/messaging","/messaging/add-template","/messaging/[id]","/poc/ant-components","/poc/form-experiments/AntForm","/poc/form-experiments/FormikAntFormItem","/poc/form-experiments/FormikControlled","/poc/form-experiments/FormikField","/poc/form-experiments/FormikSpreadField","/poc/forms","/poc/table-migration","/privacy-requests","/privacy-requests/configure","/privacy-requests/configure/messaging","/privacy-requests/configure/storage","/privacy-requests/[id]","/properties","/properties/add-property","/properties/[id]","/reporting/datamap","/settings/about","/settings/about/alpha","/settings/consent","/settings/consent/[configuration_id]/[purpose_id]","/settings/custom-fields","/settings/domain-records","/settings/domains","/settings/email-templates","/settings/locations","/settings/organization","/settings/privacy-requests","/settings/regulations","/systems","/systems/configure/[id]","/systems/configure/[id]/test-datasets","/taxonomy","/user-management","/user-management/new","/user-management/profile/[id]"]}}("static/chunks/431-86ad2beeb93c95c9.js","static/chunks/4164-355644b916ae0094.js","static/chunks/8765-f622a35b40a7ec63.js","static/chunks/9278-08cc704317fe535e.js","static/chunks/5163-e682273cd76a7d07.js","static/chunks/699-8ca44b0de9fa20f0.js","static/css/d2d4e9a6923e6730.css","static/chunks/401-4af0a912e249d30f.js","static/chunks/3662-f6a1ddca5ee42076.js","static/chunks/6527-0eed08abe252a918.js","static/chunks/1099-79646e64f26d62fa.js","static/chunks/8002-24af20d679efc04e.js","static/chunks/5277-e8a036319456127f.js","static/chunks/9951-a88367a129b724ba.js","static/chunks/4808-dd4157aa72648068.js","static/chunks/3923-bb2417b8dcade7a4.js","static/chunks/6419-d0c00d661b01f8fa.js","static/chunks/6084-c153669d5567e242.js","static/chunks/4844-46324c3d848b8b6a.js","static/chunks/3620-602eb74dc896d556.js","static/css/10994e916bc9a00a.css","static/chunks/5487-02d00bad7c6830e0.js","static/chunks/7476-45c5088baa8b66af.js","static/css/972dc7eef106ee7c.css","static/chunks/4786-61154adf88e448e1.js","static/css/304c6f148886a8d4.css","static/chunks/796-9e1ca1a4030707c5.js","static/chunks/6853-b17673391117c976.js","static/chunks/1817-0ca16d288fad916d.js","static/chunks/6954-5296188c19d7d0ac.js","static/chunks/79-65674011d455af4d.js","static/chunks/3872-f78dec02f0d959ae.js","static/chunks/3855-ef5194cdb228beb6.js","static/chunks/3847-230bf61b053bc706.js","static/chunks/1345-5e1c5b66e25c566e.js","static/chunks/9046-712156d461165f56.js","static/chunks/5258-b0de22a8521686ab.js","static/chunks/549-38ea1d91ee2addaa.js","static/chunks/1467-8808ec8836e033f9.js","static/chunks/4608-be8cba73f5d7c326.js","static/chunks/9187-7438242f0d380bb0.js","static/chunks/1316-2606e19807c08aa5.js","static/chunks/3729-c17ac8031a4c4fd1.js","static/chunks/7630-7ed6c6117775dffe.js","static/chunks/2921-52328140bc420d0f.js","static/chunks/787-a8c7eab617e2fceb.js","static/chunks/9826-dbae8dee941a7fac.js","static/chunks/4831-fd99c0b3784de128.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[4831],{74831:function(e,s,a){a.d(s,{Z:function(){return et}});var t=a(24246),n=a(96306),l=a(91437),i=()=>(0,t.jsxs)(n.xuv,{children:[(0,t.jsx)(n.xuv,{pb:4,fontSize:"18px",fontWeight:"semibold",children:"Role Description"}),(0,t.jsx)(n.gCW,{spacing:4,children:l.K.map(e=>(0,t.jsxs)(n.xuv,{width:"100%",padding:4,borderRadius:"md",backgroundColor:"gray.75",fontSize:"14px",children:[(0,t.jsx)(n.xuv,{fontWeight:"semibold",children:e.label}),(0,t.jsx)(n.xuv,{color:"gray.700",children:e.description})]},e.roleKey))})]}),r=a(16134),d=a(54682),o=a(19904),c=a(34090),h=a(86677),u=a(27378),m=a(812),p=a(46238),x=a(58452),j=a(77830),w=a(46628),g=a(26917),b=a(1315),f=a(95492),y=a(65497);let v=e=>{let{assignedSystems:s,onAssignedSystemChange:a}=e,l=(0,r.C)(y.Ux);if((0,y.d6)(l,{skip:!l}),0===s.length)return null;let i=e=>{a(s.filter(s=>s.fides_key!==e.fides_key))};return(0,t.jsxs)(n.iA_,{size:"sm","data-testid":"assign-systems-delete-table",children:[(0,t.jsx)(n.hrZ,{children:(0,t.jsxs)(n.Tr,{children:[(0,t.jsx)(n.Th,{children:"System"}),(0,t.jsx)(n.Th,{})]})}),(0,t.jsx)(n.p3B,{children:s.map(e=>(0,t.jsxs)(n.Tr,{_hover:{bg:"gray.50"},"data-testid":"row-".concat(e.fides_key),children:[(0,t.jsx)(n.Td,{children:e.name}),(0,t.jsx)(n.Td,{textAlign:"end",children:(0,t.jsx)(n.wpx,{"aria-label":"Unassign system from user",icon:(0,t.jsx)(f.l,{}),onClick:()=>i(e),"data-testid":"unassign-btn"})})]},e.fides_key))})]})};var _=e=>{let{allSystems:s,assignedSystems:a,onChange:l}=e,i=e=>{a.find(s=>s.fides_key===e.fides_key)?l(a.filter(s=>s.fides_key!==e.fides_key)):l([...a,e])};return(0,t.jsx)(n.xuv,{overflowY:"auto",maxHeight:"300px",children:(0,t.jsxs)(n.iA_,{size:"sm","data-testid":"assign-systems-table",maxHeight:"50vh",overflowY:"scroll",children:[(0,t.jsx)(n.hrZ,{position:"sticky",top:0,background:"white",zIndex:1,children:(0,t.jsxs)(n.Tr,{children:[(0,t.jsx)(n.Th,{children:"System"}),(0,t.jsx)(n.Th,{children:"Assign"})]})}),(0,t.jsx)(n.p3B,{children:s.map(e=>{let s=!!a.find(s=>s.fides_key===e.fides_key);return(0,t.jsxs)(n.Tr,{_hover:{bg:"gray.50"},"data-testid":"row-".concat(e.fides_key),children:[(0,t.jsx)(n.Td,{children:e.name}),(0,t.jsx)(n.Td,{children:(0,t.jsx)(n.rAg,{checked:s,onChange:()=>i(e),"data-testid":"assign-switch"})})]},e.fides_key)})})]})})};let C=(e,s)=>{var a,t;return(null===(a=e.name)||void 0===a?void 0:a.toLocaleLowerCase().includes(s.toLocaleLowerCase()))||(null===(t=e.description)||void 0===t?void 0:t.toLocaleLowerCase().includes(s.toLocaleLowerCase()))};var S=e=>{let{isOpen:s,onClose:a,assignedSystems:l,onAssignedSystemChange:i}=e,{data:r}=(0,b.K3)(),[d,o]=(0,u.useState)(""),[c,h]=(0,u.useState)(l),m=async()=>{i(c),a()},p=!r||0===r.length,x=(0,u.useMemo)(()=>r?r.filter(e=>C(e,d)):[],[r,d]),j=(0,u.useMemo)(()=>{let e=new Set(c.map(e=>e.fides_key));return x.every(s=>e.has(s.fides_key))},[x,c]);return(0,t.jsxs)(n.u_l,{isOpen:s,onClose:a,size:"2xl",children:[(0,t.jsx)(n.ZAr,{}),(0,t.jsxs)(n.hzk,{p:8,"data-testid":"confirmation-modal",children:[(0,t.jsxs)(n.xBx,{fontWeight:"medium",display:"flex",justifyContent:"space-between",alignItems:"center",children:[(0,t.jsx)(n.xvT,{children:"Assign systems"}),(0,t.jsxs)(n.j8w,{color:"success",children:["Assigned to ",l.length," systems"]})]}),(0,t.jsx)(n.fef,{"data-testid":"assign-systems-modal-body",children:p?(0,t.jsx)(n.xvT,{children:"No systems found"}):(0,t.jsxs)(n.Kqy,{spacing:4,children:[(0,t.jsxs)(n.kCb,{justifyContent:"space-between",children:[(0,t.jsx)(n.xvT,{fontSize:"sm",flexGrow:1,fontWeight:"medium",children:"Assign systems in your organization to this user"}),(0,t.jsx)(n.xuv,{children:(0,t.jsxs)(n.NIc,{display:"flex",alignItems:"center",children:[(0,t.jsx)(n.lXp,{fontSize:"sm",htmlFor:"assign-all-systems",mb:"0",children:"Assign all systems"}),(0,t.jsx)(n.rAg,{size:"small",id:"assign-all-systems",checked:j,onChange:e=>{e&&r?h(x):h(r?r.filter(e=>!x.includes(e)):[])},"data-testid":"assign-all-systems-toggle"})]})})]}),(0,t.jsx)(g.Z,{value:d,onChange:o,placeholder:"Search for systems","data-testid":"system-search",withIcon:!0}),(0,t.jsx)(_,{allSystems:x,assignedSystems:c,onChange:h})]})}),(0,t.jsx)(n.mzw,{justifyContent:"flex-start",children:(0,t.jsxs)("div",{children:[(0,t.jsx)(n.wpx,{onClick:a,className:"mr-2","data-testid":"cancel-btn",children:"Cancel"}),p?null:(0,t.jsx)(n.wpx,{type:"primary",onClick:m,"data-testid":"confirm-btn",children:"Confirm"})]})})]})]})},k=e=>{let{label:s,roleKey:a,isSelected:l,isDisabled:i,assignedSystems:r,onAssignedSystemChange:o}=e,{setFieldValue:h}=(0,c.u6)(),u=(0,n.qY0)(),m=i?"You do not have sufficient permissions to assign this role.":void 0;return l?(0,t.jsxs)(n.Kqy,{borderRadius:"md",border:"1px solid",borderColor:"gray.200",p:4,backgroundColor:"gray.50","aria-selected":"true",spacing:4,"data-testid":"selected",children:[(0,t.jsxs)(n.kCb,{alignItems:"center",justifyContent:"space-between",children:[(0,t.jsx)(n.xvT,{fontSize:"md",fontWeight:"semibold",children:s}),(0,t.jsx)(n.StI,{})]}),a!==d.A7.APPROVER&&a!==d.A7.RESPONDENT&&a!==d.A7.EXTERNAL_RESPONDENT?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.kCb,{alignItems:"center",children:[(0,t.jsx)(n.xvT,{fontSize:"sm",fontWeight:"semibold",mr:1,children:"Assigned systems"}),(0,t.jsx)(p.b,{label:"Assigned systems refer to those systems that have been specifically allocated to a user for management purposes. Users assigned to a system possess full edit permissions and are listed as the Data Steward for the respective system."})]}),(0,t.jsx)(n.wpx,{disabled:i,title:m,type:"primary",size:"small",onClick:u.onOpen,"data-testid":"assign-systems-btn",children:"Assign systems +"}),(0,t.jsx)(v,{assignedSystems:r,onAssignedSystemChange:o}),u.isOpen?(0,t.jsx)(S,{isOpen:u.isOpen,onClose:u.onClose,assignedSystems:r,onAssignedSystemChange:o}):null]}):null]}):(0,t.jsx)(n.wpx,{onClick:()=>{h("roles",[a])},"data-testid":"role-option-".concat(s),title:m,disabled:i,children:s})};let E={roles:[]};var R=()=>{var e,s;let a=(0,n.pmc)(),i=(0,h.useRouter)(),g=(0,r.C)(y.Ux);(0,y.d6)(g,{skip:!g});let{isOpen:b,onOpen:f,onClose:v}=(0,n.qY0)(),_=(0,r.C)(y.R$),[C,S]=(0,u.useState)(_),[R]=(0,y.G$)();(0,u.useEffect)(()=>{S(_)},[_]);let{data:A,isLoading:T}=(0,y.gU)(null!=g?g:"",{skip:!g}),[P]=(0,y.lD)(),N=!!(null==A?void 0:null===(e=A.roles)||void 0===e?void 0:e.includes(d.A7.EXTERNAL_RESPONDENT)),O=async e=>{if(b&&v(),!g)return;let s=e.roles.includes(d.A7.APPROVER),t=await P({user_id:g,payload:{roles:e.roles}});if((0,m.D4)(t)){a((0,w.Vo)((0,m.e$)(t.error)));return}if(!s){let e=C.map(e=>e.fides_key),s=await R({userId:g,fidesKeys:e});if((0,m.D4)(s)){a((0,w.Vo)((0,m.e$)(s.error)));return}}a((0,w.t5)("Permissions updated"))},I=async e=>{g&&(C.length>0&&e.roles.includes(d.A7.APPROVER)?f():await O(e))},z=(0,o.Tg)([d.Sh.USER_PERMISSION_ASSIGN_OWNERS]);if(!g)return null;if(T)return(0,t.jsx)(n.$jN,{});if(!z&&(null==A?void 0:null===(s=A.roles)||void 0===s?void 0:s.includes(d.A7.OWNER)))return(0,t.jsx)(n.xvT,{"data-testid":"insufficient-access",children:"You do not have sufficient access to change this user's permissions."});let q=(null==A?void 0:A.roles)?{roles:A.roles}:E,U=l.K.filter(e=>N?e.roleKey===d.A7.EXTERNAL_RESPONDENT:e.roleKey!==d.A7.EXTERNAL_RESPONDENT),D=N?"External respondent role cannot be changed":void 0;return(0,t.jsx)(c.J9,{onSubmit:I,initialValues:q,enableReinitialize:!0,children:e=>{let{values:s,isSubmitting:a,dirty:l}=e;return(0,t.jsxs)(c.l0,{children:[(0,t.jsxs)(n.Kqy,{spacing:7,children:[(0,t.jsxs)(n.Kqy,{spacing:3,"data-testid":"role-options",children:[(0,t.jsxs)(n.kCb,{alignItems:"center",children:[(0,t.jsx)(n.xvT,{fontSize:"sm",fontWeight:"semibold",mr:1,children:"User role"}),(0,t.jsx)(p.b,{label:"A user's role in the organization determines what parts of the UI they can access and which functions are available to them."})]}),U.map(e=>{let a=s.roles.indexOf(e.roleKey)>=0,n=e.roleKey===d.A7.OWNER?!z:N;return(0,t.jsx)(k,{isSelected:a,isDisabled:n,assignedSystems:C,onAssignedSystemChange:S,...e},e.roleKey)}),!N&&(0,t.jsx)(n.esZ,{title:"To invite a new External respondent user, create a manual task integration and then click on the 'Manage secure access' button",children:(0,t.jsx)(n.wpx,{disabled:!0,"data-testid":"role-option-External respondent",children:"External respondent"})})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(n.wpx,{onClick:()=>i.push(j.e3),children:"Cancel"}),(0,t.jsx)(n.esZ,{title:D,children:(0,t.jsx)(n.wpx,{className:"ml-2",type:"primary",htmlType:"submit",loading:a,disabled:!l&&C===_||N,"data-testid":"save-btn",children:"Save"})})]})]}),(0,t.jsx)(x.Z,{isOpen:b,onClose:v,onConfirm:()=>O(s),title:"Change role to Approver",testId:"downgrade-to-approver-confirmation-modal",continueButtonText:"Yes",message:(0,t.jsx)(n.xvT,{children:"Switching to an approver role will remove all assigned systems. Do you wish to proceed?"})})]})}})},A=a(61038),T=a(55484),P=a(25980),N=a(40324),O=a(96006),I=a(7426);let{useGetEmailInviteStatusQuery:z}=a(78780).u.injectEndpoints({endpoints:e=>({getEmailInviteStatus:e.query({query:()=>({url:"/messaging/email-invite/status"}),providesTags:()=>["Email Invite Status"]})})});var q=a(76174),U=a(91317),D=a(16125),Z=a(36835),W=a(31883),K=a(52253);let L=(e,s,a)=>{var t;try{localStorage.removeItem(K.xH)}catch(e){}e((0,Z.kS)()),null==a||null===(t=a.onClose)||void 0===t||t.call(a),s.push(K._e)},V=T.Ry().shape({password:O.a.label("Password"),passwordConfirmation:T.Z_().required().oneOf([T.iH("password")],"Passwords must match").label("Password confirmation")}),B={password:"",passwordConfirmation:""},Y=e=>{let s=(0,n.qY0)(),a=(0,n.pmc)(),[t]=(0,y.ls)(),l=(0,h.useRouter)(),i=(0,D.I0)(),d=(0,r.C)(Z.dy),o=async n=>{let r=await t({id:e,new_password:n.password});(0,W.D4)(r)?a((0,w.Vo)((0,m.e$)(r.error))):(a((0,w.t5)("Successfully reset user's password. Please inform the user of their new password.")),s.onClose(),(null==d?void 0:d.id)===e&&L(i,l))};return{...s,handleResetPassword:o}};var F=e=>{let{id:s}=e,{handleResetPassword:a,isOpen:l,onClose:i,onOpen:r}=Y(s);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.wpx,{onClick:r,"data-testid":"reset-password-btn",children:"Reset password"}),(0,t.jsxs)(n.u_l,{isCentered:!0,isOpen:l,onClose:i,children:[(0,t.jsx)(n.ZAr,{}),(0,t.jsx)(n.hzk,{children:(0,t.jsx)(c.J9,{initialValues:B,validationSchema:V,onSubmit:a,children:e=>{let{isSubmitting:s,dirty:a,isValid:l}=e;return(0,t.jsxs)(c.l0,{children:[(0,t.jsx)(n.xBx,{children:"Reset Password"}),(0,t.jsx)(n.olH,{}),(0,t.jsx)(n.fef,{children:(0,t.jsxs)(n.Kqy,{direction:"column",spacing:4,children:[(0,t.jsx)(n.xvT,{mb:2,children:"Choose a new password for this user."}),(0,t.jsx)(N.j0,{name:"password",label:"Password",placeholder:"********",type:"password",tooltip:"Password must contain at least 8 characters, 1 number, 1 capital letter, 1 lowercase letter, and at least 1 symbol.",autoComplete:"new-password"}),(0,t.jsx)(N.j0,{name:"passwordConfirmation",label:"Confirm Password",placeholder:"********",type:"password",tooltip:"Must match above password.",autoComplete:"confirm-password"})]})}),(0,t.jsx)(n.mzw,{children:(0,t.jsxs)("div",{className:"w-full gap-2",children:[(0,t.jsx)(n.wpx,{onClick:i,className:"w-1/2",children:"Cancel"}),(0,t.jsx)(n.wpx,{type:"primary",disabled:!a||!l,loading:s,htmlType:"submit",className:"w-1/2","data-testid":"submit-btn",children:"Change Password"})]})})]})}})})]})]})};let $=e=>{let s=(0,n.qY0)(),a=(0,n.pmc)(),[t,l]=(0,u.useState)(""),[i,r]=(0,u.useState)(""),[d,{isLoading:o}]=(0,y.ev)(),c=(0,h.useRouter)(),m=(0,D.I0)(),p=!!(e&&i&&t),x=async()=>{p&&d({id:e,old_password:t,new_password:i}).unwrap().then(()=>{a((0,w.t5)("Password updated")),L(m,c,{onClose:s.onClose})})};return{...s,changePasswordValidation:p,handleChange:e=>{"oldPassword"===e.target.name?l(e.target.value):r(e.target.value)},handleChangePassword:x,isLoading:o,newPasswordValue:i,oldPasswordValue:t}};var H=e=>{let{id:s}=e,{changePasswordValidation:a,handleChange:l,handleChangePassword:i,isLoading:r,isOpen:d,newPasswordValue:o,oldPasswordValue:c,onClose:h,onOpen:u}=$(s);return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.wpx,{onClick:u,"data-testid":"update-password-btn",children:"Update password"}),(0,t.jsxs)(n.u_l,{isCentered:!0,isOpen:d,onClose:h,children:[(0,t.jsx)(n.ZAr,{}),(0,t.jsxs)(n.hzk,{children:[(0,t.jsx)(n.xBx,{children:"Update Password"}),(0,t.jsx)(n.olH,{}),(0,t.jsx)(n.fef,{pb:6,children:(0,t.jsxs)(n.Kqy,{direction:"column",spacing:"15px",children:[(0,t.jsx)(n.NIc,{children:(0,t.jsx)(n.IIB,{isRequired:!0,name:"oldPassword",onChange:l,placeholder:"Old Password",type:"password",value:c,"data-testid":"input-oldPassword"})}),(0,t.jsx)(n.NIc,{children:(0,t.jsx)(n.IIB,{isRequired:!0,name:"newPassword",onChange:l,placeholder:"New Password",type:"password",value:o,"data-testid":"input-newPassword"})})]})}),(0,t.jsxs)(n.mzw,{children:[(0,t.jsx)(n.wpx,{onClick:h,className:"mr-2 w-1/2",children:"Cancel"}),(0,t.jsx)(n.wpx,{type:"primary",disabled:!a,loading:r,onClick:i,htmlType:"submit",className:"mr-3 w-1/2","data-testid":"submit-btn",children:"Change Password"})]})]})]})]})},M=()=>{var e;let s=(0,r.C)(y.Ux),a=(0,r.C)(U.dy),l=!!a&&a.id===s,{data:i}=(0,y.gU)(null!=s?s:"",{skip:!s});return(null==i?void 0:null===(e=i.roles)||void 0===e?void 0:e.includes(d.A7.EXTERNAL_RESPONDENT))?null:(0,t.jsx)(n.xuv,{children:s?(0,t.jsxs)(n.Ugi,{children:[l?(0,t.jsx)(H,{id:s}):null,(0,t.jsx)(o.ZP,{scopes:[d.Sh.USER_PASSWORD_RESET],children:(0,t.jsx)(F,{id:s})})]}):null})};let X=(e,s,a,t)=>!e||e&&!s||e&&s&&!0===a&&!!t,G=(e,s,a)=>!!(e&&s&&a),J=(e,s,a,t,n,l)=>!!e&&!s&&X(a,t,n,l),Q=(e,s,a,t)=>X(e,s,a,t),ee={username:"",first_name:"",email_address:"",last_name:"",password:"",password_login_enabled:!1},es=(e,s,a,t,n)=>T.Ry().shape({username:T.Z_().required().label("Username"),email_address:T.Z_().email().required().label("Email address"),first_name:T.Z_().label("First name"),last_name:T.Z_().label("Last name"),password:T.Z_().when(["password_login_enabled"],{is:l=>J(e,s,a,t,n,l),then:()=>O.a.label("Password"),otherwise:()=>T.Z_().optional().label("Password")}),password_login_enabled:T.O7().label("Allow password login")});var ea=e=>{let{onSubmit:s,initialValues:a,canEditNames:l}=e,i=(0,h.useRouter)(),d=(0,n.pmc)(),o=(0,r.T)(),u=(0,n.qY0)(),{data:p}=z(),{data:x}=(0,q.qv)();(0,I.tB)({api_set:!1});let g=(0,r.C)(y.ZC),b=(0,r.C)(I.iR),{plus:v}=(0,P.hz)(),_=(null==p?void 0:p.enabled)||!1,C=(null==b?void 0:b.allow_username_password_login)||!1,S=!g,k=!S&&!l,E=x&&x.length>0||!1,R=G(v,E,C),T=null!=a?a:ee;g&&"password_login_enabled"in g&&(T={...T,password_login_enabled:!!g.password_login_enabled});let O=es(S,_,v,E,C),U=async e=>{let a=J(S,_,v,E,C,e.password_login_enabled),t={username:e.username,email_address:e.email_address,first_name:e.first_name,last_name:e.last_name};R&&(t.password_login_enabled=e.password_login_enabled),a&&e.password&&(t.password=e.password);let n=await s(t);if((0,m.D4)(n)){d((0,w.Vo)((0,m.e$)(n.error)));return}d((0,w.t5)("".concat(S?"User created. By default, new users are set to the Viewer role. To change the role, please go to the Permissions tab.":"User updated."))),(null==n?void 0:n.data)&&o((0,y.Vv)(n.data.id))};return(0,t.jsx)(c.J9,{onSubmit:U,initialValues:T,validationSchema:O,"data-testid":"user-form",children:e=>{let{dirty:s,isSubmitting:a,isValid:l,values:r}=e;return(0,t.jsx)(c.l0,{children:(0,t.jsxs)(n.Kqy,{maxW:["xs","xs","100%"],width:"100%",spacing:7,children:[(0,t.jsxs)(n.Kqy,{spacing:6,maxWidth:"55%",children:[(0,t.jsxs)(n.kCb,{children:[(0,t.jsxs)(n.xvT,{display:"flex",alignItems:"center",fontSize:"sm",fontWeight:"semibold",children:["Profile"," ",(null==g?void 0:g.disabled)&&(0,t.jsx)(n.j8w,{color:"success",className:"ml-2","data-testid":"invite-sent-badge",children:"Invite sent"})]}),(0,t.jsx)(n.xuv,{marginLeft:"auto",children:(0,t.jsxs)(n.Ugi,{children:[Q(v,E,C||!1,r.password_login_enabled)&&(0,t.jsx)(M,{"data-testid":"password-management"}),S?null:(0,t.jsxs)(n.xuv,{children:[(0,t.jsx)(n.wpx,{"aria-label":"delete",icon:(0,t.jsx)(f.l,{}),onClick:u.onOpen,"data-testid":"delete-user-btn"}),(0,t.jsx)(A.Z,{user:g,...u})]})]})})]}),(0,t.jsx)(N.j0,{name:"username",label:"Username",variant:"block",placeholder:"Enter new username",disabled:!S,isRequired:!0,"data-testid":"input-username"}),(0,t.jsx)(N.j0,{name:"email_address",label:"Email address",variant:"block",placeholder:"Enter email of user",isRequired:!0,"data-testid":"input-email-address"}),(0,t.jsx)(N.j0,{name:"first_name",label:"First name",variant:"block",placeholder:"Enter first name of user",disabled:k,"data-testid":"input-first-name"}),(0,t.jsx)(N.j0,{name:"last_name",label:"Last name",variant:"block",placeholder:"Enter last name of user",disabled:k,"data-testid":"input-last-name"}),R&&(0,t.jsx)(N.w8,{name:"password_login_enabled",label:"Allow password login",tooltip:"When enabled, user can log in with username and password. When disabled, user must use SSO.",variant:"stacked",isDisabled:!S,"data-testid":"toggle-allow-password-login",size:"default"}),J(S,_,v,E,C,r.password_login_enabled)&&(0,t.jsx)(N.j0,{name:"password",label:"Password",variant:"block",placeholder:"********",type:"password",tooltip:"Password must contain at least 8 characters, 1 number, 1 capital letter, 1 lowercase letter, and at least 1 symbol.",isRequired:!0,"data-testid":"input-password"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(n.wpx,{onClick:()=>i.push(j.e3),className:"mr-3","data-testid":"cancel-btn",children:"Cancel"}),(0,t.jsx)(n.wpx,{htmlType:"submit",type:"primary",disabled:!s||!l,loading:a,"data-testid":"save-user-btn",children:"Save"})]})]})})}})},et=e=>{let{onSubmit:s,initialValues:a,...l}=e,c=(0,r.C)(y.Ux);(0,y.Fk)(c,{skip:!c});let h=(0,o.Tg)([d.Sh.USER_PERMISSION_UPDATE]),u=!c||!h,m=[{label:"Profile",key:"profile",children:(0,t.jsx)(ea,{onSubmit:s,initialValues:a,...l})},{label:"Permissions",key:"permissions",children:(0,t.jsxs)(n.kCb,{gap:"97px",children:[(0,t.jsx)(n.xuv,{w:{base:"100%",md:"50%",xl:"50%"},children:(0,t.jsx)(R,{})}),(0,t.jsx)(n.xuv,{position:"absolute",top:"96px",right:6,height:"calc(100% + 100px)",overflowY:"scroll",padding:6,w:"35%",borderLeftWidth:"1px",children:(0,t.jsx)(i,{})})]}),disabled:u,forceRender:!u}];return(0,t.jsx)(n.A5g,{items:m})}},31883:function(e,s,a){a.d(s,{Bw:function(){return t.Bw},D4:function(){return t.D4}});var t=a(19043)}}]);
|