diff --git a/govtool/frontend/src/components/organisms/VoteContext/VoteContextStoringInformation.tsx b/govtool/frontend/src/components/organisms/VoteContext/VoteContextStoringInformation.tsx index 3646a7cb7..95485fcd1 100644 --- a/govtool/frontend/src/components/organisms/VoteContext/VoteContextStoringInformation.tsx +++ b/govtool/frontend/src/components/organisms/VoteContext/VoteContextStoringInformation.tsx @@ -31,7 +31,7 @@ export const VoteContextStoringInformation = ({ validateURL, watch, generateMetadata, - onClickDownloadJson, + onClickDownloadFile, } = useVoteContextForm(setSavedHash, setStep, setErrorMessage); const openGuideAboutStoringInformation = () => @@ -78,7 +78,7 @@ export const VoteContextStoringInformation = ({ } sx={{ @@ -88,7 +88,7 @@ export const VoteContextStoringInformation = ({ }} variant="outlined" > - {t("govActions.voteContextJsonldFileName")} + {t("govActions.voteContextFileName")} } componentsLayoutStyles={{ diff --git a/govtool/frontend/src/consts/governanceAction/fields.ts b/govtool/frontend/src/consts/governanceAction/fields.ts index 59fec4bcd..8d77185f5 100644 --- a/govtool/frontend/src/consts/governanceAction/fields.ts +++ b/govtool/frontend/src/consts/governanceAction/fields.ts @@ -174,33 +174,3 @@ export const GOVERNANCE_ACTION_CONTEXT = { }, }, }; - -export const VOTE_TEST_CONTEXT = { - "@language": "en-us", - CIP100: - "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/README.md#", - CIP108: - "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0108/README.md#", - hashAlgorithm: "CIP100:hashAlgorithm", - body: { - "@id": "CIP108:body", - "@context": { - text: "CIP108:text", - }, - }, - authors: { - "@id": "CIP100:authors", - "@container": "@set" as const, - "@context": { - name: "http://xmlns.com/foaf/0.1/name", - witness: { - "@id": "CIP100:witness", - "@context": { - witnessAlgorithm: "CIP100:witnessAlgorithm", - publicKey: "CIP100:publicKey", - signature: "CIP100:signature", - }, - }, - }, - }, -}; diff --git a/govtool/frontend/src/hooks/forms/useVoteContextForm.tsx b/govtool/frontend/src/hooks/forms/useVoteContextForm.tsx index 72b1c6f8e..d0afc7ea6 100644 --- a/govtool/frontend/src/hooks/forms/useVoteContextForm.tsx +++ b/govtool/frontend/src/hooks/forms/useVoteContextForm.tsx @@ -1,16 +1,9 @@ import { Dispatch, SetStateAction, useCallback, useState } from "react"; -import { NodeObject } from "jsonld"; import { useFormContext } from "react-hook-form"; import { blake2bHex } from "blakejs"; import { captureException } from "@sentry/react"; -import { CIP_108, VOTE_TEST_CONTEXT } from "@consts"; -import { - canonizeJSON, - downloadJson, - generateJsonld, - generateMetadataBody, -} from "@utils"; +import { downloadTextFile } from "@utils"; import { MetadataValidationStatus } from "@models"; import { useValidateMutation } from "../mutations"; @@ -28,7 +21,6 @@ export const useVoteContextForm = ( ) => { const { validateMetadata } = useValidateMutation(); const [hash, setHash] = useState(null); - const [json, setJson] = useState(null); const { control, @@ -42,27 +34,21 @@ export const useVoteContextForm = ( } = useFormContext(); const generateMetadata = useCallback(async () => { - const body = generateMetadataBody({ - data: getValues(), - acceptedKeys: ["voteContextText"], - standardReference: CIP_108, - }); + const { voteContextText } = getValues(); - const jsonld = await generateJsonld(body, VOTE_TEST_CONTEXT); - const canonizedJson = await canonizeJSON(jsonld); - const canonizedJsonHash = blake2bHex(canonizedJson, undefined, 32); + const canonizedJsonHash = blake2bHex(voteContextText, undefined, 32); // That allows to validate metadata hash setHash(canonizedJsonHash); - setJson(jsonld); - return jsonld; + return voteContextText; }, [getValues]); - const onClickDownloadJson = useCallback(() => { - if (!json) return; - downloadJson(json, "Vote_Context"); - }, [json]); + const onClickDownloadFile = useCallback(() => { + const { voteContextText } = getValues(); + if (!voteContextText) return; + downloadTextFile(voteContextText, "Vote_Context"); + }, [getValues]); const validateHash = useCallback( async (url: string, localHash: string | null) => { @@ -70,14 +56,17 @@ export const useVoteContextForm = ( if (!localHash) { throw new Error(MetadataValidationStatus.INVALID_HASH); } + const result = await validateMetadata({ - url, hash: localHash, - standard: undefined, + url, + noStandard: true, }); + if (result.status) { throw result.status; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { if (Object.values(MetadataValidationStatus).includes(error)) { @@ -112,7 +101,7 @@ export const useVoteContextForm = ( generateMetadata, getValues, isValid, - onClickDownloadJson, + onClickDownloadFile, register, reset, setValue, diff --git a/govtool/frontend/src/i18n/locales/en.ts b/govtool/frontend/src/i18n/locales/en.ts index 21ddb5839..9570596a5 100644 --- a/govtool/frontend/src/i18n/locales/en.ts +++ b/govtool/frontend/src/i18n/locales/en.ts @@ -439,7 +439,7 @@ export const en = { viewOtherDetails: "View other details", viewProposalDetails: "View proposal details", vote: "Vote", - voteContextJsonldFileName: "Vote_Context.jsonld", + voteContextFileName: "Vote_Context.txt", votedOnByMe: "Voted on by me", voteOnGovActions: "Vote on Governance Action", voteSubmitted: "Vote submitted", diff --git a/govtool/frontend/src/models/metadataValidation.ts b/govtool/frontend/src/models/metadataValidation.ts index 9e2dcee18..7b085fe6b 100644 --- a/govtool/frontend/src/models/metadataValidation.ts +++ b/govtool/frontend/src/models/metadataValidation.ts @@ -22,4 +22,5 @@ export type MetadataValidationDTO = { url: string; hash: string; standard?: MetadataStandard; + noStandard?: boolean; }; diff --git a/govtool/frontend/src/utils/jsonUtils.ts b/govtool/frontend/src/utils/jsonUtils.ts index 90f091333..6b22a9c7c 100644 --- a/govtool/frontend/src/utils/jsonUtils.ts +++ b/govtool/frontend/src/utils/jsonUtils.ts @@ -1,5 +1,11 @@ import { NodeObject } from "jsonld"; +/** + * Downloads a JSON object as a file. + * @param json - The JSON object to be downloaded. + * @param fileName - The name of the file to be downloaded. + * If not provided, the default name will be "data.jsonld". + */ export const downloadJson = (json: NodeObject, fileName?: string) => { const jsonString = `data:text/jsonld;charset=utf-8,${encodeURIComponent( JSON.stringify(json, null, 2), @@ -10,3 +16,19 @@ export const downloadJson = (json: NodeObject, fileName?: string) => { link.click(); }; + +/** + * Downloads a text file with the given content. + * @param text - The content of the text file. + * @param fileName - The name of the file (optional). + * If not provided, the default name will be "data.txt". + */ +export const downloadTextFile = (text: string, fileName?: string) => { + const blob = new Blob([text], { type: "text/utf-8" }); + const url = URL.createObjectURL(blob); + const link = document.createElement("a"); + link.href = url; + link.download = `${fileName || "data"}.txt`; + + link.click(); +}; diff --git a/govtool/metadata-validation/src/app.service.ts b/govtool/metadata-validation/src/app.service.ts index fb58e3e52..d15499582 100644 --- a/govtool/metadata-validation/src/app.service.ts +++ b/govtool/metadata-validation/src/app.service.ts @@ -16,6 +16,8 @@ export class AppService { hash, url, standard = MetadataStandard.CIP108, + // workaround property to not break the haskell backend + noStandard = false, }: ValidateMetadataDTO): Promise { let status: MetadataValidationStatus; let metadata: any; @@ -27,20 +29,29 @@ export class AppService { }), ), ); - if (standard) { + if (standard && !noStandard) { await validateMetadataStandard(data, standard); } - metadata = parseMetadata(data.body, standard); + if (!noStandard) { + metadata = parseMetadata(data.body, standard); + } let canonizedMetadata; - try { - canonizedMetadata = await canonizeJSON(data); - } catch (error) { - throw MetadataValidationStatus.INVALID_JSONLD; + if (!noStandard) { + try { + canonizedMetadata = await canonizeJSON(data); + } catch (error) { + throw MetadataValidationStatus.INVALID_JSONLD; + } } - const hashedMetadata = blake.blake2bHex(canonizedMetadata, undefined, 32); + const hashedMetadata = blake.blake2bHex( + !standard ? data : canonizedMetadata, + undefined, + 32, + ); + if (hashedMetadata !== hash) { throw MetadataValidationStatus.INVALID_HASH; } diff --git a/govtool/metadata-validation/src/dto/validateMetadata.dto.ts b/govtool/metadata-validation/src/dto/validateMetadata.dto.ts index 69462cee0..7756806c3 100644 --- a/govtool/metadata-validation/src/dto/validateMetadata.dto.ts +++ b/govtool/metadata-validation/src/dto/validateMetadata.dto.ts @@ -6,4 +6,6 @@ export class ValidateMetadataDTO { url: string; standard?: MetadataStandard; + + noStandard?: boolean; }