From ce49df876277fab14e0e14b9e24a1ff64811469b Mon Sep 17 00:00:00 2001 From: pranalidhanavade <137780597+pranalidhanavade@users.noreply.github.com> Date: Fri, 23 Aug 2024 19:09:16 +0530 Subject: [PATCH] merge: DEV to QA (#737) * [Deno Deploy] Update .github/workflows/deploy.yml * feat: support no ledger (#689) * wip: implemented ui for method selection Signed-off-by: bhavanakarwade * wip: modified no ledger screen Signed-off-by: bhavanakarwade * feat: modified ui for create did popup Signed-off-by: bhavanakarwade * refactor: worked on error handling Signed-off-by: bhavanakarwade * fix: validations on create did popup Signed-off-by: bhavanakarwade * refactor: mapping function Signed-off-by: bhavanakarwade * fix: resolved sonarlint issues Signed-off-by: bhavanakarwade * fix: input box issues Signed-off-by: bhavanakarwade * refactor: handled role wise conditions Signed-off-by: bhavanakarwade * fix: resolved code duplication errors Signed-off-by: bhavanakarwade * fix: enum values Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade * fixed CSS and avatar issues (#696) * fix:css issues Signed-off-by: pranalidhanavade * fix:sonarcloud issues Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade * feat: support no ledger (#697) * wip: implemented ui for method selection Signed-off-by: bhavanakarwade * wip: modified no ledger screen Signed-off-by: bhavanakarwade * feat: modified ui for create did popup Signed-off-by: bhavanakarwade * refactor: worked on error handling Signed-off-by: bhavanakarwade * fix: validations on create did popup Signed-off-by: bhavanakarwade * refactor: mapping function Signed-off-by: bhavanakarwade * fix: resolved sonarlint issues Signed-off-by: bhavanakarwade * fix: input box issues Signed-off-by: bhavanakarwade * refactor: handled role wise conditions Signed-off-by: bhavanakarwade * fix: resolved code duplication errors Signed-off-by: bhavanakarwade * fix: enum values Signed-off-by: bhavanakarwade * fix: added loading chnages Signed-off-by: bhavanakarwade * fix: ledgerconfig object changes Signed-off-by: bhavanakarwade * fix: resolved type errors Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade * refactor: responsiveness of the component (#699) * wip: implemented ui for method selection Signed-off-by: bhavanakarwade * wip: modified no ledger screen Signed-off-by: bhavanakarwade * feat: modified ui for create did popup Signed-off-by: bhavanakarwade * refactor: worked on error handling Signed-off-by: bhavanakarwade * fix: validations on create did popup Signed-off-by: bhavanakarwade * refactor: mapping function Signed-off-by: bhavanakarwade * fix: resolved sonarlint issues Signed-off-by: bhavanakarwade * fix: input box issues Signed-off-by: bhavanakarwade * refactor: handled role wise conditions Signed-off-by: bhavanakarwade * fix: resolved code duplication errors Signed-off-by: bhavanakarwade * fix: enum values Signed-off-by: bhavanakarwade * fix: added loading chnages Signed-off-by: bhavanakarwade * fix: ledgerconfig object changes Signed-off-by: bhavanakarwade * fix: resolved type errors Signed-off-by: bhavanakarwade * refactor: modified responsiveness of the component Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade * feat: manage keycloak client Signed-off-by: bhavanakarwade * refactor: updated env sample file Signed-off-by: bhavanakarwade * fix: error messages issue from create organization and create ecosystem modals. (#698) * fix:css issues Signed-off-by: pranalidhanavade * fix:sonarcloud issues Signed-off-by: pranalidhanavade * fix:clear error on pop-up close Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade * fix: css issues (#704) * refactor: parameter name Signed-off-by: bhavanakarwade * refactor: added query parameter Signed-off-by: bhavanakarwade * fix: remove unnecessary code Signed-off-by: bhavanakarwade * fix: query param issue Signed-off-by: bhavanakarwade * fix: css issues Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade * feat: add passkey warning message for unsupported devices (#706) * feat: add passkey warning message for unsupported devices Signed-off-by: pranalidhanavade * feat: add passkey warning message for unsupported devices Signed-off-by: pranalidhanavade * feat: add passkey warning message for unsupported devices Signed-off-by: pranalidhanavade * fix: removed commnets Signed-off-by: pranalidhanavade * feat: add passkey warning message for unsupported devices Signed-off-by: pranalidhanavade * feat: add passkey warning message for unsupported devices Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade * Feat/passkey warning messages (#707) * feat: add passkey warning message for unsupported devices Signed-off-by: pranalidhanavade * feat: add passkey warning message for unsupported devices Signed-off-by: pranalidhanavade * feat: add passkey warning message for unsupported devices Signed-off-by: pranalidhanavade * fix: removed commnets Signed-off-by: pranalidhanavade * feat: add passkey warning message for unsupported devices Signed-off-by: pranalidhanavade * feat: add passkey warning message for unsupported devices Signed-off-by: pranalidhanavade * feat: add passkey warning message for unsupported devices Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade * feat: dedicated agent workflow (#693) * feat:Working on dedicated agent workflow Signed-off-by: rohit.shitre * feat/dedicated agent ui form Signed-off-by: pranalidhanavade * feat/ conditional rendering of forms Signed-off-by: pranalidhanavade * feat:add support for dedicated agent Signed-off-by: pranalidhanavade * feat:dedicated agent workflow integration Signed-off-by: pranalidhanavade * feat:dedicated agent workflow integration Signed-off-by: pranalidhanavade * feat:dedicated agent workflow integration Signed-off-by: pranalidhanavade * feat:dedicated agent workflow integration Signed-off-by: pranalidhanavade * feat:dedicated agent workflow integration Signed-off-by: pranalidhanavade * fix: sonarcloud issues Signed-off-by: pranalidhanavade * fix: sonarcloud issues Signed-off-by: pranalidhanavade * fix: sonarcloud issues Signed-off-by: pranalidhanavade * fix: sonarcloud issues Signed-off-by: pranalidhanavade * feat:dedicated agent workflow ui Signed-off-by: pranalidhanavade * feat:dedicated agent workflow Signed-off-by: pranalidhanavade * fix:sonarcloud issues Signed-off-by: pranalidhanavade * fix: duplication issue of sonarcloud Signed-off-by: pranalidhanavade * fix: duplication code issue of sonarcloud Signed-off-by: pranalidhanavade * fix: duplication code issue of sonarcloud Signed-off-by: pranalidhanavade * fix: sonarlint issues Signed-off-by: pranalidhanavade * fix: sonarlint duplication issue Signed-off-by: pranalidhanavade * feat:dedicated agent workflow Signed-off-by: pranalidhanavade * fixed:sonarcloud issues Signed-off-by: pranalidhanavade * fixed:sonarcloud issues Signed-off-by: pranalidhanavade * fix: removed consoles Signed-off-by: pranalidhanavade * feat: support for dedicated agent Signed-off-by: pranalidhanavade * fix: removed consoles Signed-off-by: pranalidhanavade * fix: removed consoles Signed-off-by: pranalidhanavade * fix: removed consoles Signed-off-by: pranalidhanavade * fix: formik validations Signed-off-by: pranalidhanavade * fix:dedicated agent formik validations Signed-off-by: pranalidhanavade * fix: yup formik validations Signed-off-by: pranalidhanavade * fix: static values from enum Signed-off-by: pranalidhanavade --------- Signed-off-by: rohit.shitre Signed-off-by: pranalidhanavade Co-authored-by: rohit.shitre * fix: formik validations for dedicated agent workflow (#708) * feat:Working on dedicated agent workflow Signed-off-by: rohit.shitre * feat/dedicated agent ui form Signed-off-by: pranalidhanavade * feat/ conditional rendering of forms Signed-off-by: pranalidhanavade * feat:add support for dedicated agent Signed-off-by: pranalidhanavade * feat:dedicated agent workflow integration Signed-off-by: pranalidhanavade * feat:dedicated agent workflow integration Signed-off-by: pranalidhanavade * feat:dedicated agent workflow integration Signed-off-by: pranalidhanavade * feat:dedicated agent workflow integration Signed-off-by: pranalidhanavade * feat:dedicated agent workflow integration Signed-off-by: pranalidhanavade * fix: sonarcloud issues Signed-off-by: pranalidhanavade * fix: sonarcloud issues Signed-off-by: pranalidhanavade * fix: sonarcloud issues Signed-off-by: pranalidhanavade * fix: sonarcloud issues Signed-off-by: pranalidhanavade * feat:dedicated agent workflow ui Signed-off-by: pranalidhanavade * feat:dedicated agent workflow Signed-off-by: pranalidhanavade * fix:sonarcloud issues Signed-off-by: pranalidhanavade * fix: duplication issue of sonarcloud Signed-off-by: pranalidhanavade * fix: duplication code issue of sonarcloud Signed-off-by: pranalidhanavade * fix: duplication code issue of sonarcloud Signed-off-by: pranalidhanavade * fix: sonarlint issues Signed-off-by: pranalidhanavade * fix: sonarlint duplication issue Signed-off-by: pranalidhanavade * feat:dedicated agent workflow Signed-off-by: pranalidhanavade * fixed:sonarcloud issues Signed-off-by: pranalidhanavade * fixed:sonarcloud issues Signed-off-by: pranalidhanavade * fix: removed consoles Signed-off-by: pranalidhanavade * feat: support for dedicated agent Signed-off-by: pranalidhanavade * fix: removed consoles Signed-off-by: pranalidhanavade * fix: removed consoles Signed-off-by: pranalidhanavade * fix: removed consoles Signed-off-by: pranalidhanavade * fix: formik validations Signed-off-by: pranalidhanavade * fix:dedicated agent formik validations Signed-off-by: pranalidhanavade * fix: yup formik validations Signed-off-by: pranalidhanavade * fix: static values from enum Signed-off-by: pranalidhanavade * fix: polygon formik validation error Signed-off-by: pranalidhanavade * fix: sonarcloud issues Signed-off-by: pranalidhanavade * fix: sonarcloud issues Signed-off-by: pranalidhanavade --------- Signed-off-by: rohit.shitre Signed-off-by: pranalidhanavade Co-authored-by: rohit.shitre * fix: create did button restrictions (#710) * refactor: parameter name Signed-off-by: bhavanakarwade * refactor: added query parameter Signed-off-by: bhavanakarwade * fix: remove unnecessary code Signed-off-by: bhavanakarwade * fix: query param issue Signed-off-by: bhavanakarwade * fix: css issues Signed-off-by: bhavanakarwade * fix: create did button restrictions Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade * feat: changed schema payload (#711) Signed-off-by: tipusinghaw * feat/delete wallet and organization (#712) * feat: delete organization and wallet Signed-off-by: pranalidhanavade * feat: delete org and wallet Signed-off-by: pranalidhanavade * feat: added custom card component for delet card Signed-off-by: pranalidhanavade * fix: removed consoles Signed-off-by: pranalidhanavade * fix: removed unused code Signed-off-by: pranalidhanavade * changes in delete organization svg image Signed-off-by: pranalidhanavade * changes in delete organization svg image Signed-off-by: pranalidhanavade * fix: resolved comments on pull request Signed-off-by: pranalidhanavade * feat: added custom message for ecosystem lead role Signed-off-by: pranalidhanavade * feat: added interfaces into interface file Signed-off-by: pranalidhanavade * fix: resolved comments on pull request Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade * fix: custom-avatar-css-issues (#714) Signed-off-by: pranalidhanavade * feat: delete wallet and organization (#715) * feat: delete organization and wallet Signed-off-by: pranalidhanavade * feat: delete org and wallet Signed-off-by: pranalidhanavade * feat: added custom card component for delet card Signed-off-by: pranalidhanavade * fix: removed consoles Signed-off-by: pranalidhanavade * fix: removed unused code Signed-off-by: pranalidhanavade * changes in delete organization svg image Signed-off-by: pranalidhanavade * changes in delete organization svg image Signed-off-by: pranalidhanavade * fix: resolved comments on pull request Signed-off-by: pranalidhanavade * feat: added custom message for ecosystem lead role Signed-off-by: pranalidhanavade * feat: added interfaces into interface file Signed-off-by: pranalidhanavade * fix: resolved comments on pull request Signed-off-by: pranalidhanavade * fix: dark mode css issues Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade * refactor: added query parameter in get all schemas API (#713) * refactor: modified bulk issuance payload Signed-off-by: bhavanakarwade * refactor: added query parameter in get all schemas API Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade * refactor: request schema payload (#717) Signed-off-by: bhavanakarwade * fix:client id and secret encryption (#724) Signed-off-by: pranalidhanavade * Client id client secret encryption (#726) * fix:client id and secret encryption Signed-off-by: pranalidhanavade * fix: text changes Signed-off-by: pranalidhanavade * fix: env variable changes Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade * feat: create schema flow for w3c (#718) * feat: create schema flow for w3c Signed-off-by: pranalidhanavade * feat: w3c create schema flow Signed-off-by: pranalidhanavade * fix: removed consoles Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade * wip: verification with email (#722) * wip: email verification Signed-off-by: bhavanakarwade * wip: verification using email Signed-off-by: bhavanakarwade * wip: verification with email Signed-off-by: bhavanakarwade * wip: routes changes for verification dashboard Signed-off-by: bhavanakarwade * wip: routes changes Signed-off-by: bhavanakarwade * wip: Implemented custom dashboard component for veriifcation and issuance dashboard Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade * feat: Implement w3c issuance with connection,email and bulk. (#721) * feat: create schema flow for w3c Signed-off-by: pranalidhanavade * feat: w3c create schema flow Signed-off-by: pranalidhanavade * feat: w3c issuance with connections, email and bulk Signed-off-by: pranalidhanavade * fix: removed console statements Signed-off-by: pranalidhanavade * fix: removed console statements in schema summarycard Signed-off-by: pranalidhanavade * fix: fixed changes in issuance payload for w3c Signed-off-by: pranalidhanavade * feat: w3c issuance astro route changes Signed-off-by: pranalidhanavade * fix: added static values from common enum Signed-off-by: pranalidhanavade * fix: w3c button on card Signed-off-by: pranalidhanavade * fix: comments on pull request Signed-off-by: pranalidhanavade * fix: delete organization pop up description messages Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade * feat: W3C verifcation with connections. (#729) * feat: w3c verification flow Signed-off-by: pranalidhanavade * fix: changes in create schema to remove version for w3c Signed-off-by: pranalidhanavade * fix: removed commnet Signed-off-by: pranalidhanavade * fix: removed comment Signed-off-by: pranalidhanavade * fix: changes in enum file Signed-off-by: pranalidhanavade * fix: removed consoles Signed-off-by: pranalidhanavade * fix: schema creddef popup on verification list Signed-off-by: pranalidhanavade * fix: schema creddef popup on verification list Signed-off-by: pranalidhanavade * fix: sonarlint issues Signed-off-by: pranalidhanavade * fix: sonarlint issues Signed-off-by: pranalidhanavade * fix: sonarlint issues by optimizing code Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade * fiz: removed unwanted code from astro components Signed-off-by: pranalidhanavade * feat: oob verification using email (#732) * wip: email verification Signed-off-by: bhavanakarwade * wip: verification using email Signed-off-by: bhavanakarwade * wip: verification with email Signed-off-by: bhavanakarwade * wip: routes changes for verification dashboard Signed-off-by: bhavanakarwade * wip: routes changes Signed-off-by: bhavanakarwade * wip: Implemented custom dashboard component for veriifcation and issuance dashboard Signed-off-by: bhavanakarwade * wip: oob verification Signed-off-by: bhavanakarwade * feat: oob verification with email Signed-off-by: bhavanakarwade * wip: resolved conflicts Signed-off-by: bhavanakarwade * wip: oob verification with email Signed-off-by: bhavanakarwade * fix: resolved sonarlint issues Signed-off-by: bhavanakarwade * worked on sonarlint issues Signed-off-by: bhavanakarwade * fix: resolved sonar cloud issues Signed-off-by: bhavanakarwade * fix: resolved function name duplication error Signed-off-by: bhavanakarwade * refactor: get schema list details function Signed-off-by: bhavanakarwade * fix: interface issues Signed-off-by: bhavanakarwade * fix: resolved readability issues Signed-off-by: bhavanakarwade * fix: resolved spacing problems Signed-off-by: bhavanakarwade * resolved sonarlint issues Signed-off-by: bhavanakarwade * refactor: interface types Signed-off-by: bhavanakarwade * refactor: remove unnecessary tab list Signed-off-by: bhavanakarwade * fix: refactor enum file Signed-off-by: bhavanakarwade * refactor: common constant changes Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade * fix: W3C issuance schemaName not displayed correctly on ADEYA. (#733) * fix: issuance schemaName issue Signed-off-by: pranalidhanavade * fix: verification breadcrumb fixes Signed-off-by: pranalidhanavade * fix: schema card hover issue Signed-off-by: pranalidhanavade * fix: delete organization delete svg issue Signed-off-by: pranalidhanavade * fix: sonarclous issues Signed-off-by: pranalidhanavade * fix: sonarlint issues duplication error Signed-off-by: pranalidhanavade * fix: added highlight tag for fixing code logic Signed-off-by: pranalidhanavade * fix: added limited attriutes value in common constant file Signed-off-by: pranalidhanavade * fix: resolved comments on pull request Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade * refactor: predicates number vaidations (#734) * wip: email verification Signed-off-by: bhavanakarwade * wip: verification using email Signed-off-by: bhavanakarwade * wip: verification with email Signed-off-by: bhavanakarwade * wip: routes changes for verification dashboard Signed-off-by: bhavanakarwade * wip: routes changes Signed-off-by: bhavanakarwade * wip: Implemented custom dashboard component for veriifcation and issuance dashboard Signed-off-by: bhavanakarwade * wip: oob verification Signed-off-by: bhavanakarwade * feat: oob verification with email Signed-off-by: bhavanakarwade * wip: resolved conflicts Signed-off-by: bhavanakarwade * wip: oob verification with email Signed-off-by: bhavanakarwade * fix: resolved sonarlint issues Signed-off-by: bhavanakarwade * worked on sonarlint issues Signed-off-by: bhavanakarwade * fix: resolved sonar cloud issues Signed-off-by: bhavanakarwade * fix: resolved function name duplication error Signed-off-by: bhavanakarwade * refactor: get schema list details function Signed-off-by: bhavanakarwade * fix: interface issues Signed-off-by: bhavanakarwade * fix: resolved readability issues Signed-off-by: bhavanakarwade * fix: resolved spacing problems Signed-off-by: bhavanakarwade * resolved sonarlint issues Signed-off-by: bhavanakarwade * refactor: interface types Signed-off-by: bhavanakarwade * refactor: remove unnecessary tab list Signed-off-by: bhavanakarwade * fix: refactor enum file Signed-off-by: bhavanakarwade * refactor: common constant changes Signed-off-by: bhavanakarwade * fix: unselected fields validations Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade * Fix verification dashboard changes (#735) * fix: issuance schemaName issue Signed-off-by: pranalidhanavade * fix: verification breadcrumb fixes Signed-off-by: pranalidhanavade * fix: schema card hover issue Signed-off-by: pranalidhanavade * fix: delete organization delete svg issue Signed-off-by: pranalidhanavade * fix: sonarclous issues Signed-off-by: pranalidhanavade * fix: sonarlint issues duplication error Signed-off-by: pranalidhanavade * fix: added highlight tag for fixing code logic Signed-off-by: pranalidhanavade * fix: added limited attriutes value in common constant file Signed-off-by: pranalidhanavade * fix: resolved comments on pull request Signed-off-by: pranalidhanavade * fix: type errors in schemaList Signed-off-by: pranalidhanavade --------- Signed-off-by: pranalidhanavade * fix: email input box issue (#736) * wip: email verification Signed-off-by: bhavanakarwade * wip: verification using email Signed-off-by: bhavanakarwade * wip: verification with email Signed-off-by: bhavanakarwade * wip: routes changes for verification dashboard Signed-off-by: bhavanakarwade * wip: routes changes Signed-off-by: bhavanakarwade * wip: Implemented custom dashboard component for veriifcation and issuance dashboard Signed-off-by: bhavanakarwade * wip: oob verification Signed-off-by: bhavanakarwade * feat: oob verification with email Signed-off-by: bhavanakarwade * wip: resolved conflicts Signed-off-by: bhavanakarwade * wip: oob verification with email Signed-off-by: bhavanakarwade * fix: resolved sonarlint issues Signed-off-by: bhavanakarwade * worked on sonarlint issues Signed-off-by: bhavanakarwade * fix: resolved sonar cloud issues Signed-off-by: bhavanakarwade * fix: resolved function name duplication error Signed-off-by: bhavanakarwade * refactor: get schema list details function Signed-off-by: bhavanakarwade * fix: interface issues Signed-off-by: bhavanakarwade * fix: resolved readability issues Signed-off-by: bhavanakarwade * fix: resolved spacing problems Signed-off-by: bhavanakarwade * resolved sonarlint issues Signed-off-by: bhavanakarwade * refactor: interface types Signed-off-by: bhavanakarwade * refactor: remove unnecessary tab list Signed-off-by: bhavanakarwade * fix: refactor enum file Signed-off-by: bhavanakarwade * refactor: common constant changes Signed-off-by: bhavanakarwade * fix: unselected fields validations Signed-off-by: bhavanakarwade * fix: css issue Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade --------- Signed-off-by: bhavanakarwade Signed-off-by: pranalidhanavade Signed-off-by: rohit.shitre Signed-off-by: tipusinghaw Co-authored-by: deno-deploy[bot] <75045203+deno-deploy[bot]@users.noreply.github.com> Co-authored-by: bhavanakarwade <137506897+bhavanakarwade@users.noreply.github.com> Co-authored-by: bhavanakarwade Co-authored-by: shitrerohit <37360542+shitrerohit@users.noreply.github.com> Co-authored-by: rohit.shitre Co-authored-by: tipusinghaw <126460794+tipusinghaw@users.noreply.github.com> --- src/api/Schema.ts | 22 + src/api/verification.ts | 17 + src/common/enums.ts | 13 +- src/commonComponents/CustomCheckbox.tsx | 80 ++++ src/commonComponents/SchemaCard.tsx | 180 ++++---- src/commonComponents/datatable/index.tsx | 4 +- src/commonComponents/interface.ts | 57 ++- src/components/Issuance/CredDefSelection.tsx | 1 + src/components/Issuance/EmailIssuance.tsx | 34 +- src/components/Issuance/Issuance.tsx | 32 +- .../Resources/Schema/SchemasList.tsx | 38 +- src/components/Tooltip/dataTooltip.tsx | 21 + src/components/Verification/Connections.tsx | 26 +- .../Verification/CredDefSelection.tsx | 7 +- .../Verification/EmailAttributesSelection.tsx | 403 +++++++++++++++++ .../Verification/EmailCredDefSelection.tsx | 192 ++++++++ .../Verification/EmailSchemaSelection.tsx | 10 + .../Verification/EmailVerification.tsx | 404 +++++++++++++++++ .../Verification/SchemaSelection.tsx | 7 +- src/components/Verification/Verification.tsx | 10 +- .../VerificationCredentialList.tsx | 3 +- .../Verification/VerificationDashboard.tsx | 5 +- .../Verification/VerificationSchemasList.tsx | 413 ++++++++++++++++++ src/components/Verification/interface.ts | 82 ++++ .../organization/DeleteOrganizationsCard.tsx | 11 +- .../walletCommonComponents/DedicatedAgent.tsx | 2 +- src/config/CommonConstant.ts | 23 + src/config/apiRoutes.ts | 1 + src/config/pathRoutes.ts | 11 +- .../email/schemas/attributes/index.astro | 14 + .../attributes/verification-email/index.astro | 14 + .../schemas/cred-defs/attributes/index.astro | 4 +- .../attributes/verification-email/index.astro | 15 + .../email/schemas/cred-defs/index.astro | 3 +- .../email/schemas/index.astro | 3 +- .../schemas/connections/index.astro | 17 + .../schemas/connections/verification.astro | 17 + .../schemas/cred-defs/index.astro | 2 +- 38 files changed, 2044 insertions(+), 154 deletions(-) create mode 100644 src/commonComponents/CustomCheckbox.tsx create mode 100644 src/components/Tooltip/dataTooltip.tsx create mode 100644 src/components/Verification/EmailAttributesSelection.tsx create mode 100644 src/components/Verification/EmailCredDefSelection.tsx create mode 100644 src/components/Verification/EmailSchemaSelection.tsx create mode 100644 src/components/Verification/EmailVerification.tsx create mode 100644 src/components/Verification/VerificationSchemasList.tsx create mode 100644 src/pages/organizations/verification/verify-credentials/email/schemas/attributes/index.astro create mode 100644 src/pages/organizations/verification/verify-credentials/email/schemas/attributes/verification-email/index.astro create mode 100644 src/pages/organizations/verification/verify-credentials/email/schemas/cred-defs/attributes/verification-email/index.astro create mode 100644 src/pages/organizations/verification/verify-credentials/schemas/connections/index.astro create mode 100644 src/pages/organizations/verification/verify-credentials/schemas/connections/verification.astro diff --git a/src/api/Schema.ts b/src/api/Schema.ts index 80f18c036..2fafeb825 100644 --- a/src/api/Schema.ts +++ b/src/api/Schema.ts @@ -159,3 +159,25 @@ export const getCredDeffById = async (schemaId: string, orgId: string) => { } } +export const getCredDefDetailsByCredDefId = async (credDefId: string, orgId: string) => { + const token = await getFromLocalStorage(storageKeys.TOKEN) + const details = { + url: `${apiRoutes.organizations.root}/${orgId}${apiRoutes.schema.createCredentialDefinition}/${credDefId}`, + config: { + headers: { + 'Content-type': 'application/json', + 'Authorization': `Bearer ${token}`, + }, + }, + } + + try { + const response = await axiosGet(details) + return response + } + catch (error) { + const err = error as Error + return err?.message + } +} + diff --git a/src/api/verification.ts b/src/api/verification.ts index 317185bfc..dd7aede30 100644 --- a/src/api/verification.ts +++ b/src/api/verification.ts @@ -23,6 +23,23 @@ export const verifyCredential = async (payload: object, requestType:RequestType) } }; +export const createOobProofRequest = async (payload: object, requestType: RequestType) => { + const orgId = await getFromLocalStorage(storageKeys.ORG_ID); + const url = `${apiRoutes.organizations.root}/${orgId}${apiRoutes.Verification.oobProofRequest}?requestType=${requestType}`; + const axiosPayload = { + url, + payload, + config: await getHeaderConfigs(), + }; + + try { + return await axiosPost(axiosPayload); + } catch (error) { + const err = error as Error; + return err?.message; + } +}; + export const getVerificationCredential = async (state: IssueCredential) => { const orgId = await getFromLocalStorage(storageKeys.ORG_ID); const url = `${apiRoutes.Issuance.getIssuedCredentials}?orgId=${orgId}&state=${state}`; diff --git a/src/common/enums.ts b/src/common/enums.ts index c08a80c20..493400253 100644 --- a/src/common/enums.ts +++ b/src/common/enums.ts @@ -139,7 +139,18 @@ export enum SchemaTypes { export enum CredentialType { INDY = 'indy', - JSONLD = 'jsonld' + JSONLD = 'jsonld', +} + +export enum ProtocolVersion { + V1 = 'v1', + V2 = 'v2' +} + +export enum AutoAccept { + ALWAYS = "always", + CONTENT_APPROVED = "contentApproved", + NEVER = "never" } export enum RequestType { diff --git a/src/commonComponents/CustomCheckbox.tsx b/src/commonComponents/CustomCheckbox.tsx new file mode 100644 index 000000000..09a94ac03 --- /dev/null +++ b/src/commonComponents/CustomCheckbox.tsx @@ -0,0 +1,80 @@ +import React, { useEffect, useState } from 'react'; +import { setToLocalStorage } from '../api/Auth'; +import { storageKeys } from '../config/CommonConstant'; +import type { ICustomCheckboxProps, ISchemaData } from './interface'; + +const CustomCheckbox: React.FC = ({ showCheckbox, isVerificationUsingEmail, onChange, schemaData }) => { + const [checked, setChecked] = useState(false); + + useEffect(() => { + if (schemaData) { + try { + const selectedSchemas = JSON.parse(localStorage.getItem('selectedSchemas') ?? '[]'); + const isChecked = selectedSchemas.some((schema: ISchemaData) => schema.schemaId === schemaData.schemaId); + setChecked(isChecked); + } catch (error) { + console.error('Error parsing JSON from localStorage:', error); + } + } + }, [schemaData]); + + const handleCheckboxChange = async () => { + const newChecked = !checked; + setChecked(newChecked); + onChange(newChecked, schemaData); + + try { + const selectedSchemas = JSON.parse(localStorage.getItem('selectedSchemas') ?? '[]'); + + if (newChecked) { + selectedSchemas.push(schemaData); + } else { + const index = selectedSchemas.findIndex((schema: ISchemaData) => schema.schemaId === schemaData?.schemaId); + if (index > -1) { + selectedSchemas.splice(index, 1); + } + } + await setToLocalStorage(storageKeys.SELECTED_SCHEMAS, JSON.stringify(selectedSchemas)); + } catch (error) { + console.error('Error updating localStorage:', error); + } + }; + + return ( + <> + {showCheckbox && ( + + )} + + ); +}; + +export default CustomCheckbox; diff --git a/src/commonComponents/SchemaCard.tsx b/src/commonComponents/SchemaCard.tsx index 7b25fed9a..e00d582a2 100644 --- a/src/commonComponents/SchemaCard.tsx +++ b/src/commonComponents/SchemaCard.tsx @@ -1,23 +1,51 @@ import { Button, Card } from 'flowbite-react'; import { dateConversion } from '../utils/DateConversion'; import DateTooltip from '../components/Tooltip'; +import DataTooltip from '../components/Tooltip/dataTooltip' + import CopyDid from './CopyDid'; -import React, { useEffect } from 'react'; +import { useEffect } from 'react'; import { pathRoutes } from '../config/pathRoutes'; import { getFromLocalStorage } from '../api/Auth'; -import { storageKeys } from '../config/CommonConstant'; -import type { ISchemaCardProps } from './interface'; +import { limitedAttributesLength, storageKeys } from '../config/CommonConstant'; +import type { IAttribute, ISchemaCardProps, ISchemaData } from './interface'; +import CustomCheckbox from './CustomCheckbox'; -const SchemaCard = (props: ISchemaCardProps) => { - const orgDidDetails = async ()=>{ +const SchemaCard = (props: ISchemaCardProps) => { + const orgDidDetails = async () => { const orgDid = await getFromLocalStorage(storageKeys.ORG_DID) } useEffect(() => { - orgDidDetails(); - }, []); - + orgDidDetails(); + }, []); + const attributes = props.limitedAttributes !== false ? props?.attributes?.slice(0, 3) : props?.attributes - + + const AttributesList: React.FC<{ attributes: IAttribute[], limitedAttributes?: boolean }> = ({ attributes, limitedAttributes }) => { + const isLimited = limitedAttributes !== false && attributes.length > limitedAttributesLength; + const displayedAttributes = isLimited ? attributes.slice(0, 3) : attributes; + + return ( +
+
+ Attributes: +
+ {displayedAttributes.map((element) => ( +
+ + {element?.attributeName} + +
+ ))} + {isLimited && ...} +
+
+
+ ); +} const handleButtonClick = () => { if (props.onClickW3cIssue) { @@ -25,46 +53,72 @@ const SchemaCard = (props: ISchemaCardProps) => { } }; +const handleCheckboxChange = (checked: boolean, schemaData?: ISchemaData) => { + + if (props.onChange) { + if (schemaData) { + props.onChange(checked, [schemaData]); + } else { + props.onChange(checked, []); + } + } +}; + return ( - { + { + if (!props.w3cSchema) { props.onClickCallback(props.schemaId, props.attributes, props.issuerDid, props.created) } + + if (props.w3cSchema) { + const W3CSchemaData = { + schemaId: props.schemaId, + schemaName: props.schemaName, + version: props.version, + issuerDid: props.issuerDid, + attributes: props.attributes, + created: props.created, + }; + + props.onClickW3CCallback(W3CSchemaData); +} }} id="schema-cards" - className={`transform transition duration-500 ${(props.isClickable !== false && !props.w3cSchema) ? "hover:scale-105 hover:bg-gray-50 cursor-pointer" : "hover:!cursor-default"} h-full w-full overflow-hidden`}> + className={`transform transition duration-500 ${props.w3cSchema ? "" : (props.isClickable !== false) ? "hover:scale-105 hover:bg-gray-50 cursor-pointer" : "hover:!cursor-default"} h-full w-full overflow-hidden`} + >
-
+
{props.schemaName}
- +

Version: {props.version}

- {props.w3cSchema && ( - - W3C - - )} + {props.w3cSchema && ( + + W3C + + )}
- +
Created: {dateConversion(props.created)} - -
+ +
@@ -77,39 +131,32 @@ const SchemaCard = (props: ISchemaCardProps) => {

Issuer DID: - +

{!props.noLedger && -

- Ledger: {props?.issuerDid?.split(":")[2]} -

+

+ Ledger: {props?.issuerDid?.split(":")[2]} +

}
-
- Attributes: -
- {attributes && attributes.length > 0 && ( - <> - {attributes?.map((element) => ( -
- - {element?.attributeName} - -
- ))} - {props?.limitedAttributes !== false && props?.attributes?.length > 3 && ...} - - )} -
-
+ {props.w3cSchema ? ( + attribute.attributeName} + > + + + + ) : ( + + + + )}
- {props.w3cSchema && !props.isVerification && ( + {props.w3cSchema && !props.isVerification && !props.isVerificationUsingEmail && (
)} - - {props.isVerification && props.w3cSchema &&( -
- -
- )}
+ + {props.showCheckbox && ( + + )} +
) } diff --git a/src/commonComponents/datatable/index.tsx b/src/commonComponents/datatable/index.tsx index dd534fec1..da7b090d5 100644 --- a/src/commonComponents/datatable/index.tsx +++ b/src/commonComponents/datatable/index.tsx @@ -8,6 +8,7 @@ interface DataTableProps { callback?: (clickId: string | null | undefined) => void; displaySelect?: boolean; showBtn?: boolean; + isEmailVerification?: boolean; } const DataTable: React.FC = ({ @@ -17,6 +18,7 @@ const DataTable: React.FC = ({ loading, callback, showBtn, + isEmailVerification }) => { return (
@@ -37,7 +39,7 @@ const DataTable: React.FC = ({
{ele.columnName}
{ele.subColumnName && ( diff --git a/src/commonComponents/interface.ts b/src/commonComponents/interface.ts index 91defea17..272af59f9 100644 --- a/src/commonComponents/interface.ts +++ b/src/commonComponents/interface.ts @@ -10,20 +10,53 @@ export interface IProps { setSuccess: (flag: string | null) => void; } +export interface IAttribute { + attributeName: string; + schemaDataType: string; + displayName: string; + isRequired: boolean; +} + +export interface ISchemaData { + schemaId: string; + schemaName: string; + attributes: IAttribute[]; +} + +export interface ICustomCheckboxProps { + showCheckbox: boolean; + isVerificationUsingEmail?: boolean; + onChange: (checked: boolean, schemaData?: ISchemaData) => void; + schemaData?: ISchemaData; + } export interface ISchemaCardProps { - className?: string, - schemaName: string, - version: string, - schemaId: string, - issuerDid: string, - attributes: [], - created: string, - isClickable?: boolean + className?: string; + schemaName: string; + version: string; + schemaId: string; + issuerDid: string; + attributes: []; + created: string; + isClickable?: boolean; + showCheckbox?: boolean; onClickCallback: (schemaId: string, attributes: string[], issuerDid: string, created: string) => void; + + onClickW3CCallback: (W3CSchemaData: { + schemaId: string; + schemaName: string; + version: string; + issuerDid: string; + attributes: []; + created: string; + }) => void; + onClickW3cIssue?: (schemaId: string, schemaName: string, version: string, issuerDid: string, attributes: [], created: string) => void; - limitedAttributes?: boolean - w3cSchema:boolean - noLedger:boolean - isVerification?:boolean + onChange?: (checked: boolean, schemaData: ISchemaData[]) => void; + limitedAttributes?: boolean; + onSelectionChange?: (selectedSchemas: any[]) => void; + w3cSchema?:boolean; + noLedger?:boolean; + isVerification?: boolean; + isVerificationUsingEmail?: boolean; } \ No newline at end of file diff --git a/src/components/Issuance/CredDefSelection.tsx b/src/components/Issuance/CredDefSelection.tsx index ed9dca7b8..0f527646f 100644 --- a/src/components/Issuance/CredDefSelection.tsx +++ b/src/components/Issuance/CredDefSelection.tsx @@ -163,6 +163,7 @@ const CredDefSelection = () => { created={schemaDetailsState.createdDateTime} onClickCallback={schemaSelectionCallback} isClickable={false} + showCheckbox={false} limitedAttributes={false} />
diff --git a/src/components/Issuance/EmailIssuance.tsx b/src/components/Issuance/EmailIssuance.tsx index c6bddcdb5..badf364e6 100644 --- a/src/components/Issuance/EmailIssuance.tsx +++ b/src/components/Issuance/EmailIssuance.tsx @@ -103,6 +103,7 @@ const EmailIssuance = () => { JSON.parse(schemaAttributes), })); setCredentialOptions(options); + } else { setSuccess(null); @@ -140,6 +141,7 @@ const EmailIssuance = () => { setIssueLoader(true); const existingData = userData; + const organizationDid = await getFromLocalStorage(storageKeys.ORG_DID); let transformedData: ITransformedData = { credentialOffer: [] }; @@ -160,8 +162,10 @@ const EmailIssuance = () => { transformedData.credentialOffer.push(transformedEntry); }); transformedData.credentialDefinitionId = credDefId; + } else if (schemaType=== SchemaTypes.schema_W3C) { + existingData.formData.forEach((entry: { email: string; credentialData: IEmailCredentialData; attributes:IIssueAttributes[] }) => { const credentialOffer = { emailId: entry.email, @@ -172,27 +176,25 @@ const EmailIssuance = () => { ], "type": [ "VerifiableCredential", - credentialOptions[0].schemaName + credentialSelected?.schemaName ], "issuer": { "id": organizationDid }, "issuanceDate": new Date().toISOString(), - - credentialSubject: entry?.attributes?.reduce((acc, attr) => { - if (attr.value === null && !attr.isRequired && typeof attr.value === 'number') { - return acc; - } else { - if (attr.name === 'rollno' && attr.value === '') { - return acc; - } else { - acc[attr.name] = attr.value; - return acc; - } - } - }, { - }), - }, + + //FIXME: Logic for passing default value as 0 for empty value of number dataType attributes. + credentialSubject: entry?.attributes?.reduce((acc, attr) => { + if (attr.schemaDataType === 'number' && (attr.value === '' || attr.value === null)) { + acc[attr.name] = 0; + } else if (attr.schemaDataType === 'string' && attr.value === '') { + acc[attr.name] = ''; + } else if (attr.value !== null) { + acc[attr.name] = attr.value; + } + return acc; + }, {}), + }, options: { proofType: schemaTypeValue===SchemaTypeValue.POLYGON ? ProofType.polygon : ProofType.no_ledger, proofPurpose: proofPurpose diff --git a/src/components/Issuance/Issuance.tsx b/src/components/Issuance/Issuance.tsx index b2f1a5723..7a3f0ee9c 100644 --- a/src/components/Issuance/Issuance.tsx +++ b/src/components/Issuance/Issuance.tsx @@ -194,7 +194,6 @@ const IssueCred = () => { setUserLoader(false); }; - const createAttributeValidationSchema = ( name: string, value: string, @@ -333,21 +332,23 @@ const getSelectedUsers = async (): Promise => { "id": w3cSchemaDetails.issuerDid }, issuanceDate: new Date().toISOString(), + //FIXME: Logic for passing default value as 0 for empty value of number dataType attributes. credentialSubject: item?.attributes?.reduce((acc, attr) => { - if (attr.value === null && !attr.isRequired && typeof attr.value === 'number') { - return acc; - } else { - if (attr.name === 'rollno' && attr.value === '') { - return acc; - } else { - acc[attr.name] = attr.value; - return acc; - } - } - }, { - }), - }, - + + if (attr.dataType === 'number' && (attr.value === '' || attr.value === null)) { + + acc[attr.name] = 0; + } else if (attr.dataType === 'string' && attr.value === '') { + + acc[attr.name] = ''; + } else if (attr.value !== null) { + + acc[attr.name] = attr.value; + } + return acc; + }, {}), + }, + options: { proofType: schemaType=== SchemaTypeValue.POLYGON ? ProofType.polygon : ProofType.no_ledger, proofPurpose: proofPurpose @@ -356,6 +357,7 @@ const getSelectedUsers = async (): Promise => { }), orgId: values.orgId, }; + } const convertedAttributesValues = { diff --git a/src/components/Resources/Schema/SchemasList.tsx b/src/components/Resources/Schema/SchemasList.tsx index 22b0fa0f8..0c3760db6 100644 --- a/src/components/Resources/Schema/SchemasList.tsx +++ b/src/components/Resources/Schema/SchemasList.tsx @@ -14,7 +14,7 @@ import { EmptyListMessage } from '../../EmptyListComponent'; import { Features } from '../../../utils/enums/features'; import RoleViewButton from '../../RoleViewButton'; import SchemaCard from '../../../commonComponents/SchemaCard'; -import type { SchemaDetails } from '../../Verification/interface'; +import type { IW3cSchemaDetails, SchemaDetails } from '../../Verification/interface'; import SearchInput from '../../SearchInput'; import { getFromLocalStorage, setToLocalStorage } from '../../../api/Auth'; import { pathRoutes } from '../../../config/pathRoutes'; @@ -30,6 +30,12 @@ const SchemaList = (props: { schemaId: string, schemaDetails: SchemaDetails, ) => void; + + W3CSchemaSelectionCallback: ( + schemaId: string, + w3cSchemaDetails: IW3cSchemaDetails, + ) => void; + verificationFlag?: boolean; }) => { @@ -148,6 +154,34 @@ const SchemaList = (props: { props.schemaSelectionCallback(schemaId, schemaDetails); }; + const W3CSchemaSelectionCallback = async ({ + schemaId, + schemaName, + version, + issuerDid, + attributes, + created, + }: { + schemaId: string, + schemaName: string, + version: string, + issuerDid: string, + attributes: [], + created: string + }) => { + const w3cSchemaDetails = { + schemaId, + schemaName, + version, + issuerDid, + attributes, + created, + }; + props.W3CSchemaSelectionCallback(schemaId, w3cSchemaDetails); + await setToLocalStorage(storageKeys.W3C_SCHEMA_DATA, w3cSchemaDetails); + }; + + const handleW3CIssue = async ( schemaId: string, schemaName: string, @@ -304,7 +338,9 @@ const SchemaList = (props: { issuerDid={element['issuerId']} attributes={element['attributes']} created={element['createDateTime']} + showCheckbox={false} onClickCallback={schemaSelectionCallback} + onClickW3CCallback={W3CSchemaSelectionCallback} onClickW3cIssue={handleW3CIssue} w3cSchema={w3cSchema} noLedger={isNoLedger} diff --git a/src/components/Tooltip/dataTooltip.tsx b/src/components/Tooltip/dataTooltip.tsx new file mode 100644 index 000000000..41e885046 --- /dev/null +++ b/src/components/Tooltip/dataTooltip.tsx @@ -0,0 +1,21 @@ +import { Tooltip } from 'flowbite-react'; +import React from 'react'; + +interface TooltipProps { + data: Type[]; + renderItem: (item: Type) => string; + id?: string; + children?: React.ReactNode; +} + +const DataTooltip = ({ data, renderItem, children }: TooltipProps) => { + const content = data.map(renderItem).join(', '); + + return ( + + {children} + + ); +}; + +export default DataTooltip; diff --git a/src/components/Verification/Connections.tsx b/src/components/Verification/Connections.tsx index ffa84f497..1abf872ef 100644 --- a/src/components/Verification/Connections.tsx +++ b/src/components/Verification/Connections.tsx @@ -1,7 +1,7 @@ import { Button } from "flowbite-react"; -import { useState } from "react"; -import { setToLocalStorage } from "../../api/Auth"; +import { useEffect, useState } from "react"; +import { getFromLocalStorage, setToLocalStorage } from "../../api/Auth"; import DataTable from "../../commonComponents/datatable"; import type { TableData } from "../../commonComponents/datatable/interface"; import { storageKeys } from "../../config/CommonConstant"; @@ -10,8 +10,10 @@ import BreadCrumbs from "../BreadCrumbs"; import ConnectionList from "./ConnectionList"; import EmailList from "./EmailList"; import BackButton from '../../commonComponents/backbutton' +import { DidMethod } from "../../common/enums"; const Connections = () => { + const [isW3cDid, setIsW3cDid] = useState(false); const [selectedConnectionList, setSelectedConnectionList] = useState([]) const selectedConnectionHeader = [ { columnName: 'User' }, @@ -21,13 +23,25 @@ const Connections = () => { const selectConnection = (connections: TableData[]) => { setSelectedConnectionList(connections) } + const fetchOrgData = async () => { + const orgDid = await getFromLocalStorage(storageKeys.ORG_DID); + + if (orgDid.includes(DidMethod.POLYGON) || orgDid.includes(DidMethod.KEY) || orgDid.includes(DidMethod.WEB)) { + setIsW3cDid(true); + } else { + setIsW3cDid(false); + } + }; + useEffect(() => { + fetchOrgData(); + }, []); const continueToVerify = async () => { const selectedConnections = selectedConnectionList.map(ele =>{ return {userName: ele.data[0].data, connectionId:ele.data[1].data} }) await setToLocalStorage(storageKeys.SELECTED_USER, selectedConnections) - window.location.href = `${pathRoutes.organizations.verification.verify}` + window.location.href = isW3cDid ? `${pathRoutes.organizations.verification.W3CVerification}` : `${pathRoutes.organizations.verification.verify}` } return ( @@ -44,18 +58,12 @@ const Connections = () => {
  • -
  • - -
  • -
    - -

    diff --git a/src/components/Verification/CredDefSelection.tsx b/src/components/Verification/CredDefSelection.tsx index 6bc5847e6..3f3030364 100644 --- a/src/components/Verification/CredDefSelection.tsx +++ b/src/components/Verification/CredDefSelection.tsx @@ -124,7 +124,7 @@ const CredDefSelection = () => {
    - +

    Schema @@ -137,7 +137,10 @@ const CredDefSelection = () => {

    :
    -
    } diff --git a/src/components/Verification/EmailAttributesSelection.tsx b/src/components/Verification/EmailAttributesSelection.tsx new file mode 100644 index 000000000..905c70936 --- /dev/null +++ b/src/components/Verification/EmailAttributesSelection.tsx @@ -0,0 +1,403 @@ + +import { Alert, Button } from 'flowbite-react'; +import { useEffect, useState } from 'react'; +import { getFromLocalStorage, setToLocalStorage } from '../../api/Auth'; +import { apiStatusCodes, predicatesConditions, storageKeys } from '../../config/CommonConstant'; +import BreadCrumbs from '../BreadCrumbs'; +import DataTable from '../../commonComponents/datatable'; +import type { TableData } from '../../commonComponents/datatable/interface'; +import { pathRoutes } from '../../config/pathRoutes'; +import BackButton from '../../commonComponents/backbutton'; +import type { + ISelectedAttributes, +} from './interface'; +import CustomCheckbox from '../../commonComponents/CustomCheckbox'; +import { getOrganizationById } from '../../api/organization'; +import type { AxiosResponse } from 'axios'; +import { DidMethod } from '../../common/enums'; + +const EmailAttributesSelection = () => { + const [attributeList, setAttributeList] = useState([]); + const [proofReqSuccess, setProofReqSuccess] = useState(null); + const [errMsg, setErrMsg] = useState(null); + const [display, setDisplay] = useState(false); + const [loading, setLoading] = useState(true); + const [attributeData, setAttributeData] = useState( + null, + ); + const [w3cSchema, setW3cSchema] = useState(false); + + const handleAttributeChange = async ( + attributeName: string, + schemaId: string | undefined, + changeType: 'checkbox' | 'input' | 'select', + value: string | boolean, + ) => { + const updatedAttributes = attributeData?.map(attribute => { + if (attribute.attributeName === attributeName && attribute.schemaId === schemaId) { + switch (changeType) { + case 'checkbox': + return { + ...attribute, + isChecked: value as boolean, + value: attribute?.value || '', + selectedOption: attribute?.condition || 'Select', + inputError: '', + selectError: '', + }; + case 'input': + return { + ...attribute, + value: value as string, + inputError: '', + }; + case 'select': + return { + ...attribute, + selectedOption: value as string, + selectError: '', + }; + default: + return attribute; + } + } + return attribute; + }) ?? []; + + setAttributeData(updatedAttributes); + + await setToLocalStorage(storageKeys.ATTRIBUTE_DATA, JSON.stringify(updatedAttributes)); + }; + + + const getOrgDetails = async () => { + setLoading(true); + const orgId = await getFromLocalStorage(storageKeys.ORG_ID); + const response = await getOrganizationById(orgId); + const { data } = response as AxiosResponse; + if (data?.statusCode === apiStatusCodes.API_STATUS_SUCCESS) { + const did = data?.data?.org_agents?.[0]?.orgDid; + + if (did.includes(DidMethod.POLYGON) || did.includes(DidMethod.KEY) || did.includes(DidMethod.WEB)) { + setW3cSchema(true); + }else if (did.includes(DidMethod.INDY)) { + setW3cSchema(false); + } + } + + setLoading(false); + }; + + useEffect(() => { + getOrgDetails(); + }, []); + + + const handleSubmit = () => { + setErrMsg(null); + + if (w3cSchema) { + redirectToAppropriatePage(); + return; + } + + if (hasInvalidNumberAttributes()) { + return; + } + + redirectToAppropriatePage(); + }; + + const hasInvalidNumberAttributes = (): boolean => { + const numberAttributes = attributeData?.filter( + (attr) => attr.dataType === 'number' && attr.isChecked + ); + + for (const attribute of numberAttributes || []) { + if (isInvalidNumberAttribute(attribute)) { + return true; + } + } + + return false; + }; + + const isInvalidNumberAttribute = (attribute: any): boolean => { + if (attribute.selectedOption === 'Select' && !attribute.value) { + setErrMsg('Condition and value are required'); + return true; + } else if (!attribute.value) { + setErrMsg('Value is required'); + return true; + } else if (!attribute.selectedOption) { + setErrMsg('Condition is required'); + return true; + } + + return false; + }; + + const redirectToAppropriatePage = () => { + window.location.href = w3cSchema + ? `${pathRoutes.organizations.verification.w3cEmailVerification}` + : `${pathRoutes.organizations.verification.emailVerification}`; + }; + + const loadAttributesData = async () => { + + setLoading(true); + + try { + setAttributeData([]); + + if (w3cSchema) { + const getW3CSchemaDetails = await getFromLocalStorage(storageKeys.SELECTED_SCHEMAS); + const parsedW3CSchemaDetails = JSON.parse(getW3CSchemaDetails || '[]'); + + if (Array.isArray(parsedW3CSchemaDetails) && parsedW3CSchemaDetails.length > 0) { + const allAttributes = parsedW3CSchemaDetails.flatMap(schema => { + if (schema.attributes && Array.isArray(schema.attributes)) { + return schema.attributes.map(attribute => ({ + ...attribute, + schemaName: schema.name, + credDefName: '', + schemaId: schema.schemaLedgerId, + credDefId: '' + })); + } + return []; + }); + + const inputArray = allAttributes.map(attribute => ({ + displayName: attribute.displayName, + attributeName: attribute.attributeName, + isChecked: false, + value: '', + condition: '', + options: predicatesConditions, + dataType: attribute.schemaDataType, + schemaName: attribute.schemaName, + credDefName: attribute.credDefName, + schemaId: attribute.schemaId, + credDefId: attribute.credDefId, + selectedOption: 'Select', + inputError: '', + selectError: '' + })); + + setAttributeData(inputArray); + } else { + console.error('W3C schema details are not in the expected format.'); + } + + } else { + const getSelectedCredDefData = await getFromLocalStorage(storageKeys.CRED_DEF_DATA); + const selectedCredDefs = JSON.parse(getSelectedCredDefData || '[]'); + + const schemaAttributes = await getFromLocalStorage(storageKeys.SCHEMA_ATTRIBUTES); + const parsedSchemaDetails = JSON.parse(schemaAttributes || '[]'); + + + if (Array.isArray(parsedSchemaDetails) && parsedSchemaDetails.length > 0) { + const allAttributes = parsedSchemaDetails.flatMap(schema => { + if (schema.attributes && Array.isArray(schema.attributes)) { + return schema.attributes.flatMap(attribute => { + const matchingCredDefs = selectedCredDefs.filter( + credDef => credDef.schemaLedgerId === schema.schemaId + ); + + return matchingCredDefs.map(credDef => ({ + displayName: attribute.displayName, + attributeName: attribute.attributeName, + isChecked: false, + value: '', + condition: '', + options: predicatesConditions, + dataType: attribute.schemaDataType, + schemaName: schema.schemaId.split(':')[2], + credDefName: credDef.tag, + schemaId: schema.schemaId, + credDefId: credDef.credentialDefinitionId, + selectedOption: 'Select', + inputError: '', + selectError: '' + })); + }); + } + return []; + }); + + setAttributeData(allAttributes); + } else { + console.error('Parsed schema details are not in the expected format.'); + } + } + } catch (error) { + console.error('Error fetching data:', error); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + loadAttributesData(); + }, [w3cSchema]); + + + const attributeFunction = async () => { + const attributes = attributeData?.map((attribute: ISelectedAttributes) => { + return { + data: [ + { + data: ( +
    + { + handleAttributeChange(attribute?.attributeName, attribute?.schemaId, 'checkbox', checked); + }} + /> +
    + ), + }, + { data: attribute?.displayName }, + { + data: !w3cSchema && ( +
    + {attribute?.dataType === 'number' && ( + + )} + {attribute?.selectError && ( +
    + {attribute?.selectError} +
    + )} +
    + ), + }, + { + data: !w3cSchema && ( +
    + {attribute?.dataType === 'number' && ( + + handleAttributeChange(attribute?.attributeName, attribute?.schemaId, 'input', e.target.value) + } + disabled={!attribute?.isChecked} + className={`${!attribute?.isChecked + ? 'opacity-50 cursor-not-allowed' + : 'cursor-pointer' + } p-1 border border-black rounded-md dark:text-gray-200 dark:bg-gray-700 dark:border-gray-300 dark:placeholder-gray-400 dark:text-white`} + /> + )} + {attribute?.inputError && ( +
    + {attribute?.inputError} +
    + )} +
    + ), + }, + { data: attribute.schemaName }, + { data: attribute.credDefName }, + ], + }; + }); + + setAttributeList(attributes); + setDisplay(attributeData?.some((attribute) => attribute?.dataType === 'number')); + }; + + + useEffect(() => { + attributeData && attributeFunction(); + }, [attributeData]); + + const header = [ + { columnName: '', width: 'w-0.5' }, + { columnName: 'Attributes' }, + display && !w3cSchema && { columnName: 'Condition' }, + display && !w3cSchema && { columnName: 'Value', width: 'w-0.75' }, + { columnName: 'Schema Name' }, + !w3cSchema && { columnName: 'Cred Def Name' }, + ]; + + return ( +
    +
    +
    + + +
    +
    + + {(proofReqSuccess || errMsg) && ( +
    + { + setProofReqSuccess(null); + setErrMsg(null); + }} + > + {proofReqSuccess ?? errMsg} + +
    + )} +
    +

    + Attributes +

    +
    +
    + +
    + +
    + +
    +
    + ); +}; + +export default EmailAttributesSelection; + diff --git a/src/components/Verification/EmailCredDefSelection.tsx b/src/components/Verification/EmailCredDefSelection.tsx new file mode 100644 index 000000000..aeddbaaff --- /dev/null +++ b/src/components/Verification/EmailCredDefSelection.tsx @@ -0,0 +1,192 @@ +import { Button } from "flowbite-react"; +import React, { useEffect, useState, type ChangeEvent } from "react"; +import { getFromLocalStorage, removeFromLocalStorage, setToLocalStorage } from "../../api/Auth"; +import { apiStatusCodes, emailCredDefHeaders, storageKeys } from "../../config/CommonConstant"; +import { pathRoutes } from "../../config/pathRoutes"; +import BreadCrumbs from "../BreadCrumbs"; +import { AlertComponent } from "../AlertComponent"; +import type { CredDefData } from "./interface"; +import type { TableData } from "../../commonComponents/datatable/interface"; +import DataTable from "../../commonComponents/datatable"; +import { getCredentialDefinitionsForVerification } from "../../api/verification"; +import BackButton from '../../commonComponents/backbutton'; +import SearchInput from '../SearchInput'; +import { getSchemaById } from "../../api/Schema"; +import type { AxiosResponse } from "axios"; +import CustomCheckbox from "../../commonComponents/CustomCheckbox"; + +const EmailCredDefSelection = () => { + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const [credDefList, setCredDefList] = useState([]); + const [searchValue, setSearchValue] = useState(''); + const [selectedCredDefs, setSelectedCredDefs] = useState([]); + + useEffect(() => { + const fetchData = async () => { + await removeFromLocalStorage(storageKeys.CRED_DEF_ID); + getSchemaAndCredDef(); + }; + + fetchData(); + }, []); + + const getSchemaAndCredDef = async () => { + try { + const schemaIdsJSON = await getFromLocalStorage(storageKeys.SCHEMA_IDS); + const schemaIds = schemaIdsJSON ? JSON.parse(schemaIdsJSON) : []; + + if (schemaIds && schemaIds.length > 0) { + getCredDefs(schemaIds); + } + } catch (error) { + console.error('Error fetching schema details:', error); + } + }; + + const handleContinue = () => { + window.location.href = `${pathRoutes.organizations.verification.attributes}`; + }; + + const getCredDefs = async (schemaIds: string[]) => { + setLoading(true); + const orgId = await getFromLocalStorage(storageKeys.ORG_ID); + let allCredDefs: TableData[] = []; + let rawCredDefs: CredDefData[] = []; + + for (const schemaId of schemaIds) { + try { + const response = await getCredentialDefinitionsForVerification(schemaId); + + const { data } = response as AxiosResponse; + + if (data?.statusCode === apiStatusCodes.API_STATUS_SUCCESS) { + const getSchemaDetails = await getSchemaById(schemaId, orgId); + const schemaName = getSchemaDetails?.data?.data?.schema?.name; + + const credDefs = data?.data?.map((ele: CredDefData) => { + rawCredDefs.push(ele); + + return { + data: [ + { + data: ( +
    + + { + selectConnection(ele?.credentialDefinitionId, checked); + }} + /> + {ele?.tag ? ele?.tag : 'Not available'} +
    + ) + }, + { data: schemaName || 'Not available' }, + { data: ele?.revocable === true ? Yes : No } + ] + }; + }); + + allCredDefs = [...allCredDefs, ...credDefs]; + + } else { + console.error(`Error fetching credential definitions for schema ${schemaId}`); + } + } catch (error) { + console.error(`Error fetching credential definitions for schema ${schemaId}:`, error); + } + } + + setLoading(false); + setCredDefList(allCredDefs); + await setToLocalStorage(storageKeys.SCHEMA_CRED_DEFS, rawCredDefs); + + if (allCredDefs.length === 0) { + setError('No Credential Definitions Found'); + } + }; + + const selectConnection = async (credDefId: string, checked: boolean) => { + if (credDefId) { + const getRawCredDefs = await getFromLocalStorage(storageKeys.SCHEMA_CRED_DEFS); + const parsedRawCredDefs = JSON.parse(getRawCredDefs); + + const selectedCredDef = parsedRawCredDefs.find((credDef: CredDefData) => credDef.credentialDefinitionId === credDefId); + + if (selectedCredDef) { + setSelectedCredDefs((prevSelected) => { + const isAlreadySelected = prevSelected.some( + (credDef) => credDef.credentialDefinitionId === selectedCredDef.credentialDefinitionId + ); + + if (!isAlreadySelected) { + const newSelected = [...prevSelected, selectedCredDef]; + + setToLocalStorage(storageKeys.CRED_DEF_DATA, JSON.stringify(newSelected)); + + return newSelected; + } + return prevSelected; + }); + } + } + else if (!checked) { + setSelectedCredDefs((prevSelected) => { + const newSelected = prevSelected.filter( + (credDef) => credDef.credentialDefinitionId !== credDefId + ); + + setToLocalStorage(storageKeys.CRED_DEF_DATA, JSON.stringify(newSelected)); + + return newSelected; + }); + } + }; + + + return ( +
    +
    +
    + + +
    +
    +

    + Credential-definition +

    + ) => setSearchValue(e.target.value)} /> +
    +
    + + {error && ( + { + setError(null); + }} + /> + )} + { }} /> +
    + +
    +
    + ); +}; + +export default EmailCredDefSelection; + diff --git a/src/components/Verification/EmailSchemaSelection.tsx b/src/components/Verification/EmailSchemaSelection.tsx new file mode 100644 index 000000000..4b78a4404 --- /dev/null +++ b/src/components/Verification/EmailSchemaSelection.tsx @@ -0,0 +1,10 @@ +import VerificationSchemasList from "./VerificationSchemasList"; + +const EmailSchemaSelection = () => { + + return ( + + ) +} + +export default EmailSchemaSelection; diff --git a/src/components/Verification/EmailVerification.tsx b/src/components/Verification/EmailVerification.tsx new file mode 100644 index 000000000..e01ee3e1e --- /dev/null +++ b/src/components/Verification/EmailVerification.tsx @@ -0,0 +1,404 @@ +import { useEffect, useState } from 'react'; +import * as Yup from 'yup'; +import BreadCrumbs from '../BreadCrumbs'; +import { Button } from 'flowbite-react'; +import { Field, Form, Formik } from 'formik'; +import { apiStatusCodes, storageKeys } from '../../config/CommonConstant'; +import { createOobProofRequest } from '../../api/verification'; +import { AutoAccept, DidMethod, ProtocolVersion, RequestType } from '../../common/enums'; +import type { AxiosResponse } from 'axios'; +import { getFromLocalStorage, removeFromLocalStorage } from '../../api/Auth'; +import type { IEmailValues, IPredicate, IRequestedAttributes, ISelectedAttributes } from './interface'; +import { getOrganizationById } from '../../api/organization'; +import { pathRoutes } from '../../config/pathRoutes'; +import { AlertComponent } from '../AlertComponent'; +import React from 'react'; + +const EmailVerification = () => { + const [loading, setLoading] = useState(false); + const [errorMessage, setErrorMessage] = useState(null); + const [emailInputs, setEmailInputs] = useState([{ value: '' }]); + const [w3cSchema, setW3cSchema] = useState(false); + + const handleInputChange = (index: number, event: React.ChangeEvent) => { + const newEmailInputs = [...emailInputs]; + newEmailInputs[index].value = event.target.value; + setEmailInputs(newEmailInputs); + }; + + const handleAddInput = () => { + setEmailInputs([...emailInputs, { value: '' }]); + }; + + const handleDeleteInput = (index: number) => { + if (emailInputs.length > 1) { + const newEmailInputs = emailInputs.filter((_, i) => i !== index); + setEmailInputs(newEmailInputs); + } + }; + + const getOrganizationDetails = async () => { + setLoading(true); + const orgId = await getFromLocalStorage(storageKeys.ORG_ID); + const response = await getOrganizationById(orgId); + const { data } = response as AxiosResponse; + if (data?.statusCode === apiStatusCodes.API_STATUS_SUCCESS) { + const did = data?.data?.org_agents?.[0]?.orgDid; + + if (did.includes(DidMethod.POLYGON) || did.includes(DidMethod.KEY) || did.includes(DidMethod.WEB)) { + setW3cSchema(true); + } + if (did.includes(DidMethod.INDY)) { + setW3cSchema(false); + } + } + setLoading(false); + }; + + useEffect(() => { + getOrganizationDetails(); + }, []); + + const handleSubmit = async (values: IEmailValues) => { + setLoading(true); + setErrorMessage(null); + + try { + let payload; + + if (w3cSchema) { + const getSelectedW3CSchemaDetails = await getFromLocalStorage(storageKeys.ATTRIBUTE_DATA); + + const parsedW3CSchemaDetails = JSON.parse(getSelectedW3CSchemaDetails); + const groupedAttributes = parsedW3CSchemaDetails + .filter(attribute => attribute.isChecked) + .reduce((acc, attribute) => { + const schemaUri = attribute.schemaId; + if (!acc[schemaUri]) { + acc[schemaUri] = { + id: attribute.schemaId.split('/').pop(), + name: attribute.schemaName, + schema: [{ uri: schemaUri }], + constraints: { + fields: [] + }, + purpose: "Verify proof" + }; + } + acc[schemaUri].constraints.fields.push({ + path: `$.credentialSubject['${attribute.attributeName}']` + }); + return acc; + }, {}); + + const inputDescriptors = Object.values(groupedAttributes).map((descriptor) => ({ + ...descriptor, + constraints: { + fields: [{ + path: descriptor.constraints.fields.map(field => field.path) + }] + } + })); + + payload = { + goalCode: "verification", + willConfirm: true, + protocolVersion: ProtocolVersion.V2, + presentationDefinition: { + id: "32f54163-7166-48f1-93d8-ff217bdb0653", + input_descriptors: inputDescriptors + }, + comment: "proof request", + autoAcceptProof: AutoAccept.NEVER, + emailId: values.emailData.map(input => input.email), + reuseConnection: true + }; + } else { + + const selectedAttributes = await getFromLocalStorage(storageKeys.ATTRIBUTE_DATA); + const parsedSelectedAttributes = JSON.parse(selectedAttributes) || []; + + const selectedAttributesDetails = parsedSelectedAttributes.filter((attr: ISelectedAttributes) => attr.isChecked && attr.dataType !== 'number') || []; + const selectedPredicatesDetails = parsedSelectedAttributes.filter(attr => attr.isChecked && attr.dataType === 'number') || []; + + const requestedAttributes: Record = {}; + const requestedPredicates: Record = {}; + + const attributeGroups = selectedAttributesDetails.reduce((acc, attr) => { + const key = `${attr.attributeName}:${attr.schemaId}`; + if (!acc[key]) { + acc[key] = []; + } + acc[key].push(attr.credDefId); + return acc; + }, {} as Record); + + Object.keys(attributeGroups).forEach(key => { + + const parts = key.split(':'); + const attributeName = parts[0]; + const schemaId = parts.slice(1).join(':'); + + if (!requestedAttributes[attributeName]) { + requestedAttributes[attributeName] = { + name: attributeName, + restrictions: [], + }; + } + requestedAttributes[attributeName].restrictions.push(...attributeGroups[key].map(credDefId => ({ + schema_id: schemaId, + cred_def_id: credDefId, + }))); + }); + + selectedPredicatesDetails.forEach(attr => { + if (attr.isChecked && attr.dataType === 'number') { + requestedPredicates[attr.attributeName] = { + name: attr.attributeName, + p_type: attr.selectedOption, + p_value: Number(attr.value), + restrictions: [ + { + schema_id: attr.schemaId, + cred_def_id: attr.credDefId, + }, + ], + }; + } + }); + + const proofFormats = { + indy: { + name: "proof-request", + version: "1.0", + requested_attributes: requestedAttributes, + requested_predicates: requestedPredicates, + }, + }; + + payload = { + goalCode: "verification", + protocolVersion: ProtocolVersion.V1, + isShortenUrl: true, + autoAcceptProof: AutoAccept.NEVER, + emailId: values.emailData.map(input => input.email), + proofFormats, + }; + } + + const requestType = w3cSchema ? RequestType.PRESENTATION_EXCHANGE : RequestType.INDY; + const response = await createOobProofRequest(payload, requestType); + const { data } = response as AxiosResponse; + + if (data?.statusCode === apiStatusCodes.API_STATUS_CREATED) { + await removeFromLocalStorage(storageKeys.ATTRIBUTE_DATA); + window.location.href = pathRoutes.organizations.credentials; + + } else { + setErrorMessage('Failed to create proof request'); + console.error('API response data:', data); + } + } catch (error) { + console.error('Error during handleSubmit:', error); + setErrorMessage('An error occurred. Please try again.'); + } finally { + setLoading(false); + } + }; + + return ( +
    +
    +
    + +
    +
    +

    + Request Proof(s) to Email ID +

    + + Please enter an email address to request a proof to + +
    +
    + {(errorMessage) && ( + { + setErrorMessage(null); + }} + /> + )} +
    +
    +
    +
    +
    + ({ email: input.value })), + }} + validationSchema={Yup.object().shape({ + emailData: Yup.array().of( + Yup.object().shape({ + email: Yup.string() + .email('Invalid email address') + .required('Email is required'), + }), + ), + })} + validateOnBlur + validateOnChange + enableReinitialize + onSubmit={handleSubmit + } + > + {({ values, errors, touched, resetForm }) => ( +
    +
    + {values.emailData.map((input, index) => ( +
    +
    +
    +
    + +
    + ) => handleInputChange(index, event)} + className="bg-gray-50 border border-gray-300 text-gray-900 sm:text-md rounded-lg focus:ring-primary-500 focus:border-primary-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" + /> + {errors.emailData?.[index]?.email && touched.emailData?.[index]?.email && ( + + {errors.emailData[index].email} + + )} +
    +
    + + {values.emailData.length > 1 && ( + + )} +
    +
    +
    + ))} +
    + +
    +
    + +
    + + +
    +
    + + )} +
    +
    +
    +
    +
    +
    +
    + ); +}; + +export default EmailVerification; diff --git a/src/components/Verification/SchemaSelection.tsx b/src/components/Verification/SchemaSelection.tsx index a6316b45d..ea8926aae 100644 --- a/src/components/Verification/SchemaSelection.tsx +++ b/src/components/Verification/SchemaSelection.tsx @@ -1,4 +1,3 @@ - import { removeFromLocalStorage, setToLocalStorage } from "../../api/Auth"; import { storageKeys } from "../../config/CommonConstant"; import { pathRoutes } from "../../config/pathRoutes"; @@ -15,8 +14,12 @@ const SchemaSelection = () => { window.location.href = `${pathRoutes.organizations.verification.credDef}` } + const W3CSchemaSelectionCallback = async () => { + window.location.href = `${pathRoutes.organizations.verification.W3CConnections}` + } + return ( - + ) } diff --git a/src/components/Verification/Verification.tsx b/src/components/Verification/Verification.tsx index bdcd165ae..14864b373 100644 --- a/src/components/Verification/Verification.tsx +++ b/src/components/Verification/Verification.tsx @@ -318,8 +318,10 @@ const VerificationCred = () => { if(w3cSchema){ - const getW3cAttributes = await getFromLocalStorage(storageKeys.W3C_SCHEMA_DETAILS); + const getW3cAttributes = await getFromLocalStorage(storageKeys.W3C_SCHEMA_DATA); + const parsedSchemaAttributes = JSON.parse(getW3cAttributes) || []; + const w3cInputArray: SelectedUsers[] = parsedSchemaAttributes.attributes.map( (attribute: IAttribute) => { return { @@ -447,7 +449,7 @@ const VerificationCred = () => { }; }); - setAttributeList(attributes); + setAttributeList(attributes); setDisplay( attributeData?.some((attribute) => attribute?.dataType === 'number'), @@ -467,7 +469,8 @@ const VerificationCred = () => { if(isW3c){ const orgId = await getFromLocalStorage(storageKeys.ORG_ID); - const getW3cSchemaDetails = await getFromLocalStorage(storageKeys.W3C_SCHEMA_DETAILS); + const getW3cSchemaDetails = await getFromLocalStorage(storageKeys.W3C_SCHEMA_DATA); + const parsedW3cSchemaDetails = JSON.parse(getW3cSchemaDetails); const schemaId = parsedW3cSchemaDetails?.schemaId createW3cSchemaPayload(schemaId,parsedW3cSchemaDetails) @@ -531,7 +534,6 @@ const VerificationCred = () => { version={w3cSchemaDetails.version} hideCredDefId={true} /> - ) )} {(proofReqSuccess || errMsg) && ( diff --git a/src/components/Verification/VerificationCredentialList.tsx b/src/components/Verification/VerificationCredentialList.tsx index a87872cb4..510209747 100644 --- a/src/components/Verification/VerificationCredentialList.tsx +++ b/src/components/Verification/VerificationCredentialList.tsx @@ -324,7 +324,8 @@ const VerificationCredentialList = () => { }, [listAPIParameter]); const schemeSelection = () => { - window.location.href = pathRoutes.organizations.verification.schema; + window.location.href = pathRoutes.organizations.verification.requestProof; + }; const refreshPage = () => { diff --git a/src/components/Verification/VerificationDashboard.tsx b/src/components/Verification/VerificationDashboard.tsx index 24ef11367..16888675a 100644 --- a/src/components/Verification/VerificationDashboard.tsx +++ b/src/components/Verification/VerificationDashboard.tsx @@ -6,12 +6,13 @@ const VerificationDashboard = () => { { heading: 'Connection', description: 'Verify credential(s) by selecting existing connections', - path: pathRoutes.organizations.verification.connections, + path: pathRoutes.organizations.verification.schema, + }, { heading: 'Email', description: 'Verify credential(s) by entering email ID for specific user', - path: null, + path: pathRoutes.organizations.verification.email, }, { heading: 'Bulk', diff --git a/src/components/Verification/VerificationSchemasList.tsx b/src/components/Verification/VerificationSchemasList.tsx new file mode 100644 index 000000000..c177271c6 --- /dev/null +++ b/src/components/Verification/VerificationSchemasList.tsx @@ -0,0 +1,413 @@ + +import { Alert, Button, Pagination } from 'flowbite-react'; +import React, { useEffect, useState } from 'react'; +import type { ChangeEvent } from 'react'; +import type { AxiosResponse } from 'axios'; +import { checkEcosystem, type ICheckEcosystem } from '../../config/ecosystem'; +import { getFromLocalStorage, setToLocalStorage } from '../../api/Auth'; +import { apiStatusCodes, storageKeys } from '../../config/CommonConstant'; +import { getAllSchemas, getAllSchemasByOrgId } from '../../api/Schema'; +import { DidMethod, SchemaType } from '../../common/enums'; +import { getOrganizationById } from '../../api/organization'; +import { Create, SchemaEndorsement } from '../Issuance/Constant'; +import BreadCrumbs from '../BreadCrumbs'; +import SearchInput from '../SearchInput'; +import RoleViewButton from '../RoleViewButton'; +import { Features } from '../../utils/enums/features'; +import { pathRoutes } from '../../config/pathRoutes'; +import CustomSpinner from '../CustomSpinner'; +import { EmptyListMessage } from '../EmptyListComponent'; +import SchemaCard from '../../commonComponents/SchemaCard'; +import type { IAttributesDetails, ISchema, ISchemaData } from './interface'; + +const VerificationSchemasList = () => { + const [schemasList, setSchemasList] = useState([]); + const [schemasDetailsErr, setSchemasDetailsErr] = useState(''); + const [loading, setLoading] = useState(true); + const [allSchemasFlag, setAllSchemasFlag] = useState(false); + const [schemasListParameter, setSchemasListParameter] = useState({ + itemPerPage: 9, + page: 1, + search: '', + sortBy: 'id', + sortingOrder: 'desc', + allSearch: '', + }); + const [walletStatus, setWalletStatus] = useState(false); + const [totalItems, setTotalItems] = useState(0); + const [isEcosystemData, setIsEcosystemData] = useState(); + const [searchValue, setSearchValue] = useState(''); + const [selectedSchemas, setSelectedSchemas] = useState([]); + const [w3cSchema, setW3cSchema] = useState(false); + const [isNoLedger, setIsNoLedger] = useState(false); + + const getSchemaListDetails = async ( + schemasListParameter: { + itemPerPage: number, + page: number, + search: string, + sortingOrder: string, + sortBy: string, + allSearch: string + }, + flag: boolean, + ) => { + try { + const organizationId = await getFromLocalStorage(storageKeys.ORG_ID); + setLoading(true); + let schemasList; + if (allSchemasFlag) { + schemasList = await getAllSchemas(schemasListParameter, SchemaType.INDY); + } else { + schemasList = await getAllSchemasByOrgId( + schemasListParameter, + organizationId, + ); + } + + const { data } = schemasList as AxiosResponse; + + if (schemasList === 'Schema records not found') { + setLoading(false); + setSchemasList([]); + } + + if (data?.statusCode === apiStatusCodes.API_STATUS_SUCCESS) { + if (data?.data?.data) { + setTotalItems(data?.data?.lastPage); + setSchemasList(data?.data?.data); + setLoading(false); + } else { + setLoading(false); + if (schemasList !== 'Schema records not found') { + setSchemasDetailsErr(schemasList as string); + } + } + } else { + setLoading(false); + if (schemasList !== 'Schema records not found') { + setSchemasDetailsErr(schemasList as string); + } + } + setTimeout(() => { + setSchemasDetailsErr(''); + }, 3000); + } catch (error) { + console.error('Error while fetching schema list:', error); + setLoading(false); + } + }; + + useEffect(() => { + getSchemaListDetails(schemasListParameter, false); + }, [schemasListParameter, allSchemasFlag]); + + + const onSchemaListParameterSearch = async ( + event: ChangeEvent, + ): Promise => { + event.preventDefault(); + const inputValue = event.target.value; + setSearchValue(inputValue); + + getSchemaListDetails( + { + ...schemasListParameter, + search: inputValue, + }, + false, + ); + + if (allSchemasFlag) { + getSchemaListDetails( + { + ...schemasListParameter, + allSearch: inputValue, + }, + false, + ); + } + }; + + const handleSchemaSelection = ( + schemaId: string, + attributes: IAttributesDetails[], + issuerId: string, + created: string, + ) => { + const schemaDetails = { + schemaId: schemaId, + attributes: attributes, + issuerId: issuerId, + createdDate: created, + }; + + const isSelected = selectedSchemas.some((schema) => schema.schemaId === schemaId); + if (isSelected) { + const updatedSchemas = selectedSchemas.filter((schema) => schema.schemaId !== schemaId); + + setSelectedSchemas(updatedSchemas); + } else { + setSelectedSchemas([...selectedSchemas, schemaDetails]); + } + }; + + + const handleW3cSchemas = async (checked: boolean, schemaData?: ISchemaData) => { + const updateSchemas = (prevSchemas: ISchemaData[]) => { + let updatedSchemas = [...prevSchemas]; + if (checked && schemaData) { + updatedSchemas = [...updatedSchemas, schemaData]; + } else { + updatedSchemas = updatedSchemas.filter(schema => schema?.schemaLedgerId !== schemaData?.schemaLedgerId); + } + + return updatedSchemas; + }; + + setSelectedSchemas(prevSchemas => { + if (!Array.isArray(prevSchemas)) { + console.error('Previous schemas is not an array:', prevSchemas); + return []; + } + + const updatedSchemas = updateSchemas(prevSchemas); + + setToLocalStorage(storageKeys.SELECTED_SCHEMAS, updatedSchemas) + .catch(error => console.error('Failed to save to local storage:', error)); + + return updatedSchemas; + }); + }; + + const fetchOrganizationDetails = async () => { + setLoading(true); + const orgId = await getFromLocalStorage(storageKeys.ORG_ID); + const response = await getOrganizationById(orgId); + const { data } = response as AxiosResponse; + if (data?.statusCode === apiStatusCodes.API_STATUS_SUCCESS) { + const did = data?.data?.org_agents?.[0]?.orgDid; + + if (data?.data?.org_agents && data?.data?.org_agents?.length > 0) { + setWalletStatus(true); + } + if (did.includes(DidMethod.POLYGON) || did.includes(DidMethod.KEY) || did.includes(DidMethod.WEB)) { + setW3cSchema(true); + } + if (did.includes(DidMethod.INDY)) { + setW3cSchema(false); + } + if (did.includes(DidMethod.KEY) || did.includes(DidMethod.WEB)) { + setIsNoLedger(true); + } + } + setLoading(false); + }; + + const handleContinue = async () => { + const schemaIds = selectedSchemas?.map(schema => schema?.schemaId) + await setToLocalStorage(storageKeys.SCHEMA_IDS, schemaIds) + + const schemaAttributes = selectedSchemas.map(schema => ({ + schemaId: schema.schemaId, + attributes: schema.attributes, + })); + + await setToLocalStorage(storageKeys.SCHEMA_ATTRIBUTES, schemaAttributes); + + window.location.href = `${pathRoutes.organizations.verification.emailCredDef}`; + }; + + const handleW3CSchemaDetails = async () => { + const w3cSchemaDetails = await getFromLocalStorage(storageKeys.SELECTED_SCHEMAS) + + const parsedSchemaDetails = JSON.parse(w3cSchemaDetails); + + const w3cSchemaAttributes = parsedSchemaDetails.map(schema => ({ + schemaId: schema.schemaId, + attributes: schema.attributes, + schemaName: schema.schemaName + })) + await setToLocalStorage(storageKeys.W3C_SCHEMA_ATTRIBUTES, w3cSchemaAttributes); + + window.location.href = `${pathRoutes.organizations.verification.w3cAttributes}`; + }; + + const options = ['All schemas']; + + const handleFilter = (e: React.ChangeEvent) => { + if (e.target.value === 'All schemas') { + setAllSchemasFlag(true); + } else { + setAllSchemasFlag(false); + getSchemaListDetails(schemasListParameter, false); + } + }; + + useEffect(() => { + fetchOrganizationDetails(); + (async () => { + try { + const data: ICheckEcosystem = await checkEcosystem(); + setIsEcosystemData(data); + } catch (error) { + console.error(error); + } + })(); + setSearchValue(''); + }, []); + + const createSchemaButtonTitle = isEcosystemData?.isEcosystemMember + ? { title: 'Schema Endorsement', toolTip: 'Add new schema request', svg: } + : { title: 'Create', svg: , toolTip: 'Create new schema' }; + const emptySchemaListTitle = 'No Schemas'; + const emptySchemaListDescription = 'Get started by creating a new Schema'; + const emptySchemaListBtn = isEcosystemData?.isEcosystemMember + ? { title: 'Schema Endorsement', svg: } + : { title: 'Create Schema', svg: }; + return ( +
    +
    + +
    + +
    +
    +
    +

    + Schemas +

    + + + + +
    + {walletStatus ? ( + { + window.location.href = `${pathRoutes.organizations.createSchema}`; + }} + /> + ) : ( + { + window.location.href = `${pathRoutes.organizations.dashboard}`; + }} + /> + )} +
    +
    +
    + {schemasDetailsErr && ( + setSchemasDetailsErr(null)}> + +

    {schemasDetailsErr}

    +
    +
    + )} + {schemasList && schemasList.length > 0 ? ( +
    +
    + {schemasList && + schemasList.length > 0 && + schemasList.map((element) => ( +
    + handleW3cSchemas(checked, element)} + onClickCallback={handleSchemaSelection} + /> +
    + ))} +
    + +
    + +
    +
    + {totalItems > 1 && ( + { + setSchemasListParameter((prevState) => ({ + ...prevState, + page: page, + })); + }} + totalPages={totalItems} + /> + )} +
    +
    + ) : ( +
    + {loading ? ( +
    + +
    + ) : ( +
    + { + window.location.href = `${pathRoutes.organizations.createSchema}`; + }} + /> +
    + )} +
    + )} +
    +
    + ); +}; + +export default VerificationSchemasList; diff --git a/src/components/Verification/interface.ts b/src/components/Verification/interface.ts index c45d81145..3ea8f57ad 100644 --- a/src/components/Verification/interface.ts +++ b/src/components/Verification/interface.ts @@ -35,6 +35,9 @@ export interface SchemaDetails { attribute: string[]; issuerDid: string; createdDate: string; + schemaName?: string; + version?: string; + schemaId?: string; } export interface IProofRrquestDetails { @@ -66,6 +69,7 @@ export interface IW3cSchemaDetails { schemaId: string; w3cAttributes?: IAttributesData[]; issuerDid?:string; + created?:string; } export interface IAttributesData { @@ -84,6 +88,10 @@ export interface IAttribute { displayName: string; attributeName: string; schemaDataType: string; + schemaName?: string; + credDefName?: string; + schemaId?: string; + credDefId?: string; } export interface SelectedUsers { userName: string; @@ -112,6 +120,9 @@ export interface ISelectedUser { dataType: string; displayName?: string; attributeName: string; + schemaName?: string; + schemaId?: string; + credDefName?: string; isChecked: false; value: number; selectedOption?: SelectedOption; @@ -124,3 +135,74 @@ export interface ISelectedUser { }, ]; } + +export interface IOption { + value: string | number; + label: string; + } +export interface ISelectedAttributes { + displayName: string; + attributeName: string; + isChecked: boolean; + value: string; + condition: string; + options: IOption[]; + dataType: string; + schemaName?: string; + credDefName?: string; + schemaId?: string; + credDefId?: string; + selectedOption: string; + inputError: string; + selectError: string; + } + + export interface IRequestedAttributes { + name: string; + restrictions: Array<{ + schema_id: string; + cred_def_id: string; + }>; +} +interface IEmailData { + email: string; +} +export interface IEmailValues { + emailData: IEmailData[]; +} + +export interface IPredicate extends IRequestedAttributes { + p_type: string; + p_value: number; +} +export interface IRequestedPredicates { + [key: string]: IPredicate; +} + +export interface IAttributesDetails { + attributeName: string; + schemaDataType: string; + displayName: string; + isRequired: boolean; +} + +export interface ISchemaData { + createDateTime: string; + name: string; + version: string; + attributes: IAttributesDetails[]; + schemaLedgerId: string; + createdBy: string; + publisherDid: string; + orgId: string; + issuerId: string; + organizationName: string; + userName: string; +} + +export interface ISchema { + schemaId: string; + attributes: IAttributesDetails[]; + issuerId: string; + createdDate: string; +} diff --git a/src/components/organization/DeleteOrganizationsCard.tsx b/src/components/organization/DeleteOrganizationsCard.tsx index a6677dffa..69625d6f8 100644 --- a/src/components/organization/DeleteOrganizationsCard.tsx +++ b/src/components/organization/DeleteOrganizationsCard.tsx @@ -30,11 +30,12 @@ const DeleteOrganizationsCard: React.FC = ({ {count &&

    Total:{count}

    }

    diff --git a/src/config/CommonConstant.ts b/src/config/CommonConstant.ts index d32f5537f..3bfde0115 100644 --- a/src/config/CommonConstant.ts +++ b/src/config/CommonConstant.ts @@ -8,6 +8,7 @@ export const emailRegex = /(\.[a-zA-Z]{2,})$/ export const CREDENTIAL_CONTEXT_VALUE = 'https://www.w3.org/2018/credentials/v1' export const schemaVersionRegex = /^\d{1,5}(?=.*[0-9])(?:\.\d{1,5})?(?:\.\d{1,5})?$/gm export const proofPurpose = 'assertionMethod' +export const limitedAttributesLength = 3 export const apiStatusCodes = { API_STATUS_SUCCESS : 200, @@ -28,8 +29,11 @@ export const storageKeys = { PERMISSIONS: 'user_permissions', USER_EMAIL: 'user_email', SELECTED_USER:'selected_user', + CRED_DEF_DATA: 'CRED_DEF_DATA', SELECTED_CONNECTIONS: 'selected_connections', SCHEMA_ID:'schema_id', + W3C_SCHEMA_DATA:'w3cSchemaDetails', + W3C_SCHEMA_ATTRIBUTES: 'w3c_schema_attributes', SCHEMA_ATTR:'schema_attr', W3C_SCHEMA_DETAILS:'schemaDetails', CRED_DEF_ID:'cred_def_id', @@ -38,6 +42,11 @@ export const storageKeys = { ECOSYSTEM_ID: "ecosystem_id", ORG_DETAILS: "org_details", ECOSYSTEM_ROLE: "ecosystem_role", + SCHEMA_IDS: "schemaIds", + SCHEMA_ATTRIBUTES: "schema_attributes", + SCHEMA_CRED_DEFS: "schema_cred_defs", + ATTRIBUTE_DATA: "attribute_data", + SELECTED_SCHEMAS:'selectedSchemas', SOCKET_ID: "socket_id", LEDGER_ID: "ledger_id", ORG_INFO:'organization_Info', @@ -46,3 +55,17 @@ export const storageKeys = { SELECT_ORG_IN_ECOSYSTEM: 'select_orgs_in_ecosystem', ERROR_ORG_IN_ECOSYSTEM: 'error_orgs_in_ecosystem' } + +export const emailCredDefHeaders = [ + { columnName: 'Cred def name' }, + { columnName: 'Schema name' }, + { columnName: 'Revocable' }, +]; + +export const predicatesConditions = [ + { value: '', label: 'Select' }, + { value: '>', label: 'Greater than' }, + { value: '<', label: 'Less than' }, + { value: '>=', label: 'Greater than or equal to' }, + { value: '<=', label: 'Less than or equal to' } +] diff --git a/src/config/apiRoutes.ts b/src/config/apiRoutes.ts index f2a9b2f33..3c6eb762a 100644 --- a/src/config/apiRoutes.ts +++ b/src/config/apiRoutes.ts @@ -77,6 +77,7 @@ export const apiRoutes = { Verification: { getAllRequestList: '/credentials/proofs', verifyCredential: '/proofs', + oobProofRequest: '/proofs/oob', presentationVerification: '/proofs', proofRequestAttributesVerification: '/verified-proofs', verificationCredDef: '/verifiation/cred-defs' diff --git a/src/config/pathRoutes.ts b/src/config/pathRoutes.ts index 887f80ae7..c8415ff82 100644 --- a/src/config/pathRoutes.ts +++ b/src/config/pathRoutes.ts @@ -30,8 +30,6 @@ export const pathRoutes = { createSchema: '/organizations/schemas/create', deleteOrganization:'/organizations/delete-organizations', - - viewSchema: '/organizations/schemas/view-schema', Issuance: { issue: '/organizations/credentials/issue', @@ -54,11 +52,18 @@ export const pathRoutes = { email: '/organizations/verification/verify-credentials/email/schemas', schema: '/organizations/verification/verify-credentials/schemas', credDef: '/organizations/verification/verify-credentials/schemas/cred-defs', - attributes: '/organizations/verification/verify-credentials/schemas/cred-defs/attributes', + w3cAttributes: '/organizations/verification/verify-credentials/email/schemas/attributes', + attributes: '/organizations/verification/verify-credentials/email/schemas/cred-defs/attributes', + emailVerification: '/organizations/verification/verify-credentials/email/schemas/cred-defs/attributes/verification-email', + w3cEmailVerification: '/organizations/verification/verify-credentials/email/schemas/attributes/verification-email', emailCredDef: '/organizations/verification/verify-credentials/email/schemas/cred-defs', connections: '/organizations/verification/verify-credentials/schemas/cred-defs/connections', + W3CConnections: '/organizations/verification/verify-credentials/schemas/connections', + verify: '/organizations/verification/verify-credentials/schemas/cred-defs/connections/verification', + W3CVerification: + '/organizations/verification/verify-credentials/schemas/connections/verification', }, }, ecosystem: { diff --git a/src/pages/organizations/verification/verify-credentials/email/schemas/attributes/index.astro b/src/pages/organizations/verification/verify-credentials/email/schemas/attributes/index.astro new file mode 100644 index 000000000..c95f548f5 --- /dev/null +++ b/src/pages/organizations/verification/verify-credentials/email/schemas/attributes/index.astro @@ -0,0 +1,14 @@ +--- +import LayoutSidebar from "../../../../../../../app/LayoutSidebar.astro"; +import EmailAttributesSelection from "../../../../../../../components/Verification/EmailAttributesSelection"; +import { checkUserSession } from "../../../../../../../utils/check-session"; + +const response = await checkUserSession({cookies: Astro.cookies, currentPath: Astro.url.pathname}); +if (!response.authorized) { + return Astro.redirect(response.redirect); +} +--- + + + + diff --git a/src/pages/organizations/verification/verify-credentials/email/schemas/attributes/verification-email/index.astro b/src/pages/organizations/verification/verify-credentials/email/schemas/attributes/verification-email/index.astro new file mode 100644 index 000000000..aa8a0c183 --- /dev/null +++ b/src/pages/organizations/verification/verify-credentials/email/schemas/attributes/verification-email/index.astro @@ -0,0 +1,14 @@ +--- +import LayoutSidebar from "../../../../../../../../app/LayoutSidebar.astro"; +import EmailVerification from "../../../../../../../../components/Verification/EmailVerification"; +import { checkUserSession } from "../../../../../../../../utils/check-session"; + +const response = await checkUserSession({cookies: Astro.cookies, currentPath: Astro.url.pathname}); +if (!response.authorized) { + return Astro.redirect(response.redirect); +} +--- + + + + diff --git a/src/pages/organizations/verification/verify-credentials/email/schemas/cred-defs/attributes/index.astro b/src/pages/organizations/verification/verify-credentials/email/schemas/cred-defs/attributes/index.astro index 1a5fa482e..5503c6b90 100644 --- a/src/pages/organizations/verification/verify-credentials/email/schemas/cred-defs/attributes/index.astro +++ b/src/pages/organizations/verification/verify-credentials/email/schemas/cred-defs/attributes/index.astro @@ -1,14 +1,14 @@ --- import LayoutSidebar from "../../../../../../../../app/LayoutSidebar.astro"; -import { pathRoutes } from "../../../../../../../../config/pathRoutes"; +import EmailAttributesSelection from "../../../../../../../../components/Verification/EmailAttributesSelection"; import { checkUserSession } from "../../../../../../../../utils/check-session"; const response = await checkUserSession({cookies: Astro.cookies, currentPath: Astro.url.pathname}); -const route: string = pathRoutes.auth.sinIn if (!response.authorized) { return Astro.redirect(response.redirect); } --- + diff --git a/src/pages/organizations/verification/verify-credentials/email/schemas/cred-defs/attributes/verification-email/index.astro b/src/pages/organizations/verification/verify-credentials/email/schemas/cred-defs/attributes/verification-email/index.astro new file mode 100644 index 000000000..cd4f921c5 --- /dev/null +++ b/src/pages/organizations/verification/verify-credentials/email/schemas/cred-defs/attributes/verification-email/index.astro @@ -0,0 +1,15 @@ +--- +import LayoutSidebar from "../../../../../../../../../app/LayoutSidebar.astro"; +import EmailVerification from "../../../../../../../../../components/Verification/EmailVerification"; +import { checkUserSession } from "../../../../../../../../../utils/check-session"; + + +const response = await checkUserSession({cookies: Astro.cookies, currentPath: Astro.url.pathname}); +if (!response.authorized) { + return Astro.redirect(response.redirect); +} +--- + + + + diff --git a/src/pages/organizations/verification/verify-credentials/email/schemas/cred-defs/index.astro b/src/pages/organizations/verification/verify-credentials/email/schemas/cred-defs/index.astro index 605a8dca5..9d224c9e5 100644 --- a/src/pages/organizations/verification/verify-credentials/email/schemas/cred-defs/index.astro +++ b/src/pages/organizations/verification/verify-credentials/email/schemas/cred-defs/index.astro @@ -1,6 +1,6 @@ --- import LayoutSidebar from "../../../../../../../app/LayoutSidebar.astro"; -import CredDefSelection from "../../../../../../../components/Verification/CredDefSelection"; +import EmailCredDefSelection from "../../../../../../../components/Verification/EmailCredDefSelection"; import { pathRoutes } from "../../../../../../../config/pathRoutes"; import { checkUserSession } from "../../../../../../../utils/check-session"; @@ -13,4 +13,5 @@ if (!response.authorized) { --- + diff --git a/src/pages/organizations/verification/verify-credentials/email/schemas/index.astro b/src/pages/organizations/verification/verify-credentials/email/schemas/index.astro index 6da80ddd8..4f1d3bb1d 100644 --- a/src/pages/organizations/verification/verify-credentials/email/schemas/index.astro +++ b/src/pages/organizations/verification/verify-credentials/email/schemas/index.astro @@ -1,6 +1,6 @@ --- import LayoutSidebar from "../../../../../../app/LayoutSidebar.astro"; -import SchemaSelection from "../../../../../../components/Verification/SchemaSelection"; +import EmailSchemaSelection from "../../../../../../components/Verification/EmailSchemaSelection"; import { pathRoutes } from "../../../../../../config/pathRoutes"; import { checkUserSession } from "../../../../../../utils/check-session"; @@ -12,4 +12,5 @@ if (!response.authorized) { --- + diff --git a/src/pages/organizations/verification/verify-credentials/schemas/connections/index.astro b/src/pages/organizations/verification/verify-credentials/schemas/connections/index.astro new file mode 100644 index 000000000..0ea57bf87 --- /dev/null +++ b/src/pages/organizations/verification/verify-credentials/schemas/connections/index.astro @@ -0,0 +1,17 @@ +--- +import LayoutSidebar from "../../../../../../app/LayoutSidebar.astro"; +import Connections from "../../../../../../components/Verification/Connections"; +import { pathRoutes } from "../../../../../../config/pathRoutes"; +import { checkUserSession } from "../../../../../../utils/check-session"; + + +const response = await checkUserSession({cookies: Astro.cookies, currentPath: Astro.url.pathname}); +const route: string = pathRoutes.auth.sinIn +if (!response.authorized) { + return Astro.redirect(response.redirect); +} +--- + + + + diff --git a/src/pages/organizations/verification/verify-credentials/schemas/connections/verification.astro b/src/pages/organizations/verification/verify-credentials/schemas/connections/verification.astro new file mode 100644 index 000000000..2dbff36f5 --- /dev/null +++ b/src/pages/organizations/verification/verify-credentials/schemas/connections/verification.astro @@ -0,0 +1,17 @@ +--- +import LayoutSidebar from "../../../../../../app/LayoutSidebar.astro"; +import VerificationCred from "../../../../../../components/Verification/Verification"; +import { pathRoutes } from "../../../../../../config/pathRoutes"; +import { checkUserSession } from "../../../../../../utils/check-session"; + + +const response = await checkUserSession({cookies: Astro.cookies, currentPath: Astro.url.pathname}); +const route: string = pathRoutes.auth.sinIn +if (!response.authorized) { + return Astro.redirect(response.redirect); +} +--- + + + + diff --git a/src/pages/organizations/verification/verify-credentials/schemas/cred-defs/index.astro b/src/pages/organizations/verification/verify-credentials/schemas/cred-defs/index.astro index c5bc7bfd1..d5354bad4 100644 --- a/src/pages/organizations/verification/verify-credentials/schemas/cred-defs/index.astro +++ b/src/pages/organizations/verification/verify-credentials/schemas/cred-defs/index.astro @@ -12,5 +12,5 @@ if (!response.authorized) { --- - +