diff --git a/.github/workflows/lighthouse.yml b/.github/workflows/lighthouse.yml index bf1d30c45..2bf75ada6 100644 --- a/.github/workflows/lighthouse.yml +++ b/.github/workflows/lighthouse.yml @@ -36,23 +36,23 @@ jobs: - name: Run build and lighthouse task working-directory: ./govtool/frontend run: | - npm install - VITE_BASE_URL=https://staging.govtool.byron.network/api npm run build - lhci collect + npm install + VITE_BASE_URL=https://staging.govtool.byron.network/ npm run build + lhci collect - name: Evaluate reports if: github.repository_owner != 'IntersectMBO' run: | - lhci assert --preset "lighthouse:recommended" + lhci assert --preset "lighthouse:recommended" - name: Publish reports working-directory: ./govtool/frontend if: github.repository_owner == 'IntersectMBO' run: | - lhci assert --preset lighthouse:recommended || echo "LightHouse Assertion error ignored ..." - lhci upload --githubAppToken="${{ secrets.LHCI_GITHUB_APP_TOKEN }}" --token="${{ secrets.LHCI_SERVER_TOKEN }}" --serverBaseUrl=https://lighthouse.cardanoapi.io --ignoreDuplicateBuildFailure - curl -X POST https://ligththouse.cardanoapi.io/api/metrics/build-reports \ - -d "@./lighthouseci/$(ls ./.lighthouseci |grep 'lhr.*\.json' | head -n 1)" \ - -H "commit-hash: $(git rev-parse HEAD)" \ - -H "secret-token: ${{ secrets.METRICS_SERVER_SECRET_TOKEN }}" \ - -H 'Content-Type: application/json' || echo "Metric Upload error ignored ..." + lhci assert --preset lighthouse:recommended || echo "LightHouse Assertion error ignored ..." + lhci upload --githubAppToken="${{ secrets.LHCI_GITHUB_APP_TOKEN }}" --token="${{ secrets.LHCI_SERVER_TOKEN }}" --serverBaseUrl=https://lighthouse.cardanoapi.io --ignoreDuplicateBuildFailure + curl -X POST https://ligththouse.cardanoapi.io/api/metrics/build-reports \ + -d "@./lighthouseci/$(ls ./.lighthouseci |grep 'lhr.*\.json' | head -n 1)" \ + -H "commit-hash: $(git rev-parse HEAD)" \ + -H "secret-token: ${{ secrets.METRICS_SERVER_SECRET_TOKEN }}" \ + -H 'Content-Type: application/json' || echo "Metric Upload error ignored ..." diff --git a/CHANGELOG.md b/CHANGELOG.md index cb3c92587..961928ae3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ changes. ## [Unreleased] +- Integrate frontend with metadata validation service [Issue 617](https://github.com/IntersectMBO/govtool/issues/617) + ### Added - added `epochNo` and `date` to `drep/getVotes` and `proposal/get` diff --git a/govtool/frontend/Makefile b/govtool/frontend/Makefile index 24f0702dc..f8dd5c348 100644 --- a/govtool/frontend/Makefile +++ b/govtool/frontend/Makefile @@ -15,7 +15,7 @@ build-frontend: docker-login if [[ "$(cardano_network)" = "mainnet" ]]; then NETWORK_FLAG=1; else NETWORK_FLAG=0; fi; \ $(call check_image_on_ecr,frontend,$(frontend_image_tag)) || \ $(docker) build --tag "$(repo_url)/frontend:$(frontend_image_tag)" \ - --build-arg VITE_BASE_URL="https://$(domain)/api" \ + --build-arg VITE_BASE_URL="https://$(domain)" \ --build-arg VITE_GTM_ID="$${GTM_ID}" \ --build-arg VITE_NETWORK_FLAG="$$NETWORK_FLAG" \ --build-arg VITE_SENTRY_DSN="$${SENTRY_DSN}" \ diff --git a/govtool/frontend/src/consts/externalDataModalConfig.ts b/govtool/frontend/src/consts/externalDataModalConfig.ts index 1508004f4..132b20103 100644 --- a/govtool/frontend/src/consts/externalDataModalConfig.ts +++ b/govtool/frontend/src/consts/externalDataModalConfig.ts @@ -1,5 +1,6 @@ import { ModalState } from "@/context"; import I18n from "@/i18n"; +import { MetadataValidationStatus } from "@/models"; export enum MetadataHashValidationErrors { INVALID_URL = "Invalid URL", @@ -29,13 +30,12 @@ const urlCannotBeFound = { }; export const storageInformationErrorModals: Record< - MetadataHashValidationErrors, + MetadataValidationStatus, ModalState< typeof externalDataDoesntMatchModal | typeof urlCannotBeFound >["state"] > = { - [MetadataHashValidationErrors.INVALID_URL]: urlCannotBeFound, - [MetadataHashValidationErrors.FETCH_ERROR]: urlCannotBeFound, - [MetadataHashValidationErrors.INVALID_JSON]: externalDataDoesntMatchModal, - [MetadataHashValidationErrors.INVALID_HASH]: externalDataDoesntMatchModal, + [MetadataValidationStatus.URL_NOT_FOUND]: urlCannotBeFound, + [MetadataValidationStatus.INVALID_JSONLD]: externalDataDoesntMatchModal, + [MetadataValidationStatus.INVALID_HASH]: externalDataDoesntMatchModal, }; diff --git a/govtool/frontend/src/consts/queryKeys.ts b/govtool/frontend/src/consts/queryKeys.ts index 66a12b0b1..9a1e3c887 100644 --- a/govtool/frontend/src/consts/queryKeys.ts +++ b/govtool/frontend/src/consts/queryKeys.ts @@ -10,3 +10,7 @@ export const QUERY_KEYS = { useGetDRepInfoKey: "useGetDRepInfoKey", useGetVoteContextFromFile: "useGetVoteContextFromFile", }; + +export const MUTATION_KEYS = { + postValidateKey: "postValidateKey", +}; diff --git a/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts b/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts index e8ff4f660..24ed8a26b 100644 --- a/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts +++ b/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts @@ -10,22 +10,19 @@ import { CIP_100, CIP_108, GOVERNANCE_ACTION_CONTEXT, - MetadataHashValidationErrors, PATHS, storageInformationErrorModals, } from "@consts"; import { useCardano, useModal } from "@context"; -import { - canonizeJSON, - downloadJson, - generateJsonld, - validateMetadataHash, -} from "@utils"; +import { canonizeJSON, downloadJson, generateJsonld } from "@utils"; +import { MetadataValidationStatus } from "@models"; import { GovernanceActionFieldSchemas, GovernanceActionType, } from "@/types/governanceAction"; +import { useValidateMutation } from "../mutations"; + export type CreateGovernanceActionValues = { links?: { link: string }[]; storeData?: boolean; @@ -48,6 +45,7 @@ export const useCreateGovernanceActionForm = ( buildTreasuryGovernanceAction, buildSignSubmitConwayCertTx, } = useCardano(); + const { validateMetadata } = useValidateMutation(); const { t } = useTranslation(); const [isLoading, setIsLoading] = useState(false); const [hash, setHash] = useState(null); @@ -120,22 +118,27 @@ export const useCreateGovernanceActionForm = ( }, [govActionType, json]); const validateHash = useCallback( - async (storingUrl: string, localHash: string | null) => { + async (url: string, localHash: string | null) => { try { if (!localHash) { - throw new Error(MetadataHashValidationErrors.INVALID_HASH); + throw new Error(MetadataValidationStatus.INVALID_HASH); } - await validateMetadataHash(storingUrl, localHash); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } catch (error: any) { + const result = await validateMetadata({ url, hash: localHash }); + + if (result.status) { + throw result.status; + } + } catch (error) { if ( - Object.values(MetadataHashValidationErrors).includes(error.message) + Object.values(MetadataValidationStatus).includes( + error as MetadataValidationStatus, + ) ) { openModal({ type: "statusModal", state: { ...storageInformationErrorModals[ - error.message as MetadataHashValidationErrors + error as MetadataValidationStatus ], onSubmit: backToForm, onCancel: backToDashboard, @@ -214,6 +217,7 @@ export const useCreateGovernanceActionForm = ( setIsLoading(true); await validateHash(data.storingURL, hash); + const govActionBuilder = await buildTransaction(data); await buildSignSubmitConwayCertTx({ govActionBuilder, diff --git a/govtool/frontend/src/hooks/forms/useEditDRepInfoForm.ts b/govtool/frontend/src/hooks/forms/useEditDRepInfoForm.ts index 89795269c..60a3e6bd0 100644 --- a/govtool/frontend/src/hooks/forms/useEditDRepInfoForm.ts +++ b/govtool/frontend/src/hooks/forms/useEditDRepInfoForm.ts @@ -15,12 +15,10 @@ import { storageInformationErrorModals, } from "@consts"; import { useCardano, useModal } from "@context"; -import { - canonizeJSON, - downloadJson, - generateJsonld, - validateMetadataHash, -} from "@utils"; +import { canonizeJSON, downloadJson, generateJsonld } from "@utils"; +import { MetadataValidationStatus } from "@models"; + +import { useValidateMutation } from "../mutations"; export type EditDRepInfoValues = { bio?: string; @@ -43,6 +41,7 @@ export const defaultEditDRepInfoValues: EditDRepInfoValues = { export const useEditDRepInfoForm = ( setStep?: Dispatch>, ) => { + const { validateMetadata } = useValidateMutation(); const { t } = useTranslation(); const navigate = useNavigate(); const [isLoading, setIsLoading] = useState(false); @@ -113,21 +112,23 @@ export const useEditDRepInfoForm = ( }; const validateHash = useCallback( - async (storingUrl: string) => { + async (url: string) => { try { if (!hash) throw new Error(MetadataHashValidationErrors.INVALID_HASH); - await validateMetadataHash(storingUrl, hash); + const result = await validateMetadata({ url, hash }); + + if (result.status) { + throw result.status; + } // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { - if ( - Object.values(MetadataHashValidationErrors).includes(error.message) - ) { + if (Object.values(MetadataValidationStatus).includes(error)) { openModal({ type: "statusModal", state: { ...storageInformationErrorModals[ - error.message as MetadataHashValidationErrors + error as MetadataValidationStatus ], onSubmit: backToForm, onCancel: backToDashboard, diff --git a/govtool/frontend/src/hooks/forms/useRegisterAsdRepForm.tsx b/govtool/frontend/src/hooks/forms/useRegisterAsdRepForm.tsx index 22c2aa4cd..d7f502f43 100644 --- a/govtool/frontend/src/hooks/forms/useRegisterAsdRepForm.tsx +++ b/govtool/frontend/src/hooks/forms/useRegisterAsdRepForm.tsx @@ -10,18 +10,15 @@ import { CIP_100, CIP_QQQ, DREP_CONTEXT, - MetadataHashValidationErrors, PATHS, storageInformationErrorModals, } from "@consts"; import { useCardano, useModal } from "@context"; -import { - canonizeJSON, - downloadJson, - generateJsonld, - validateMetadataHash, -} from "@utils"; +import { MetadataValidationStatus } from "@models"; +import { canonizeJSON, downloadJson, generateJsonld } from "@utils"; + import { useGetVoterInfo } from ".."; +import { useValidateMutation } from "../mutations"; export type RegisterAsDRepValues = { bio?: string; @@ -44,6 +41,7 @@ export const defaultRegisterAsDRepValues: RegisterAsDRepValues = { export const useRegisterAsdRepForm = ( setStep?: Dispatch>, ) => { + const { validateMetadata } = useValidateMutation(); const { t } = useTranslation(); const navigate = useNavigate(); const [isLoading, setIsLoading] = useState(false); @@ -116,21 +114,27 @@ export const useRegisterAsdRepForm = ( }; const validateHash = useCallback( - async (storingUrl: string) => { + async (url: string) => { try { - if (!hash) throw new Error(MetadataHashValidationErrors.INVALID_HASH); + if (!hash) throw new Error(MetadataValidationStatus.INVALID_HASH); - await validateMetadataHash(storingUrl, hash); + const result = await validateMetadata({ url, hash }); + + if (result.status) { + throw result.status; + } // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { if ( - Object.values(MetadataHashValidationErrors).includes(error.message) + Object.values(MetadataValidationStatus).includes( + error as MetadataValidationStatus, + ) ) { openModal({ type: "statusModal", state: { ...storageInformationErrorModals[ - error.message as MetadataHashValidationErrors + error as MetadataValidationStatus ], onSubmit: backToForm, onCancel: backToDashboard, diff --git a/govtool/frontend/src/hooks/forms/useVoteContextForm.tsx b/govtool/frontend/src/hooks/forms/useVoteContextForm.tsx index 27cfccede..b14f1722f 100644 --- a/govtool/frontend/src/hooks/forms/useVoteContextForm.tsx +++ b/govtool/frontend/src/hooks/forms/useVoteContextForm.tsx @@ -2,20 +2,14 @@ import { Dispatch, SetStateAction, useCallback, useState } from "react"; import { NodeObject } from "jsonld"; import { useFormContext } from "react-hook-form"; import { blake2bHex } from "blakejs"; - -import { - CIP_108, - MetadataHashValidationErrors, - VOTE_TEST_CONTEXT, -} from "@consts"; -import { - canonizeJSON, - downloadJson, - generateJsonld, - validateMetadataHash, -} from "@utils"; import { captureException } from "@sentry/react"; +import { CIP_108, VOTE_TEST_CONTEXT } from "@consts"; +import { canonizeJSON, downloadJson, generateJsonld } from "@utils"; +import { MetadataValidationStatus } from "@models"; + +import { useValidateMutation } from "../mutations"; + export type VoteContextFormValues = { voteContextText: string; terms?: boolean; @@ -27,6 +21,7 @@ export const useVoteContextForm = ( setStep?: Dispatch>, setErrorMessage?: Dispatch>, ) => { + const { validateMetadata } = useValidateMutation(); const [hash, setHash] = useState(null); const [json, setJson] = useState(null); @@ -71,18 +66,19 @@ export const useVoteContextForm = ( }, [json]); const validateHash = useCallback( - async (storingUrl: string, localHash: string | null) => { + async (url: string, localHash: string | null) => { try { if (!localHash) { - throw new Error(MetadataHashValidationErrors.INVALID_HASH); + throw new Error(MetadataValidationStatus.INVALID_HASH); + } + const result = await validateMetadata({ url, hash: localHash }); + if (result.status) { + throw result.status; } - await validateMetadataHash(storingUrl, localHash); // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { - if ( - Object.values(MetadataHashValidationErrors).includes(error.message) - ) { - if (setErrorMessage) setErrorMessage(error.message); + if (Object.values(MetadataValidationStatus).includes(error)) { + if (setErrorMessage) setErrorMessage(error); if (setStep) setStep(4); } throw error; diff --git a/govtool/frontend/src/hooks/mutations/index.ts b/govtool/frontend/src/hooks/mutations/index.ts new file mode 100644 index 000000000..c70ff462e --- /dev/null +++ b/govtool/frontend/src/hooks/mutations/index.ts @@ -0,0 +1 @@ +export * from "./metadataValidation"; diff --git a/govtool/frontend/src/hooks/mutations/metadataValidation/index.ts b/govtool/frontend/src/hooks/mutations/metadataValidation/index.ts new file mode 100644 index 000000000..61abbe804 --- /dev/null +++ b/govtool/frontend/src/hooks/mutations/metadataValidation/index.ts @@ -0,0 +1 @@ +export * from "./useValidateMutation"; diff --git a/govtool/frontend/src/hooks/mutations/metadataValidation/useValidateMutation.ts b/govtool/frontend/src/hooks/mutations/metadataValidation/useValidateMutation.ts new file mode 100644 index 000000000..9363ca7f1 --- /dev/null +++ b/govtool/frontend/src/hooks/mutations/metadataValidation/useValidateMutation.ts @@ -0,0 +1,18 @@ +import { useMutation } from "react-query"; + +import { postValidate } from "@services"; +import { MUTATION_KEYS } from "@consts"; +import { MetadataValidationDTO } from "@models"; + +export const useValidateMutation = () => { + const { data, isLoading, mutateAsync } = useMutation({ + mutationFn: (body: MetadataValidationDTO) => postValidate(body), + mutationKey: [MUTATION_KEYS.postValidateKey], + }); + + return { + validateMetadata: mutateAsync, + validationStatus: data, + isValidating: isLoading, + }; +}; diff --git a/govtool/frontend/src/models/index.ts b/govtool/frontend/src/models/index.ts index 331bf6b43..46b6a8e5d 100644 --- a/govtool/frontend/src/models/index.ts +++ b/govtool/frontend/src/models/index.ts @@ -1,3 +1,4 @@ export * from "./api"; export * from "./snackbar"; export * from "./wallet"; +export * from "./metadataValidation"; diff --git a/govtool/frontend/src/models/metadataValidation.ts b/govtool/frontend/src/models/metadataValidation.ts new file mode 100644 index 000000000..284a8821c --- /dev/null +++ b/govtool/frontend/src/models/metadataValidation.ts @@ -0,0 +1,16 @@ +// TODO: Should be taken from @govtool/metadata-validation +export enum MetadataValidationStatus { + URL_NOT_FOUND = "URL_NOT_FOUND", + INVALID_JSONLD = "INVALID_JSONLD", + INVALID_HASH = "INVALID_HASH", +} + +export type ValidateMetadataResult = { + status?: MetadataValidationStatus; + valid: boolean; +}; + +export type MetadataValidationDTO = { + url: string; + hash: string; +}; diff --git a/govtool/frontend/src/services/API.ts b/govtool/frontend/src/services/API.ts index 8ac9341f2..1815ecbc2 100644 --- a/govtool/frontend/src/services/API.ts +++ b/govtool/frontend/src/services/API.ts @@ -1,13 +1,18 @@ import axios from "axios"; +import { NavigateFunction } from "react-router-dom"; import { PATHS } from "@consts"; -import { NavigateFunction } from "react-router-dom"; const TIMEOUT_IN_SECONDS = 30 * 1000; // 1000 ms is 1 s then its 10 s const BASE_URL = import.meta.env.VITE_BASE_URL; export const API = axios.create({ - baseURL: BASE_URL, + baseURL: `${BASE_URL}api`, + timeout: TIMEOUT_IN_SECONDS, +}); + +export const METADATA_VALIDATION_API = axios.create({ + baseURL: `${BASE_URL}metadata-validation`, timeout: TIMEOUT_IN_SECONDS, }); diff --git a/govtool/frontend/src/services/requests/index.ts b/govtool/frontend/src/services/requests/index.ts index 747289515..3121e4c5c 100644 --- a/govtool/frontend/src/services/requests/index.ts +++ b/govtool/frontend/src/services/requests/index.ts @@ -17,3 +17,4 @@ export * from "./postDRepRegister"; export * from "./postDRepRemoveVote"; export * from "./postDRepRetire"; export * from "./postDRepVote"; +export * from "./metadataValidation"; diff --git a/govtool/frontend/src/services/requests/metadataValidation/index.ts b/govtool/frontend/src/services/requests/metadataValidation/index.ts new file mode 100644 index 000000000..3eb5cea95 --- /dev/null +++ b/govtool/frontend/src/services/requests/metadataValidation/index.ts @@ -0,0 +1 @@ +export * from "./postValidate"; diff --git a/govtool/frontend/src/services/requests/metadataValidation/postValidate.ts b/govtool/frontend/src/services/requests/metadataValidation/postValidate.ts new file mode 100644 index 000000000..4dd95281b --- /dev/null +++ b/govtool/frontend/src/services/requests/metadataValidation/postValidate.ts @@ -0,0 +1,11 @@ +import type { MetadataValidationDTO, ValidateMetadataResult } from "@models"; +import { METADATA_VALIDATION_API } from "../../API"; + +export const postValidate = async (body: MetadataValidationDTO) => { + const response = await METADATA_VALIDATION_API.post( + `/validate`, + body, + ); + + return response.data; +}; diff --git a/govtool/frontend/src/utils/tests/validateMetadataHash.test.ts b/govtool/frontend/src/utils/tests/validateMetadataHash.test.ts deleted file mode 100644 index b6bd163c7..000000000 --- a/govtool/frontend/src/utils/tests/validateMetadataHash.test.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { vi } from "vitest"; -import { API } from "@/services"; -import { validateMetadataHash } from ".."; - -describe("validateMetadataHash", () => { - const mockHash = "abcdef1234567890"; - - it("should throw an error for invalid URL", async () => { - const invalidURL = "invalid-url"; - await expect(validateMetadataHash(invalidURL, mockHash)).rejects.toThrow( - "Invalid URL", - ); - }); - - it("should throw an error for invalid JSON", async () => { - const invalidJSONURL = "https://example.com/invalid-json"; - vi.spyOn(API, "get").mockRejectedValueOnce(new Error("Invalid JSON")); - await expect( - validateMetadataHash(invalidJSONURL, mockHash), - ).rejects.toThrow("Invalid JSON"); - }); - - // TODO: Provide tests for invalid hash -}); diff --git a/govtool/frontend/src/utils/validateMetadataHash.ts b/govtool/frontend/src/utils/validateMetadataHash.ts index 4c9f640eb..af8ece41d 100644 --- a/govtool/frontend/src/utils/validateMetadataHash.ts +++ b/govtool/frontend/src/utils/validateMetadataHash.ts @@ -1,11 +1,7 @@ import * as blake from "blakejs"; -import { isAxiosError } from "axios"; import { API } from "@services"; -import { - sharedGovernanceActionFields, - MetadataHashValidationErrors, -} from "@consts"; +import { sharedGovernanceActionFields } from "@consts"; import { URL_REGEX, areObjectsTheSame, canonizeJSON } from "."; @@ -15,54 +11,6 @@ export enum GAMetedataErrors { INCORRECT_FORMAT = "Data Formatted Incorrectly", } -/** - * Validates the metadata hash by fetching the metadata from the given URL, - * canonizing it, and comparing the hash with the provided hash. - * - * @param storingURL - The URL where the metadata is stored. - * @param hash - The hash to compare with the calculated hash of the metadata. - * @returns A promise that resolves to `true` if the metadata hash is valid, - * or rejects with an error message if validation fails. - */ -export const validateMetadataHash = async ( - storingURL: string, - hash: string, -) => { - try { - if (!storingURL.match(URL_REGEX)) { - throw new Error(MetadataHashValidationErrors.INVALID_URL); - } - - const { data: userMetadataJSON } = await API.get(storingURL); - - let canonizedUserMetadata; - try { - canonizedUserMetadata = await canonizeJSON(userMetadataJSON); - } catch (error) { - throw new Error(MetadataHashValidationErrors.INVALID_JSON); - } - if (!canonizedUserMetadata) { - throw new Error(MetadataHashValidationErrors.INVALID_JSON); - } - - const hashedUserMetadata = blake.blake2bHex( - canonizedUserMetadata, - undefined, - 32, - ); - - if (hashedUserMetadata !== hash) { - throw new Error(MetadataHashValidationErrors.INVALID_HASH); - } - return true; - } catch (error) { - if (isAxiosError(error)) { - throw new Error(MetadataHashValidationErrors.FETCH_ERROR); - } - throw error; - } -}; - export const checkIsMissingGAMetadata = async ({ url, hash, diff --git a/govtool/metadata-validation/src/app.controller.ts b/govtool/metadata-validation/src/app.controller.ts index 0bcf57fe9..6b248a789 100644 --- a/govtool/metadata-validation/src/app.controller.ts +++ b/govtool/metadata-validation/src/app.controller.ts @@ -1,4 +1,4 @@ -import { Controller, Get, Body } from '@nestjs/common'; +import { Controller, Body, Post } from '@nestjs/common'; import { AppService } from './app.service'; import { ValidateMetadataDTO } from './dto/validateMetadata.dto'; import { ValidateMetadataResult } from './types/validateMetadata'; @@ -7,7 +7,7 @@ import { ValidateMetadataResult } from './types/validateMetadata'; export class AppController { constructor(private readonly appService: AppService) {} - @Get('validate') + @Post('validate') validateMetadata( @Body() validateMetadataDto: ValidateMetadataDTO, ): Promise { diff --git a/scripts/govtool/config/templates/docker-compose.yml.tpl b/scripts/govtool/config/templates/docker-compose.yml.tpl index 4cf11a525..cc05931c3 100644 --- a/scripts/govtool/config/templates/docker-compose.yml.tpl +++ b/scripts/govtool/config/templates/docker-compose.yml.tpl @@ -246,7 +246,7 @@ services: - "traefik.http.routers.frontend.rule=Host(``)" - "traefik.http.routers.frontend.entrypoints=websecure" - "traefik.http.routers.frontend.tls.certresolver=myresolver" - - "traefik.http.middlewares.frontend-csp.headers.contentSecurityPolicy=default-src 'self'; img-src *.usersnap.com 'self' data:; script-src *.usersnap.com 'self' 'unsafe-inline' https://www.googletagmanager.com https://browser.sentry-cdn.com; style-src *.usersnap.com *.googleapis.com 'self' 'unsafe-inline' https://fonts.googleapis.com; connect-src *.usersnap.com https://s3.eu-central-1.amazonaws.com/upload.usersnap.com 'self' o4506155985141760.ingest.sentry.io *.google-analytics.com *.githubusercontent.com *.ipfs.io; font-src *.usersnap.com *.gstatic.com 'self' 'unsafe-inline' https://fonts.gstatic.com; worker-src blob:" + - "traefik.http.middlewares.frontend-csp.headers.contentSecurityPolicy=default-src 'self'; img-src *.usersnap.com 'self' data:; script-src *.usersnap.com 'self' 'unsafe-inline' https://www.googletagmanager.com https://browser.sentry-cdn.com; style-src *.usersnap.com *.googleapis.com 'self' 'unsafe-inline' https://fonts.googleapis.com; connect-src *.usersnap.com https://s3.eu-central-1.amazonaws.com/upload.usersnap.com 'self' o4506155985141760.ingest.sentry.io *.google-analytics.com; font-src *.usersnap.com *.gstatic.com 'self' 'unsafe-inline' https://fonts.gstatic.com; worker-src blob:" - "traefik.http.routers.frontend.middlewares=frontend-csp@docker" - "traefik.http.services.frontend.loadbalancer.server.port=80"