synapse-react-client 4.0.42 → 4.0.43
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.
- package/dist/SWC.index.js +1 -1
- package/dist/components/AccessRequirementList/AccessRequirementList.d.ts +6 -20
- package/dist/components/AccessRequirementList/AccessRequirementList.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/AccessRequirementList.js +165 -159
- package/dist/components/AccessRequirementList/AccessRequirementList.js.map +1 -1
- package/dist/components/AccessRequirementList/AccessRequirementListItem.d.ts +3 -2
- package/dist/components/AccessRequirementList/AccessRequirementListItem.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/AccessRequirementListItem.js +23 -22
- package/dist/components/AccessRequirementList/AccessRequirementListItem.js.map +1 -1
- package/dist/components/AccessRequirementList/AccessRequirementListUtils.d.ts +4 -3
- package/dist/components/AccessRequirementList/AccessRequirementListUtils.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/AccessRequirementListUtils.js +6 -4
- package/dist/components/AccessRequirementList/AccessRequirementListUtils.js.map +1 -1
- package/dist/components/AccessRequirementList/JsonSchemaAccessRequirementRequestFlow/JsonSchemaRequestWizard.d.ts +22 -0
- package/dist/components/AccessRequirementList/JsonSchemaAccessRequirementRequestFlow/JsonSchemaRequestWizard.d.ts.map +1 -0
- package/dist/components/AccessRequirementList/JsonSchemaAccessRequirementRequestFlow/JsonSchemaRequestWizard.js +166 -0
- package/dist/components/AccessRequirementList/JsonSchemaAccessRequirementRequestFlow/JsonSchemaRequestWizard.js.map +1 -0
- package/dist/components/AccessRequirementList/JsonSchemaAccessRequirementRequestFlow/RequesterInformationFields.d.ts +18 -0
- package/dist/components/AccessRequirementList/JsonSchemaAccessRequirementRequestFlow/RequesterInformationFields.d.ts.map +1 -0
- package/dist/components/AccessRequirementList/JsonSchemaAccessRequirementRequestFlow/RequesterInformationFields.js +91 -0
- package/dist/components/AccessRequirementList/JsonSchemaAccessRequirementRequestFlow/RequesterInformationFields.js.map +1 -0
- package/dist/components/AccessRequirementList/JsonSchemaAccessRequirementRequestFlow/requesterInformation.d.ts +33 -0
- package/dist/components/AccessRequirementList/JsonSchemaAccessRequirementRequestFlow/requesterInformation.d.ts.map +1 -0
- package/dist/components/AccessRequirementList/JsonSchemaAccessRequirementRequestFlow/requesterInformation.js +49 -0
- package/dist/components/AccessRequirementList/JsonSchemaAccessRequirementRequestFlow/requesterInformation.js.map +1 -0
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/CancelRequestDataAccess.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/CancelRequestDataAccess.js +26 -42
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/CancelRequestDataAccess.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsFilesForm/DataAccessRequestAccessorsFilesForm.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsFilesForm/DataAccessRequestAccessorsFilesForm.js +140 -155
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsFilesForm/DataAccessRequestAccessorsFilesForm.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/EDucPreviewStep/EDucPreviewStep.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/EDucPreviewStep/EDucPreviewStep.js +43 -60
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/EDucPreviewStep/EDucPreviewStep.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManagedACTAccessRequirementFormWikiWrapper.d.ts +4 -5
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManagedACTAccessRequirementFormWikiWrapper.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManagedACTAccessRequirementFormWikiWrapper.js +5 -5
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManagedACTAccessRequirementFormWikiWrapper.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManualUploadDucStep/ManualUploadDucStep.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManualUploadDucStep/ManualUploadDucStep.js +88 -103
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManualUploadDucStep/ManualUploadDucStep.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/RequestDataAccessSuccess.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/RequestDataAccessSuccess.js +14 -30
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/RequestDataAccessSuccess.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/{ManagedACTAccessRequirementItem.d.ts → RequestableAccessRequirementItem.d.ts} +9 -8
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/RequestableAccessRequirementItem.d.ts.map +1 -0
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/{ManagedACTAccessRequirementItem.js → RequestableAccessRequirementItem.js} +16 -16
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/RequestableAccessRequirementItem.js.map +1 -0
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/{ManagedACTAccessRequirementItemView.d.ts → RequestableAccessRequirementItemView.d.ts} +5 -5
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/RequestableAccessRequirementItemView.d.ts.map +1 -0
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/{ManagedACTAccessRequirementItemView.js → RequestableAccessRequirementItemView.js} +3 -4
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/RequestableAccessRequirementItemView.js.map +1 -0
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ResearchProjectForm/ResearchProjectForm.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ResearchProjectForm/ResearchProjectForm.js +94 -110
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ResearchProjectForm/ResearchProjectForm.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ReviewDucStep/ReviewDucStep.d.ts +0 -2
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ReviewDucStep/ReviewDucStep.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ReviewDucStep/ReviewDucStep.js +35 -52
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ReviewDucStep/ReviewDucStep.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/SignatureStatusStep/SignatureStatusStep.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/SignatureStatusStep/SignatureStatusStep.js +79 -95
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/SignatureStatusStep/SignatureStatusStep.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/requestFlowTypes.d.ts +2 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/requestFlowTypes.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/RequestDataStep.d.ts +34 -0
- package/dist/components/AccessRequirementList/RequestDataStep.d.ts.map +1 -0
- package/dist/components/AccessRequirementList/RequestDataStep.js +37 -0
- package/dist/components/AccessRequirementList/RequestDataStep.js.map +1 -0
- package/dist/components/AccessRequirementList/RequirementItem/UnmanagedACTAccessRequirementItem.d.ts +1 -1
- package/dist/components/AccessRequirementList/RequirementItem/UnmanagedACTAccessRequirementItem.js.map +1 -1
- package/dist/components/FormTemplateEditor/FormTemplatePreview.d.ts.map +1 -1
- package/dist/components/FormTemplateEditor/FormTemplatePreview.js +29 -30
- package/dist/components/FormTemplateEditor/FormTemplatePreview.js.map +1 -1
- package/dist/components/JsonSchemaForm/SchemaStepForm.d.ts +21 -0
- package/dist/components/JsonSchemaForm/SchemaStepForm.d.ts.map +1 -0
- package/dist/components/JsonSchemaForm/SchemaStepForm.js +29 -0
- package/dist/components/JsonSchemaForm/SchemaStepForm.js.map +1 -0
- package/dist/components/SetBasicAccessRequirementFields/GovernanceUtils.d.ts +2 -2
- package/dist/components/SetBasicAccessRequirementFields/GovernanceUtils.d.ts.map +1 -1
- package/dist/components/SetBasicAccessRequirementFields/GovernanceUtils.js +11 -10
- package/dist/components/SetBasicAccessRequirementFields/GovernanceUtils.js.map +1 -1
- package/dist/components/SynapseForm/SynapseForm.js +28 -28
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.d.ts.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.js +5 -4
- package/dist/components/dataaccess/UserAccessRequestHistory/InFlightEDucSignaturesTable.js.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPlace.d.ts.map +1 -1
- package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPlace.js +5 -4
- package/dist/components/dataaccess/UserAccessRequestHistory/UserAccessRequestHistoryPlace.js.map +1 -1
- package/dist/features/curator/dashboard/CuratorDashboardRouter.d.ts.map +1 -1
- package/dist/features/curator/dashboard/CuratorDashboardRouter.js +15 -15
- package/dist/features/curator/dashboard/CuratorDashboardRouter.js.map +1 -1
- package/dist/features/entity/metadata-task/components/MetadataTasksPageRouter.d.ts.map +1 -1
- package/dist/features/entity/metadata-task/components/MetadataTasksPageRouter.js +15 -14
- package/dist/features/entity/metadata-task/components/MetadataTasksPageRouter.js.map +1 -1
- package/dist/mocks/accessRequirement/mockJsonSchemaAccessRequirements.d.ts +7 -0
- package/dist/mocks/accessRequirement/mockJsonSchemaAccessRequirements.d.ts.map +1 -1
- package/dist/mocks/accessRequirement/mockJsonSchemaAccessRequirements.js +30 -15
- package/dist/mocks/accessRequirement/mockJsonSchemaAccessRequirements.js.map +1 -1
- package/dist/mocks/dataaccess/MockDataAccessRequest.d.ts +3 -0
- package/dist/mocks/dataaccess/MockDataAccessRequest.d.ts.map +1 -1
- package/dist/mocks/dataaccess/MockDataAccessRequest.js +24 -12
- package/dist/mocks/dataaccess/MockDataAccessRequest.js.map +1 -1
- package/dist/mocks/msw/handlers/dataAccessRequestHandlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers/dataAccessRequestHandlers.js +42 -30
- package/dist/mocks/msw/handlers/dataAccessRequestHandlers.js.map +1 -1
- package/dist/synapse-queries/dataaccess/useGeneratedRequestForm.d.ts +19 -0
- package/dist/synapse-queries/dataaccess/useGeneratedRequestForm.d.ts.map +1 -0
- package/dist/synapse-queries/dataaccess/useGeneratedRequestForm.js +26 -0
- package/dist/synapse-queries/dataaccess/useGeneratedRequestForm.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/hooks/useDetectSSOCode.d.ts.map +1 -1
- package/dist/utils/hooks/useDetectSSOCode.js +31 -26
- package/dist/utils/hooks/useDetectSSOCode.js.map +1 -1
- package/dist/utils/jsonschema/schemaData.d.ts +18 -0
- package/dist/utils/jsonschema/schemaData.d.ts.map +1 -0
- package/dist/utils/jsonschema/schemaData.js +26 -0
- package/dist/utils/jsonschema/schemaData.js.map +1 -0
- package/package.json +2 -2
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManagedACTAccessRequirementItem.d.ts.map +0 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManagedACTAccessRequirementItem.js.map +0 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManagedACTAccessRequirementItemView.d.ts.map +0 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManagedACTAccessRequirementItemView.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDetectSSOCode.d.ts","sourceRoot":"","sources":["../../../src/utils/hooks/useDetectSSOCode.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,0BAA0B,EAAE,MAAM,8EAA8E,CAAA;AAyBzH,MAAM,MAAM,0BAA0B,GAAG;IAEvC,SAAS,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAA;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;IAChC,uBAAuB,CAAC,EAAE,CAAC,IAAI,EAAE,0BAA0B,KAAK,IAAI,CAAA;IACpE,gCAAgC,CAAC,EAAE,CACjC,IAAI,EAAE,0BAA0B,EAChC,sBAAsB,EAAE,MAAM,KAC3B,IAAI,CAAA;IACT,qBAAqB,EAAE,OAAO,CAAA;IAC9B,eAAe,EAAE,OAAO,CAAA;CACzB,CAAA;
|
|
1
|
+
{"version":3,"file":"useDetectSSOCode.d.ts","sourceRoot":"","sources":["../../../src/utils/hooks/useDetectSSOCode.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,0BAA0B,EAAE,MAAM,8EAA8E,CAAA;AAyBzH,MAAM,MAAM,0BAA0B,GAAG;IAEvC,SAAS,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAA;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;IAChC,uBAAuB,CAAC,EAAE,CAAC,IAAI,EAAE,0BAA0B,KAAK,IAAI,CAAA;IACpE,gCAAgC,CAAC,EAAE,CACjC,IAAI,EAAE,0BAA0B,EAChC,sBAAsB,EAAE,MAAM,KAC3B,IAAI,CAAA;IACT,qBAAqB,EAAE,OAAO,CAAA;IAC9B,eAAe,EAAE,OAAO,CAAA;CACzB,CAAA;AAmBD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CACtC,IAAI,GAAE,uBAGL,GACA,0BAA0B,CAwN5B"}
|
|
@@ -20,13 +20,17 @@ function m(e) {
|
|
|
20
20
|
console.warn(`Unable to remove from localStorage: ${e}`, t);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
var h = {
|
|
24
|
+
[t.ORCID]: "No Synapse account is linked to this ORCID iD. Sign in to Synapse and link your ORCID iD from your account settings.",
|
|
25
|
+
[t.NIH_RESEARCHER_AUTH_SERVICE]: "No Synapse account is linked to this NIH RAS identity. Sign in to Synapse and link your NIH RAS identity from your account settings."
|
|
26
|
+
};
|
|
27
|
+
function g(g = {
|
|
24
28
|
isInitializingSession: !0,
|
|
25
29
|
isAuthenticated: !1
|
|
26
30
|
}) {
|
|
27
|
-
let
|
|
28
|
-
if (!
|
|
29
|
-
let e =
|
|
31
|
+
let _ = l("/register1"), { onSignInComplete: v, registerAccountUrl: y = _.toString(), onError: b, onTwoFactorAuthRequired: x, onTwoFactorAuthResetTokenPresent: S, isInitializingSession: C, isAuthenticated: w } = g, T = i(), { searchParams: E } = new URL(typeof window < "u" ? window.location.href : "http://localhost/"), D = E?.get("code"), O = E?.get("provider"), k = !!(E?.get("client_id") && E?.get("redirect_uri")), A = d(() => {
|
|
32
|
+
if (!k) {
|
|
33
|
+
let e = E?.get("state");
|
|
30
34
|
try {
|
|
31
35
|
return e ? JSON.parse(decodeURIComponent(e)) : null;
|
|
32
36
|
} catch (t) {
|
|
@@ -34,43 +38,44 @@ function h(h = {
|
|
|
34
38
|
}
|
|
35
39
|
}
|
|
36
40
|
return null;
|
|
37
|
-
}, [
|
|
41
|
+
}, [k, E]), [j, M] = f(!!(D && O));
|
|
38
42
|
return u(() => {
|
|
39
|
-
if (!
|
|
40
|
-
if (!
|
|
41
|
-
let t = p(e), n =
|
|
43
|
+
if (!C && D && O) {
|
|
44
|
+
if (!k) {
|
|
45
|
+
let t = p(e), n = A?.csrfToken ?? null;
|
|
42
46
|
if (!(typeof n == "string" && typeof t == "string" && n === t)) {
|
|
43
|
-
m(e), console.error("Invalid or missing OAuth CSRF token detected. Aborting OAuth flow."),
|
|
47
|
+
m(e), console.error("Invalid or missing OAuth CSRF token detected. Aborting OAuth flow."), b && b("Invalid OAuth state. Please try signing in again."), M(!1);
|
|
44
48
|
return;
|
|
45
49
|
}
|
|
46
50
|
m(e);
|
|
47
51
|
}
|
|
48
|
-
let i = `${
|
|
49
|
-
if (t.ORCID ==
|
|
50
|
-
console.error("Error binding ORCiD to account: ", e),
|
|
51
|
-
}).finally(() =>
|
|
52
|
-
else if (t.NIH_RESEARCHER_AUTH_SERVICE ==
|
|
53
|
-
console.error("Error binding NIH RAS identity to account: ", e),
|
|
54
|
-
}).finally(() =>
|
|
55
|
-
else if (t.GOOGLE ==
|
|
52
|
+
let i = `${T}?provider=${O}`;
|
|
53
|
+
if (t.ORCID == O && w) r(O, D, i, n.REPO_ENDPOINT).then(v).catch((e) => {
|
|
54
|
+
console.error("Error binding ORCiD to account: ", e), b && b(e.reason);
|
|
55
|
+
}).finally(() => M(!1));
|
|
56
|
+
else if (t.NIH_RESEARCHER_AUTH_SERVICE == O && w) a(O, String(D), i).then(v).catch((e) => {
|
|
57
|
+
console.error("Error binding NIH RAS identity to account: ", e), b && b(e.reason);
|
|
58
|
+
}).finally(() => M(!1));
|
|
59
|
+
else if (t.GOOGLE == O || t.ORCID == O || t.ARCUS == O || t.SAGE_BIONETWORKS == O || t.NIH_RESEARCHER_AUTH_SERVICE == O) {
|
|
56
60
|
let e = (e) => {
|
|
57
|
-
e && ("accessToken" in e ? c(e.accessToken).then(
|
|
61
|
+
e && ("accessToken" in e ? c(e.accessToken).then(v) : (x && x(e), A?.twoFaResetToken && S && S(e, A.twoFaResetToken)));
|
|
58
62
|
}, r = (e) => {
|
|
59
63
|
if (e.status === 404) {
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
let t = h[O];
|
|
65
|
+
if (t) {
|
|
66
|
+
console.error("No Synapse account is linked to this identity: ", e), b && b(t);
|
|
62
67
|
return;
|
|
63
68
|
}
|
|
64
|
-
window.location.replace(
|
|
69
|
+
window.location.replace(y);
|
|
65
70
|
}
|
|
66
|
-
console.error("Error with account login: ", e),
|
|
71
|
+
console.error("Error with account login: ", e), b && b(e.reason);
|
|
67
72
|
};
|
|
68
|
-
(t.GOOGLE ==
|
|
69
|
-
} else console.warn("Unknown SSO Provider: ",
|
|
73
|
+
(t.GOOGLE == O || t.ARCUS == O || t.SAGE_BIONETWORKS == O) && A?.registrationUsername ? o(A.registrationUsername, O, D, i, n.REPO_ENDPOINT).then(e).catch(r).finally(() => M(!1)) : s(O, D, i, n.REPO_ENDPOINT).then(e).catch(r).finally(() => M(!1));
|
|
74
|
+
} else console.warn("Unknown SSO Provider: ", O), M(!1);
|
|
70
75
|
}
|
|
71
|
-
}, [
|
|
76
|
+
}, [C]), { isLoading: j };
|
|
72
77
|
}
|
|
73
78
|
//#endregion
|
|
74
|
-
export {
|
|
79
|
+
export { g as default };
|
|
75
80
|
|
|
76
81
|
//# sourceMappingURL=useDetectSSOCode.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDetectSSOCode.js","names":[],"sources":["../../../src/utils/hooks/useDetectSSOCode.ts"],"sourcesContent":["import {\n bindOAuthProviderToAccount,\n getRootURL,\n oAuthIdentityRequest,\n oAuthRegisterAccountStep2,\n oAuthSessionRequest,\n setAccessTokenCookie,\n} from '@/synapse-client'\nimport { OAuth2State } from '@/utils/types'\nimport { OAuthValidationRequestProviderEnum } from '@sage-bionetworks/synapse-client'\nimport { TwoFactorAuthErrorResponse } from '@sage-bionetworks/synapse-client/generated/models/TwoFactorAuthErrorResponse'\nimport { SynapseClientError } from '@sage-bionetworks/synapse-client/util/SynapseClientError'\nimport { LoginResponse } from '@sage-bionetworks/synapse-types'\nimport { useEffect, useMemo, useState } from 'react'\nimport { BackendDestinationEnum } from '../functions'\nimport { CSRF_TOKEN_STORAGE_KEY, OAUTH2_PROVIDERS } from '../SynapseConstants'\nimport { useOneSageURL } from './useOneSageURL'\n\nfunction safeLocalStorageGetItem(key: string): string | null {\n try {\n return localStorage.getItem(key)\n } catch (err) {\n console.warn(`Unable to read from localStorage: ${key}`, err)\n return null\n }\n}\n\nfunction safeLocalStorageRemoveItem(key: string): void {\n try {\n localStorage.removeItem(key)\n } catch (err) {\n console.warn(`Unable to remove from localStorage: ${key}`, err)\n }\n}\n\nexport type UseDetectSSOCodeReturnType = {\n /* true iff SSO login has occurred and the completion of the OAuth flow in Synapse is pending */\n isLoading: boolean\n}\n\nexport type UseDetectSSOCodeOptions = {\n onSignInComplete?: () => void\n registerAccountUrl?: string\n onError?: (err: unknown) => void\n onTwoFactorAuthRequired?: (resp: TwoFactorAuthErrorResponse) => void\n onTwoFactorAuthResetTokenPresent?: (\n resp: TwoFactorAuthErrorResponse,\n encodedTwoFaResetToken: string,\n ) => void\n isInitializingSession: boolean\n isAuthenticated: boolean\n}\n\n/*\n * During SSO login, the authorization provider (Google, ORCiD, ArcusBio Okta, ...) will send the user back to the portal with an authorization code,\n * which can be exchanged for a Synapse user session. This function should be called whenever the root App is initialized\n * (to look for this code parameter and complete the round-trip). If state is included, then we assume that this is being\n * used for account creation, where we pass the username through the process.\n */\nexport default function useDetectSSOCode(\n opts: UseDetectSSOCodeOptions = {\n isInitializingSession: true,\n isAuthenticated: false,\n },\n): UseDetectSSOCodeReturnType {\n const defaultRegisterAccountURL = useOneSageURL('/register1')\n\n const {\n onSignInComplete,\n registerAccountUrl = defaultRegisterAccountURL.toString(),\n onError,\n onTwoFactorAuthRequired,\n onTwoFactorAuthResetTokenPresent,\n isInitializingSession,\n isAuthenticated,\n } = opts\n const redirectURL = getRootURL()\n // 'code' handling (from SSO) should be preformed on the root page, and then redirect to original route.\n // Use 'http://localhost/' as a placeholder during SSR (no browser URL available).\n // Since there is no 'code' or 'provider' in this placeholder URL, the rest of the hook is a no-op.\n const fullUrl: URL = new URL(\n typeof window !== 'undefined' ? window.location.href : 'http://localhost/',\n )\n // in test environment the searchParams isn't defined\n const { searchParams } = fullUrl\n const code = searchParams?.get('code')\n const provider = searchParams?.get('provider')\n\n // If the URL contains a client_id and redirect_uri, then we are acting as an identity provider for an external OAuth client\n const isHandlingSynapseOAuthSignIn = Boolean(\n searchParams?.get('client_id') && searchParams?.get('redirect_uri'),\n )\n\n // If the Synapse user signed in with an external IdP, we may have passed data in the 'state' param\n // Parse it (if appropriate)\n const state: OAuth2State | null = useMemo(() => {\n // If we are acting as an OIDC identity provider, then we should not parse the state param -- it was sent to us, and we should return it untouched\n if (!isHandlingSynapseOAuthSignIn) {\n const encodedState = searchParams?.get('state')\n try {\n return encodedState\n ? (JSON.parse(decodeURIComponent(encodedState)) as OAuth2State)\n : null\n } catch (e) {\n console.error(\n 'Error parsing state param:\\n',\n e,\n '\\nEncoded value:\\n',\n encodedState,\n )\n }\n }\n return null\n }, [isHandlingSynapseOAuthSignIn, searchParams])\n\n const [isLoading, setIsLoading] = useState(!!(code && provider))\n\n useEffect(() => {\n if (!isInitializingSession) {\n if (code && provider) {\n if (!isHandlingSynapseOAuthSignIn) {\n const storedCsrfToken = safeLocalStorageGetItem(\n CSRF_TOKEN_STORAGE_KEY,\n )\n\n const expectedCsrfToken = state?.csrfToken ?? null\n const tokensMatch =\n typeof expectedCsrfToken === 'string' &&\n typeof storedCsrfToken === 'string' &&\n expectedCsrfToken === storedCsrfToken\n\n if (!tokensMatch) {\n safeLocalStorageRemoveItem(CSRF_TOKEN_STORAGE_KEY)\n console.error(\n 'Invalid or missing OAuth CSRF token detected. Aborting OAuth flow.',\n )\n if (onError) {\n onError('Invalid OAuth state. Please try signing in again.')\n }\n setIsLoading(false)\n return\n }\n\n safeLocalStorageRemoveItem(CSRF_TOKEN_STORAGE_KEY)\n }\n\n const redirectUrl = `${redirectURL}?provider=${provider}`\n\n //If user is already logged in, and the provider is ORCID, then try to bind this OAuth provider to the account.\n if (OAUTH2_PROVIDERS.ORCID == provider && isAuthenticated) {\n // now bind this to the user account\n const onFailure = (err: SynapseClientError) => {\n console.error('Error binding ORCiD to account: ', err)\n if (onError) {\n onError(err.reason)\n }\n }\n bindOAuthProviderToAccount(\n provider,\n code,\n redirectUrl,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n .then(onSignInComplete)\n .catch(onFailure)\n .finally(() => setIsLoading(false))\n } else if (\n OAUTH2_PROVIDERS.NIH_RESEARCHER_AUTH_SERVICE == provider &&\n isAuthenticated\n ) {\n // RAS does not provide an alias, so bind via the identity endpoint\n const onFailure = (err: SynapseClientError) => {\n console.error('Error binding NIH RAS identity to account: ', err)\n if (onError) {\n onError(err.reason)\n }\n }\n oAuthIdentityRequest(\n provider as OAuthValidationRequestProviderEnum,\n String(code),\n redirectUrl,\n )\n .then(onSignInComplete)\n .catch(onFailure)\n .finally(() => setIsLoading(false))\n } else if (\n OAUTH2_PROVIDERS.GOOGLE == provider ||\n OAUTH2_PROVIDERS.ORCID == provider ||\n OAUTH2_PROVIDERS.ARCUS == provider ||\n OAUTH2_PROVIDERS.SAGE_BIONETWORKS == provider ||\n OAUTH2_PROVIDERS.NIH_RESEARCHER_AUTH_SERVICE == provider\n ) {\n const onSuccess = (\n response: LoginResponse | TwoFactorAuthErrorResponse | null,\n ) => {\n if (response) {\n if ('accessToken' in response) {\n setAccessTokenCookie(response.accessToken).then(\n onSignInComplete,\n )\n } else {\n // The app will redirect or open a modal to handle a standard 2FA sign in\n if (onTwoFactorAuthRequired) {\n onTwoFactorAuthRequired(response)\n }\n if (\n // The user logged in with OAuth while attempting to disable 2FA using an emailed signed token\n state?.twoFaResetToken &&\n onTwoFactorAuthResetTokenPresent\n ) {\n // Let the app handle redirecting to the 2FA reset page\n onTwoFactorAuthResetTokenPresent(\n response,\n state.twoFaResetToken,\n )\n }\n }\n }\n }\n const onFailure = (err: SynapseClientError) => {\n if (err.status === 404) {\n if (OAUTH2_PROVIDERS.NIH_RESEARCHER_AUTH_SERVICE == provider) {\n // RAS cannot create a Synapse account (no alias). Surface an\n // explicit error instead of redirecting to registration.\n console.error(\n 'No Synapse account is linked to this NIH RAS identity: ',\n err,\n )\n if (onError) {\n onError(\n 'No Synapse account is linked to this NIH RAS identity. Sign in to Synapse and link your NIH RAS identity from your account settings.',\n )\n }\n return\n }\n // Synapse account not found, send to registration page\n window.location.replace(registerAccountUrl)\n }\n console.error('Error with account login: ', err)\n if (onError) {\n onError(err.reason)\n }\n }\n\n if (\n (OAUTH2_PROVIDERS.GOOGLE == provider ||\n OAUTH2_PROVIDERS.ARCUS == provider ||\n OAUTH2_PROVIDERS.SAGE_BIONETWORKS == provider) &&\n state?.registrationUsername\n ) {\n oAuthRegisterAccountStep2(\n state.registrationUsername,\n provider,\n code,\n redirectUrl,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n .then(onSuccess)\n .catch(onFailure)\n .finally(() => setIsLoading(false))\n } else {\n oAuthSessionRequest(\n provider,\n code,\n redirectUrl,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n .then(onSuccess)\n .catch(onFailure)\n .finally(() => setIsLoading(false))\n }\n } else {\n console.warn('Unknown SSO Provider: ', provider)\n setIsLoading(false)\n }\n }\n }\n // Intentionally only monitoring initialization of the session -- only running on mount after the session detection has completed since this uses URL params that come from a redirect\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [isInitializingSession])\n\n return { isLoading }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useDetectSSOCode.js","names":[],"sources":["../../../src/utils/hooks/useDetectSSOCode.ts"],"sourcesContent":["import {\n bindOAuthProviderToAccount,\n getRootURL,\n oAuthIdentityRequest,\n oAuthRegisterAccountStep2,\n oAuthSessionRequest,\n setAccessTokenCookie,\n} from '@/synapse-client'\nimport { OAuth2State } from '@/utils/types'\nimport { OAuthValidationRequestProviderEnum } from '@sage-bionetworks/synapse-client'\nimport { TwoFactorAuthErrorResponse } from '@sage-bionetworks/synapse-client/generated/models/TwoFactorAuthErrorResponse'\nimport { SynapseClientError } from '@sage-bionetworks/synapse-client/util/SynapseClientError'\nimport { LoginResponse } from '@sage-bionetworks/synapse-types'\nimport { useEffect, useMemo, useState } from 'react'\nimport { BackendDestinationEnum } from '../functions'\nimport { CSRF_TOKEN_STORAGE_KEY, OAUTH2_PROVIDERS } from '../SynapseConstants'\nimport { useOneSageURL } from './useOneSageURL'\n\nfunction safeLocalStorageGetItem(key: string): string | null {\n try {\n return localStorage.getItem(key)\n } catch (err) {\n console.warn(`Unable to read from localStorage: ${key}`, err)\n return null\n }\n}\n\nfunction safeLocalStorageRemoveItem(key: string): void {\n try {\n localStorage.removeItem(key)\n } catch (err) {\n console.warn(`Unable to remove from localStorage: ${key}`, err)\n }\n}\n\nexport type UseDetectSSOCodeReturnType = {\n /* true iff SSO login has occurred and the completion of the OAuth flow in Synapse is pending */\n isLoading: boolean\n}\n\nexport type UseDetectSSOCodeOptions = {\n onSignInComplete?: () => void\n registerAccountUrl?: string\n onError?: (err: unknown) => void\n onTwoFactorAuthRequired?: (resp: TwoFactorAuthErrorResponse) => void\n onTwoFactorAuthResetTokenPresent?: (\n resp: TwoFactorAuthErrorResponse,\n encodedTwoFaResetToken: string,\n ) => void\n isInitializingSession: boolean\n isAuthenticated: boolean\n}\n\n/*\n * Identity providers that cannot be used to create a Synapse account, so an unlinked identity must surface an error\n * instead of sending the user to registration.\n */\nconst UNLINKED_IDENTITY_ERROR_BY_PROVIDER: Partial<Record<string, string>> = {\n [OAUTH2_PROVIDERS.ORCID]:\n 'No Synapse account is linked to this ORCID iD. Sign in to Synapse and link your ORCID iD from your account settings.',\n [OAUTH2_PROVIDERS.NIH_RESEARCHER_AUTH_SERVICE]:\n 'No Synapse account is linked to this NIH RAS identity. Sign in to Synapse and link your NIH RAS identity from your account settings.',\n}\n\n/*\n * During SSO login, the authorization provider (Google, ORCiD, ArcusBio Okta, ...) will send the user back to the portal with an authorization code,\n * which can be exchanged for a Synapse user session. This function should be called whenever the root App is initialized\n * (to look for this code parameter and complete the round-trip). If state is included, then we assume that this is being\n * used for account creation, where we pass the username through the process.\n */\nexport default function useDetectSSOCode(\n opts: UseDetectSSOCodeOptions = {\n isInitializingSession: true,\n isAuthenticated: false,\n },\n): UseDetectSSOCodeReturnType {\n const defaultRegisterAccountURL = useOneSageURL('/register1')\n\n const {\n onSignInComplete,\n registerAccountUrl = defaultRegisterAccountURL.toString(),\n onError,\n onTwoFactorAuthRequired,\n onTwoFactorAuthResetTokenPresent,\n isInitializingSession,\n isAuthenticated,\n } = opts\n const redirectURL = getRootURL()\n // 'code' handling (from SSO) should be preformed on the root page, and then redirect to original route.\n // Use 'http://localhost/' as a placeholder during SSR (no browser URL available).\n // Since there is no 'code' or 'provider' in this placeholder URL, the rest of the hook is a no-op.\n const fullUrl: URL = new URL(\n typeof window !== 'undefined' ? window.location.href : 'http://localhost/',\n )\n // in test environment the searchParams isn't defined\n const { searchParams } = fullUrl\n const code = searchParams?.get('code')\n const provider = searchParams?.get('provider')\n\n // If the URL contains a client_id and redirect_uri, then we are acting as an identity provider for an external OAuth client\n const isHandlingSynapseOAuthSignIn = Boolean(\n searchParams?.get('client_id') && searchParams?.get('redirect_uri'),\n )\n\n // If the Synapse user signed in with an external IdP, we may have passed data in the 'state' param\n // Parse it (if appropriate)\n const state: OAuth2State | null = useMemo(() => {\n // If we are acting as an OIDC identity provider, then we should not parse the state param -- it was sent to us, and we should return it untouched\n if (!isHandlingSynapseOAuthSignIn) {\n const encodedState = searchParams?.get('state')\n try {\n return encodedState\n ? (JSON.parse(decodeURIComponent(encodedState)) as OAuth2State)\n : null\n } catch (e) {\n console.error(\n 'Error parsing state param:\\n',\n e,\n '\\nEncoded value:\\n',\n encodedState,\n )\n }\n }\n return null\n }, [isHandlingSynapseOAuthSignIn, searchParams])\n\n const [isLoading, setIsLoading] = useState(!!(code && provider))\n\n useEffect(() => {\n if (!isInitializingSession) {\n if (code && provider) {\n if (!isHandlingSynapseOAuthSignIn) {\n const storedCsrfToken = safeLocalStorageGetItem(\n CSRF_TOKEN_STORAGE_KEY,\n )\n\n const expectedCsrfToken = state?.csrfToken ?? null\n const tokensMatch =\n typeof expectedCsrfToken === 'string' &&\n typeof storedCsrfToken === 'string' &&\n expectedCsrfToken === storedCsrfToken\n\n if (!tokensMatch) {\n safeLocalStorageRemoveItem(CSRF_TOKEN_STORAGE_KEY)\n console.error(\n 'Invalid or missing OAuth CSRF token detected. Aborting OAuth flow.',\n )\n if (onError) {\n onError('Invalid OAuth state. Please try signing in again.')\n }\n setIsLoading(false)\n return\n }\n\n safeLocalStorageRemoveItem(CSRF_TOKEN_STORAGE_KEY)\n }\n\n const redirectUrl = `${redirectURL}?provider=${provider}`\n\n //If user is already logged in, and the provider is ORCID, then try to bind this OAuth provider to the account.\n if (OAUTH2_PROVIDERS.ORCID == provider && isAuthenticated) {\n // now bind this to the user account\n const onFailure = (err: SynapseClientError) => {\n console.error('Error binding ORCiD to account: ', err)\n if (onError) {\n onError(err.reason)\n }\n }\n bindOAuthProviderToAccount(\n provider,\n code,\n redirectUrl,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n .then(onSignInComplete)\n .catch(onFailure)\n .finally(() => setIsLoading(false))\n } else if (\n OAUTH2_PROVIDERS.NIH_RESEARCHER_AUTH_SERVICE == provider &&\n isAuthenticated\n ) {\n // RAS does not provide an alias, so bind via the identity endpoint\n const onFailure = (err: SynapseClientError) => {\n console.error('Error binding NIH RAS identity to account: ', err)\n if (onError) {\n onError(err.reason)\n }\n }\n oAuthIdentityRequest(\n provider as OAuthValidationRequestProviderEnum,\n String(code),\n redirectUrl,\n )\n .then(onSignInComplete)\n .catch(onFailure)\n .finally(() => setIsLoading(false))\n } else if (\n OAUTH2_PROVIDERS.GOOGLE == provider ||\n OAUTH2_PROVIDERS.ORCID == provider ||\n OAUTH2_PROVIDERS.ARCUS == provider ||\n OAUTH2_PROVIDERS.SAGE_BIONETWORKS == provider ||\n OAUTH2_PROVIDERS.NIH_RESEARCHER_AUTH_SERVICE == provider\n ) {\n const onSuccess = (\n response: LoginResponse | TwoFactorAuthErrorResponse | null,\n ) => {\n if (response) {\n if ('accessToken' in response) {\n setAccessTokenCookie(response.accessToken).then(\n onSignInComplete,\n )\n } else {\n // The app will redirect or open a modal to handle a standard 2FA sign in\n if (onTwoFactorAuthRequired) {\n onTwoFactorAuthRequired(response)\n }\n if (\n // The user logged in with OAuth while attempting to disable 2FA using an emailed signed token\n state?.twoFaResetToken &&\n onTwoFactorAuthResetTokenPresent\n ) {\n // Let the app handle redirecting to the 2FA reset page\n onTwoFactorAuthResetTokenPresent(\n response,\n state.twoFaResetToken,\n )\n }\n }\n }\n }\n const onFailure = (err: SynapseClientError) => {\n if (err.status === 404) {\n const unlinkedIdentityError =\n UNLINKED_IDENTITY_ERROR_BY_PROVIDER[provider]\n if (unlinkedIdentityError) {\n console.error(\n 'No Synapse account is linked to this identity: ',\n err,\n )\n if (onError) {\n onError(unlinkedIdentityError)\n }\n return\n }\n // Synapse account not found, send to registration page\n window.location.replace(registerAccountUrl)\n }\n console.error('Error with account login: ', err)\n if (onError) {\n onError(err.reason)\n }\n }\n\n if (\n (OAUTH2_PROVIDERS.GOOGLE == provider ||\n OAUTH2_PROVIDERS.ARCUS == provider ||\n OAUTH2_PROVIDERS.SAGE_BIONETWORKS == provider) &&\n state?.registrationUsername\n ) {\n oAuthRegisterAccountStep2(\n state.registrationUsername,\n provider,\n code,\n redirectUrl,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n .then(onSuccess)\n .catch(onFailure)\n .finally(() => setIsLoading(false))\n } else {\n oAuthSessionRequest(\n provider,\n code,\n redirectUrl,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n .then(onSuccess)\n .catch(onFailure)\n .finally(() => setIsLoading(false))\n }\n } else {\n console.warn('Unknown SSO Provider: ', provider)\n setIsLoading(false)\n }\n }\n }\n // Intentionally only monitoring initialization of the session -- only running on mount after the session detection has completed since this uses URL params that come from a redirect\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [isInitializingSession])\n\n return { isLoading }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { GeneratedFormStepForRjsf } from '@/utils/jsonschema/generateDataAccessSchema';
|
|
2
|
+
import { DataAccessRequestType } from '@sage-bionetworks/synapse-client';
|
|
3
|
+
export type SchemaData = Record<string, unknown>;
|
|
4
|
+
/** The answers that belong to the given step. */
|
|
5
|
+
export declare function getStepData(schemaData: SchemaData, step: GeneratedFormStepForRjsf): SchemaData;
|
|
6
|
+
/**
|
|
7
|
+
* The title of a generated step, or `Step {position}` for a step without one.
|
|
8
|
+
* @param position the 1-based position of the step among all steps shown to the user
|
|
9
|
+
*/
|
|
10
|
+
export declare function getStepTitle(step: GeneratedFormStepForRjsf, position: number): string;
|
|
11
|
+
/**
|
|
12
|
+
* The payload the server validates. It must declare the type of the request so that context-specific properties are
|
|
13
|
+
* validated against the right branch of the schema.
|
|
14
|
+
*/
|
|
15
|
+
export declare function withSubmissionContext(schemaData: SchemaData, requestType: DataAccessRequestType): SchemaData;
|
|
16
|
+
/** The titles of the file upload fields, which the request form cannot yet collect. */
|
|
17
|
+
export declare function getFileUploadFieldTitles(steps: GeneratedFormStepForRjsf[]): string[];
|
|
18
|
+
//# sourceMappingURL=schemaData.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaData.d.ts","sourceRoot":"","sources":["../../../src/utils/jsonschema/schemaData.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAA;AAGtF,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAA;AAGxE,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAQhD,iDAAiD;AACjD,wBAAgB,WAAW,CACzB,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,wBAAwB,GAC7B,UAAU,CAEZ;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,wBAAwB,EAC9B,QAAQ,EAAE,MAAM,GACf,MAAM,CAIR;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,qBAAqB,GACjC,UAAU,CAKZ;AAED,uFAAuF;AACvF,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,wBAAwB,EAAE,GAChC,MAAM,EAAE,CASV"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { SUBMISSION_CONTEXT_PROPERTY as e } from "./submissionContext.js";
|
|
2
|
+
import t from "lodash-es/pick";
|
|
3
|
+
//#region src/utils/jsonschema/schemaData.ts
|
|
4
|
+
var n = "synapse-filehandle-id";
|
|
5
|
+
function r(e) {
|
|
6
|
+
return Object.keys(e.jsonSchema.properties ?? {});
|
|
7
|
+
}
|
|
8
|
+
function i(e, n) {
|
|
9
|
+
return t(e, r(n));
|
|
10
|
+
}
|
|
11
|
+
function a(e, t) {
|
|
12
|
+
return typeof e.jsonSchema.title == "string" && e.jsonSchema.title ? e.jsonSchema.title : `Step ${t}`;
|
|
13
|
+
}
|
|
14
|
+
function o(t, n) {
|
|
15
|
+
return {
|
|
16
|
+
...t,
|
|
17
|
+
[e]: n
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function s(e) {
|
|
21
|
+
return e.flatMap((e) => Object.entries(e.jsonSchema.properties ?? {}).filter(([, e]) => e.format === n).map(([e, t]) => t.title ?? e));
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { s as getFileUploadFieldTitles, i as getStepData, a as getStepTitle, o as withSubmissionContext };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=schemaData.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaData.js","names":[],"sources":["../../../src/utils/jsonschema/schemaData.ts"],"sourcesContent":["import { GeneratedFormStepForRjsf } from '@/utils/jsonschema/generateDataAccessSchema'\nimport { SUBMISSION_CONTEXT_PROPERTY } from '@/utils/jsonschema/submissionContext'\nimport { RJSFSchema } from '@rjsf/utils'\nimport { DataAccessRequestType } from '@sage-bionetworks/synapse-client'\nimport pick from 'lodash-es/pick'\n\nexport type SchemaData = Record<string, unknown>\n\nconst SYNAPSE_FILE_HANDLE_ID_FORMAT = 'synapse-filehandle-id'\n\nfunction getStepPropertyKeys(step: GeneratedFormStepForRjsf): string[] {\n return Object.keys(step.jsonSchema.properties ?? {})\n}\n\n/** The answers that belong to the given step. */\nexport function getStepData(\n schemaData: SchemaData,\n step: GeneratedFormStepForRjsf,\n): SchemaData {\n return pick(schemaData, getStepPropertyKeys(step))\n}\n\n/**\n * The title of a generated step, or `Step {position}` for a step without one.\n * @param position the 1-based position of the step among all steps shown to the user\n */\nexport function getStepTitle(\n step: GeneratedFormStepForRjsf,\n position: number,\n): string {\n return typeof step.jsonSchema.title === 'string' && step.jsonSchema.title\n ? step.jsonSchema.title\n : `Step ${position}`\n}\n\n/**\n * The payload the server validates. It must declare the type of the request so that context-specific properties are\n * validated against the right branch of the schema.\n */\nexport function withSubmissionContext(\n schemaData: SchemaData,\n requestType: DataAccessRequestType,\n): SchemaData {\n return {\n ...schemaData,\n [SUBMISSION_CONTEXT_PROPERTY]: requestType,\n }\n}\n\n/** The titles of the file upload fields, which the request form cannot yet collect. */\nexport function getFileUploadFieldTitles(\n steps: GeneratedFormStepForRjsf[],\n): string[] {\n return steps.flatMap(step =>\n Object.entries(step.jsonSchema.properties ?? {})\n .filter(\n ([, property]) =>\n (property as RJSFSchema).format === SYNAPSE_FILE_HANDLE_ID_FORMAT,\n )\n .map(([key, property]) => (property as RJSFSchema).title ?? key),\n )\n}\n"],"mappings":";;;AAQA,IAAM,IAAgC;AAEtC,SAAS,EAAoB,GAA0C;CACrE,OAAO,OAAO,KAAK,EAAK,WAAW,cAAc,CAAC,CAAC;AACrD;AAGA,SAAgB,EACd,GACA,GACY;CACZ,OAAO,EAAK,GAAY,EAAoB,CAAI,CAAC;AACnD;AAMA,SAAgB,EACd,GACA,GACQ;CACR,OAAO,OAAO,EAAK,WAAW,SAAU,YAAY,EAAK,WAAW,QAChE,EAAK,WAAW,QAChB,QAAQ;AACd;AAMA,SAAgB,EACd,GACA,GACY;CACZ,OAAO;EACL,GAAG;GACF,IAA8B;CACjC;AACF;AAGA,SAAgB,EACd,GACU;CACV,OAAO,EAAM,SAAQ,MACnB,OAAO,QAAQ,EAAK,WAAW,cAAc,CAAC,CAAC,EAC5C,QACE,GAAG,OACD,EAAwB,WAAW,CACxC,EACC,KAAK,CAAC,GAAK,OAAe,EAAwB,SAAS,CAAG,CACnE;AACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "synapse-react-client",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.43",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -124,8 +124,8 @@
|
|
|
124
124
|
"@sage-bionetworks/markdown-it-container": "4.0.1",
|
|
125
125
|
"@sage-bionetworks/react-datasheet-grid": "4.11.5-sage.10",
|
|
126
126
|
"@sage-bionetworks/synapse-client": "0.0.24",
|
|
127
|
+
"@sage-bionetworks/synapse-types": "0.0.11",
|
|
127
128
|
"markdown-it-synapse": "2.0.0",
|
|
128
|
-
"@sage-bionetworks/synapse-types": "0.0.10",
|
|
129
129
|
"markdown-it-synapse-table": "1.0.8"
|
|
130
130
|
},
|
|
131
131
|
"peerDependencies": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ManagedACTAccessRequirementItem.d.ts","sourceRoot":"","sources":["../../../../src/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManagedACTAccessRequirementItem.tsx"],"names":[],"mappings":"AAOA,OAAO,EACL,2BAA2B,EAE3B,sBAAsB,EACvB,MAAM,iCAAiC,CAAA;AAMxC,MAAM,MAAM,oCAAoC,GAAG;IACjD;;OAEG;IACH,iBAAiB,EAAE,2BAA2B,CAAA;IAC9C;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,WAAW,CAAC,EAAE,sBAAsB,CAAA;IACpC;;OAEG;IACH,aAAa,EAAE,MAAM,IAAI,CAAA;IACzB;;OAEG;IACH,eAAe,EAAE,MAAM,IAAI,CAAA;CAC5B,CAAA;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,oCAAoC,2CAqG5C;AAED,eAAe,+BAA+B,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ManagedACTAccessRequirementItem.js","names":[],"sources":["../../../../src/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManagedACTAccessRequirementItem.tsx"],"sourcesContent":["import {\n useCancelDataAccessRequest,\n useGetAccessRequirementStatus,\n useGetAccessRequirementWikiPageKey,\n useGetRestrictionInformation,\n} from '@/synapse-queries'\nimport { Alert } from '@mui/material'\nimport {\n ManagedACTAccessRequirement,\n ManagedACTAccessRequirementStatus,\n RestrictableObjectType,\n} from '@sage-bionetworks/synapse-types'\nimport { ReactNode, useCallback } from 'react'\nimport MarkdownSynapse from '../../Markdown/MarkdownSynapse'\nimport RequirementItem from '../RequirementItem/RequirementItem'\nimport ManagedACTAccessRequirementItemView from './ManagedACTAccessRequirementItemView'\n\nexport type ManagedACTAccessRequirementItemProps = {\n /**\n * The ManagedACTAccessRequirement to be displayed.\n */\n accessRequirement: ManagedACTAccessRequirement\n /**\n * If available, the ID of the object that this access requirement is being displayed for.\n */\n subjectId?: string\n /**\n * If available, the type of the object that this access requirement is being displayed for.\n */\n subjectType?: RestrictableObjectType\n /**\n * Invoked when the user clicks the \"I do not accept\" button.\n */\n onRejectTerms: () => void\n /**\n * Invoked when the user clicks the \"Request access\" button.\n */\n onRequestAccess: () => void\n}\n\n/**\n * Renders a {@link RequirementItem} for a ManagedACTAccessRequirement, which allows a user to see if they have met the\n * requirement, and if not, complete a data access request to apply for access.\n */\nexport function ManagedACTAccessRequirementItem(\n props: ManagedACTAccessRequirementItemProps,\n) {\n const {\n accessRequirement,\n subjectId,\n subjectType,\n onRejectTerms,\n onRequestAccess,\n } = props\n const {\n data: wikiPageKey,\n isLoading: isLoadingWikiPageKey,\n error: getWikiPageError,\n } = useGetAccessRequirementWikiPageKey(accessRequirement.id.toString())\n\n const {\n data: accessRequirementStatus,\n isLoading: isLoadingArStatus,\n error: getArStatusError,\n } = useGetAccessRequirementStatus<ManagedACTAccessRequirementStatus>(\n String(accessRequirement.id),\n )\n\n const {\n data: restrictionInformation,\n isLoading: isLoadingRestrictionInfo,\n error: getRestrictionInfoError,\n } = useGetRestrictionInformation(\n {\n objectId: subjectId!,\n restrictableObjectType: subjectType!,\n },\n { enabled: !!subjectId && !!subjectType },\n )\n\n const {\n mutate: cancelDataAccessRequest,\n error: cancelRequestError,\n isPending: cancelRequestIsPending,\n } = useCancelDataAccessRequest()\n\n const onCancelDataAccessRequest = useCallback(() => {\n if (!accessRequirementStatus) {\n // no-op; the component is still loading, so this will never happen\n return\n }\n cancelDataAccessRequest({\n submissionId:\n accessRequirementStatus.currentSubmissionStatus!.submissionId,\n accessRequirementId: String(accessRequirement.id),\n })\n }, [accessRequirement.id, accessRequirementStatus, cancelDataAccessRequest])\n\n const isLoading =\n isLoadingWikiPageKey || isLoadingArStatus || isLoadingRestrictionInfo\n\n let error: ReactNode = null\n if (\n getWikiPageError ||\n getArStatusError ||\n getRestrictionInfoError ||\n cancelRequestError\n ) {\n error = (\n <Alert className={'access-requirement-list-alert'} severity={'error'}>\n {getWikiPageError && getWikiPageError.reason}\n {getArStatusError && getArStatusError.reason}\n {getRestrictionInfoError && getRestrictionInfoError.reason}\n {cancelRequestError && (\n <>\n <strong>Error canceling your data access request:</strong>\n <br />\n {cancelRequestError.reason}\n </>\n )}\n </Alert>\n )\n }\n\n return (\n <ManagedACTAccessRequirementItemView\n isLoading={isLoading}\n accessRequirement={accessRequirement}\n accessRequirementStatus={accessRequirementStatus}\n restrictionInformation={restrictionInformation}\n wikiPage={\n wikiPageKey && (\n <MarkdownSynapse\n wikiId={wikiPageKey.wikiPageId}\n ownerId={wikiPageKey.ownerObjectId}\n objectType={wikiPageKey.ownerObjectType}\n />\n )\n }\n error={error}\n onCancelDataAccessRequest={onCancelDataAccessRequest}\n onRejectTerms={onRejectTerms}\n onRequestAccess={onRequestAccess}\n cancelRequestIsPending={cancelRequestIsPending}\n />\n )\n}\n\nexport default ManagedACTAccessRequirementItem\n"],"mappings":";;;;;;;;;AA4CA,SAAgB,EACd,GACA;CACA,IAAM,EACJ,sBACA,cACA,gBACA,kBACA,uBACE,GACE,EACJ,MAAM,GACN,WAAW,GACX,OAAO,MACL,EAAmC,EAAkB,GAAG,SAAS,CAAC,GAEhE,EACJ,MAAM,GACN,WAAW,GACX,OAAO,MACL,EACF,OAAO,EAAkB,EAAE,CAC7B,GAEM,EACJ,MAAM,GACN,WAAW,GACX,OAAO,MACL,EACF;EACE,UAAU;EACV,wBAAwB;CAC1B,GACA,EAAE,SAAS,CAAC,CAAC,KAAa,CAAC,CAAC,EAAY,CAC1C,GAEM,EACJ,QAAQ,GACR,OAAO,GACP,WAAW,MACT,EAA2B,GAEzB,IAA4B,QAAkB;EAC7C,KAIL,EAAwB;GACtB,cACE,EAAwB,wBAAyB;GACnD,qBAAqB,OAAO,EAAkB,EAAE;EAClD,CAAC;CACH,GAAG;EAAC,EAAkB;EAAI;EAAyB;CAAuB,CAAC,GAErE,IACJ,KAAwB,KAAqB,GAE3C,IAAmB;CAuBvB,QArBE,KACA,KACA,KACA,OAEA,IACE,kBAAC,GAAD;EAAO,WAAW;EAAiC,UAAU;YAA7D;GACG,KAAoB,EAAiB;GACrC,KAAoB,EAAiB;GACrC,KAA2B,EAAwB;GACnD,KACC,kBAAA,GAAA,EAAA,UAAA;IACE,kBAAC,UAAD,EAAA,UAAQ,4CAAiD,CAAA;IACzD,kBAAC,MAAD,CAAK,CAAA;IACJ,EAAmB;GACpB,EAAA,CAAA;EAEC;MAKT,kBAAC,GAAD;EACa;EACQ;EACM;EACD;EACxB,UACE,KACE,kBAAC,GAAD;GACE,QAAQ,EAAY;GACpB,SAAS,EAAY;GACrB,YAAY,EAAY;EACzB,CAAA;EAGE;EACoB;EACZ;EACE;EACO;CACzB,CAAA;AAEL"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ManagedACTAccessRequirementItemView.d.ts","sourceRoot":"","sources":["../../../../src/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManagedACTAccessRequirementItemView.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,iCAAiC,EACjC,8BAA8B,EAE/B,MAAM,iCAAiC,CAAA;AAExC,OAAO,EAAE,SAAS,EAAY,MAAM,OAAO,CAAA;AAG3C,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAA;AAEjE,MAAM,MAAM,wCAAwC,GAAG;IACrD;;OAEG;IACH,iBAAiB,EAAE,4BAA4B,CAAA;IAC/C;;OAEG;IACH,uBAAuB,CAAC,EAAE,iCAAiC,CAAA;IAC3D;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB;;OAEG;IACH,SAAS,EAAE,OAAO,CAAA;IAClB;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,8BAA8B,CAAA;IACvD;;OAEG;IACH,aAAa,EAAE,MAAM,IAAI,CAAA;IACzB;;OAEG;IACH,eAAe,EAAE,MAAM,IAAI,CAAA;IAC3B;;OAEG;IACH,yBAAyB,EAAE,MAAM,IAAI,CAAA;IACrC;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB;;OAEG;IACH,sBAAsB,EAAE,OAAO,CAAA;CAChC,CAAA;AA2GD;;;;;GAKG;AACH,wBAAgB,mCAAmC,CACjD,KAAK,EAAE,wCAAwC,2CA6IhD;AAED,eAAe,mCAAmC,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ManagedACTAccessRequirementItemView.js","names":[],"sources":["../../../../src/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManagedACTAccessRequirementItemView.tsx"],"sourcesContent":["import { formatDate } from '@/utils/functions/DateFormatter'\nimport { Alert, Box, ButtonProps, Link, Typography } from '@mui/material'\nimport Stack from '@mui/material/Stack'\nimport {\n ManagedACTAccessRequirementStatus,\n RestrictionInformationResponse,\n SubmissionState,\n} from '@sage-bionetworks/synapse-types'\nimport dayjs from 'dayjs'\nimport { ReactNode, useState } from 'react'\nimport { RequirementItemStatus } from '../AccessApprovalCheckMark'\nimport RequirementItem from '../RequirementItem/RequirementItem'\nimport { RequestFlowAccessRequirement } from './requestFlowTypes'\n\nexport type ManagedACTAccessRequirementItemViewProps = {\n /**\n * The ManagedACTAccessRequirement to be displayed.\n */\n accessRequirement: RequestFlowAccessRequirement\n /**\n * The user's status for this access requirement.\n */\n accessRequirementStatus?: ManagedACTAccessRequirementStatus\n /**\n * A ReactNode that contains the wiki page content for this access requirement.\n */\n wikiPage?: ReactNode\n /**\n * Whether the component is currently loading data.\n */\n isLoading: boolean\n /**\n * If available, the restriction information relevant to the subject that this\n * access requirement is being displayed for.\n *\n * This is used to determine if the user is exempt from meeting this requirement.\n */\n restrictionInformation?: RestrictionInformationResponse\n /**\n * Invoked when the user clicks the \"I do not accept\" button.\n */\n onRejectTerms: () => void\n /**\n * Invoked when the user clicks the \"Request access\" button.\n */\n onRequestAccess: () => void\n /**\n * Invoked when the user clicks the \"Cancel Request\" button (only shown if a request is active).\n */\n onCancelDataAccessRequest: () => void\n /**\n * ReactNode to display if there is an error in the component.\n */\n error?: ReactNode\n /**\n * Whether the a request to cancel the data access request is currently pending.\n */\n cancelRequestIsPending: boolean\n}\n\nconst APPROVED_TEXT = 'Your data access request has been approved.'\nconst EXEMPT_TEXT =\n 'This data access requirement is fulfilled by your team membership and permissions.'\n\n/**\n * Translate the ManagedACTAccessRequirementStatus and exemption status into a the\n * RequirementItemStatus displayed by the UI\n * @param status\n * @param isExempt\n */\nfunction getRequirementItemUiState(\n status: ManagedACTAccessRequirementStatus,\n isExempt: boolean,\n): RequirementItemStatus {\n if (isExempt) {\n return RequirementItemStatus.COMPLETE\n }\n\n // If there's no current submission, check the isApproved flag directly\n if (!status.currentSubmissionStatus) {\n return status.isApproved\n ? RequirementItemStatus.COMPLETE\n : RequirementItemStatus.LOCKED\n }\n\n switch (status.currentSubmissionStatus.state) {\n case SubmissionState.APPROVED:\n return status.isApproved\n ? RequirementItemStatus.COMPLETE\n : RequirementItemStatus.LOCKED\n case SubmissionState.SUBMITTED:\n return RequirementItemStatus.PENDING\n case SubmissionState.REJECTED:\n case SubmissionState.CANCELLED:\n default:\n return RequirementItemStatus.LOCKED\n }\n}\n\n/**\n * Gets the action buttons to display for a ManagedACTAccessRequirement based on the current state of the requirement.\n * @param accessRequirementStatus - the user's status for the access requirement\n * @param isExempt - whether the user is exempt from submitting a request for this access requirement\n * @param cancelRequestIsPending - whether a request to cancel the data access request is currently pending\n * @param callbacks - callbacks to invoke when the user clicks the action buttons\n */\nfunction getActionButtonProps(\n accessRequirementStatus: ManagedACTAccessRequirementStatus,\n isExempt: boolean,\n cancelRequestIsPending: boolean,\n callbacks: {\n onRequestAccess: () => void\n onRejectTerms: () => void\n onCancelDataAccessRequest: () => void\n },\n): ButtonProps[] {\n const { onRequestAccess, onRejectTerms, onCancelDataAccessRequest } =\n callbacks\n\n const actions: ButtonProps[] = []\n\n if (accessRequirementStatus) {\n if (accessRequirementStatus.currentSubmissionStatus == null) {\n actions.push({\n variant: 'outlined',\n onClick: onRequestAccess,\n // Show \"Update Request\" if approved, \"Request access\" otherwise\n children: accessRequirementStatus.isApproved\n ? 'Update Request'\n : 'Request access',\n })\n if (!isExempt && !accessRequirementStatus.isApproved) {\n actions.push({\n variant: 'text',\n onClick: onRejectTerms,\n children: 'I do not accept',\n })\n }\n } else if (\n [\n SubmissionState.APPROVED,\n SubmissionState.REJECTED,\n SubmissionState.CANCELLED,\n ].includes(accessRequirementStatus.currentSubmissionStatus.state)\n ) {\n actions.push({\n variant: 'outlined',\n onClick: onRequestAccess,\n children: 'Update Request',\n })\n } else if (\n accessRequirementStatus.currentSubmissionStatus.state ===\n SubmissionState.SUBMITTED\n ) {\n actions.push({\n variant: 'outlined',\n onClick: onCancelDataAccessRequest,\n children: 'Cancel Request',\n loading: cancelRequestIsPending,\n })\n }\n }\n return actions\n}\n\n/**\n * Renders a {@link RequirementItem} for a ManagedACTAccessRequirement, which allows a user to see if they have met the\n * requirement, and if not, complete a data access request to apply for access.\n *\n * This is a UI-only component that does not make any requests to external stores, and is exported for testing/Storybook only.\n */\nexport function ManagedACTAccessRequirementItemView(\n props: ManagedACTAccessRequirementItemViewProps,\n) {\n const {\n accessRequirement,\n accessRequirementStatus,\n isLoading,\n wikiPage,\n restrictionInformation,\n onRejectTerms,\n onRequestAccess,\n error,\n onCancelDataAccessRequest,\n cancelRequestIsPending,\n } = props\n const restrictionFulfillment =\n restrictionInformation?.restrictionDetails?.find(\n ar => ar.accessRequirementId === accessRequirement.id,\n )\n\n const [collapseWikiContent, setCollapseWikiContent] = useState<boolean>(true)\n\n const isApproved = accessRequirementStatus?.isApproved\n const isExempt = Boolean(restrictionFulfillment?.isExempt)\n\n const requirementTermsWikiContent = (\n <Stack gap={2}>\n {wikiPage}\n {accessRequirementStatus?.currentSubmissionStatus?.state ===\n SubmissionState.SUBMITTED && (\n <Alert className={'access-requirement-list-alert'} severity={'info'}>\n <strong>You have submitted a data access request.</strong>\n </Alert>\n )}\n {accessRequirementStatus?.currentSubmissionStatus?.state ===\n SubmissionState.APPROVED &&\n isApproved && (\n <Alert\n className={'access-requirement-list-alert'}\n severity={'success'}\n >\n <strong>Your data access request has been approved.</strong>\n </Alert>\n )}\n {accessRequirementStatus?.currentSubmissionStatus?.state ===\n SubmissionState.APPROVED &&\n !isApproved && (\n <Alert\n className={'access-requirement-list-alert'}\n severity={'warning'}\n >\n <Typography variant={'smallText1'} gutterBottom>\n <strong>Your data access has been revoked.</strong>\n </Typography>\n {accessRequirementStatus.expiredOn &&\n dayjs(accessRequirementStatus.expiredOn).isBefore(dayjs()) && (\n <Typography variant={'smallText1'} gutterBottom>\n Your access expired on{' '}\n {formatDate(dayjs(accessRequirementStatus.expiredOn))}.\n </Typography>\n )}\n </Alert>\n )}\n {accessRequirementStatus?.currentSubmissionStatus?.state ===\n SubmissionState.REJECTED && (\n <Alert className={'access-requirement-list-alert'} severity={'error'}>\n <Typography variant={'body1'} gutterBottom>\n <strong>Your data access request has been rejected.</strong>\n </Typography>\n <Typography\n variant={'body1'}\n gutterBottom\n sx={{ whiteSpace: 'pre-line' }}\n >\n {accessRequirementStatus?.currentSubmissionStatus.rejectedReason ||\n ''}\n </Typography>\n </Alert>\n )}\n {accessRequirementStatus?.currentSubmissionStatus?.state ===\n SubmissionState.CANCELLED && (\n <Alert className={'access-requirement-list-alert'} severity={'info'}>\n <Typography variant={'body1'}>\n Your data access request has been canceled.\n </Typography>\n </Alert>\n )}\n </Stack>\n )\n\n let actions: ButtonProps[] = []\n if (!isLoading && accessRequirementStatus) {\n actions = getActionButtonProps(\n accessRequirementStatus,\n isExempt,\n cancelRequestIsPending,\n {\n onRequestAccess,\n onRejectTerms,\n onCancelDataAccessRequest,\n },\n )\n }\n\n let requirementItemState: RequirementItemStatus =\n RequirementItemStatus.LOADING\n if (!isLoading && accessRequirementStatus) {\n requirementItemState = getRequirementItemUiState(\n accessRequirementStatus,\n isExempt,\n )\n }\n\n return (\n <RequirementItem\n data-testid=\"ManagedACTAccessRequirementItem\"\n status={requirementItemState}\n actions={actions}\n >\n {/* If not approved/exempt, show the terms */}\n {!isApproved && !isExempt && <>{requirementTermsWikiContent}</>}\n {(isApproved || isExempt) && (\n <>\n <Typography variant={'body1'}>\n {isApproved && APPROVED_TEXT} {isExempt && EXEMPT_TEXT}{' '}\n <Link\n role={'button'}\n onClick={() => {\n setCollapseWikiContent(!collapseWikiContent)\n }}\n >\n {collapseWikiContent ? 'View Terms' : 'Hide Terms'}\n </Link>\n </Typography>\n {!collapseWikiContent && (\n <Box sx={{ my: 1 }}>{requirementTermsWikiContent}</Box>\n )}\n </>\n )}\n {error}\n </RequirementItem>\n )\n}\n\nexport default ManagedACTAccessRequirementItemView\n"],"mappings":"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"}
|