diff --git a/packages/state/src/hooks/labels.test.ts b/packages/state/src/hooks/labels.test.ts index 2ddc953f10..00d8ed6969 100644 --- a/packages/state/src/hooks/labels.test.ts +++ b/packages/state/src/hooks/labels.test.ts @@ -9,7 +9,7 @@ import { } from "@umami/core"; import { MAINNET } from "@umami/tezos"; -import { useGetNextAvailableAccountLabels, useValidateName } from "./labels"; +import { PROHIBITED_CHARACTERS, useGetNextAvailableAccountLabels, useValidateName } from "./labels"; import { contactsActions, multisigsActions, networksActions } from "../slices"; import { type UmamiStore, makeStore } from "../store"; import { addTestAccounts, renderHook } from "../testUtils"; @@ -22,6 +22,22 @@ beforeEach(() => { describe("labelsHooks", () => { describe("useValidateName", () => { + it.each(PROHIBITED_CHARACTERS)("fails if name contains `%s` special character", char => { + const { + result: { current: validateName }, + } = renderHook(() => useValidateName(), { store }); + + expect(validateName(`Some ${char} name`)).toEqual("Name contains special character(s)"); + }); + + it("fails if name exceeds 256 characters", () => { + const { + result: { current: validateName }, + } = renderHook(() => useValidateName(), { store }); + + expect(validateName("a".repeat(257))).toEqual("Name should not exceed 256 characters"); + }); + describe.each([ { testCase: "with trailing whitespaces", withWhitespaces: true }, { testCase: "without trailing whitespaces", withWhitespaces: false }, diff --git a/packages/state/src/hooks/labels.ts b/packages/state/src/hooks/labels.ts index 7cd545cefc..c5d9452791 100644 --- a/packages/state/src/hooks/labels.ts +++ b/packages/state/src/hooks/labels.ts @@ -1,12 +1,20 @@ import { useAllContacts } from "./contacts"; import { useAllAccounts } from "./getAccountData"; +export const PROHIBITED_CHARACTERS = ["<", ">", '"', "'", "&", "/", "\\", "\t", "\n", "\r", "`"]; + /** Hook for validating name for account or contact. */ export const useValidateName = (oldName?: string | undefined) => { const isUniqueLabel = useIsUniqueLabel(); return (name: string) => { const trimmedName = name.trim(); + if (trimmedName.length > 256) { + return "Name should not exceed 256 characters"; + } + if (PROHIBITED_CHARACTERS.some(char => trimmedName.includes(char))) { + return "Name contains special character(s)"; + } if (trimmedName.length === 0) { return "Name should not be empty"; }