Skip to content

Commit

Permalink
chore: added sanitization for local storage values
Browse files Browse the repository at this point in the history
  • Loading branch information
aaryan610 committed Oct 17, 2024
1 parent 0e91448 commit add87b4
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ export const CustomCalloutExtensionConfig = Node.create({
};
},

// Parse HTML elements matching the class 'callout'
parseHTML() {
return [{ tag: "callout-component" }];
},
Expand Down
5 changes: 2 additions & 3 deletions packages/editor/src/core/extensions/callout/logo-selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export const CalloutBlockLogoSelector: React.FC<Props> = (props) => {
in_use: "emoji",
emoji: {
value: convertHexEmojiToDecimal(val.value.unified),
url: val.value.imageUrl,
},
};
} else if (val.type === "icon") {
Expand All @@ -87,9 +88,7 @@ export const CalloutBlockLogoSelector: React.FC<Props> = (props) => {
handleOpen(false);
}}
defaultIconColor={logoValue?.in_use && logoValue.in_use === "icon" ? logoValue?.icon?.color : undefined}
defaultOpen={
logoValue?.in_use && logoValue.in_use === "emoji" ? EmojiIconPickerTypes.EMOJI : EmojiIconPickerTypes.ICON
}
defaultOpen={logoValue.in_use === "emoji" ? EmojiIconPickerTypes.EMOJI : EmojiIconPickerTypes.ICON}
disabled={disabled}
/>
</div>
Expand Down
43 changes: 28 additions & 15 deletions packages/editor/src/core/extensions/callout/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// plane helpers
import { sanitizeHTML } from "@plane/helpers";
// plane ui
import { TEmojiLogoProps } from "@plane/ui";
// types
Expand All @@ -17,35 +19,46 @@ export const DEFAULT_CALLOUT_BLOCK_ATTRIBUTES: TCalloutBlockAttributes = {
"data-background": null,
};

type TStoredLogoValue = Pick<TCalloutBlockAttributes, EAttributeNames.LOGO_IN_USE> &
(TCalloutBlockEmojiAttributes | TCalloutBlockIconAttributes);

// function to get the stored logo from local storage
export const getStoredLogo = (): Pick<TCalloutBlockAttributes, EAttributeNames.LOGO_IN_USE> &
(TCalloutBlockEmojiAttributes | TCalloutBlockIconAttributes) => {
export const getStoredLogo = (): TStoredLogoValue => {
const fallBackValues: TStoredLogoValue = {
"data-logo-in-use": "emoji",
"data-emoji-unicode": DEFAULT_CALLOUT_BLOCK_ATTRIBUTES["data-emoji-unicode"],
"data-emoji-url": DEFAULT_CALLOUT_BLOCK_ATTRIBUTES["data-emoji-url"],
};

if (typeof window !== "undefined") {
const storedData = localStorage.getItem("editor-calloutComponent-logo");
const storedData = sanitizeHTML(localStorage.getItem("editor-calloutComponent-logo"));
if (storedData) {
const parsedData: TEmojiLogoProps = JSON.parse(storedData);
let parsedData: TEmojiLogoProps;
try {
parsedData = JSON.parse(storedData);
} catch (error) {
console.error(`Error parsing stored callout logo, stored value- ${storedData}`, error);

Check notice on line 40 in packages/editor/src/core/extensions/callout/utils.ts

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

packages/editor/src/core/extensions/callout/utils.ts#L40

Detected string concatenation with a non-literal variable in a util.format / console.log function.
localStorage.removeItem("editor-calloutComponent-logo");
return fallBackValues;
}
if (parsedData.in_use === "emoji" && parsedData.emoji?.value) {
return {
"data-logo-in-use": "emoji",
"data-emoji-unicode": parsedData.emoji.value,
"data-emoji-url": parsedData.emoji.url,
"data-emoji-unicode": parsedData.emoji.value || DEFAULT_CALLOUT_BLOCK_ATTRIBUTES["data-emoji-unicode"],
"data-emoji-url": parsedData.emoji.url || DEFAULT_CALLOUT_BLOCK_ATTRIBUTES["data-emoji-url"],
};
}
if (parsedData.in_use === "icon" && parsedData.icon?.name) {
return {
"data-logo-in-use": "icon",
"data-icon-name": parsedData.icon.name,
"data-icon-color": parsedData.icon.color || "",
"data-icon-name": parsedData.icon.name || DEFAULT_CALLOUT_BLOCK_ATTRIBUTES["data-icon-name"],
"data-icon-color": parsedData.icon.color || DEFAULT_CALLOUT_BLOCK_ATTRIBUTES["data-icon-color"],
};
}
}
}
// fallback values
return {
"data-logo-in-use": "emoji",
"data-emoji-unicode": DEFAULT_CALLOUT_BLOCK_ATTRIBUTES["data-emoji-unicode"],
"data-emoji-url": DEFAULT_CALLOUT_BLOCK_ATTRIBUTES["data-emoji-url"],
};
return fallBackValues;
};
// function to update the stored logo on local storage
export const updateStoredLogo = (value: TEmojiLogoProps): void => {
Expand All @@ -55,14 +68,14 @@ export const updateStoredLogo = (value: TEmojiLogoProps): void => {
// function to get the stored background color from local storage
export const getStoredBackgroundColor = (): string | null => {
if (typeof window !== "undefined") {
return localStorage.getItem("editor-calloutComponent-background");
return sanitizeHTML(localStorage.getItem("editor-calloutComponent-background"));
}
return null;
};
// function to update the stored background color on local storage
export const updateStoredBackgroundColor = (value: string | null): void => {
if (typeof window === "undefined") return;
if (!value) {
if (value === null) {
localStorage.removeItem("editor-calloutComponent-background");
return;
} else {
Expand Down
3 changes: 2 additions & 1 deletion packages/helpers/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./emoji.helper"
export * from "./emoji.helper"
export * from "./string.helper"
15 changes: 15 additions & 0 deletions packages/helpers/helpers/string.helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import DOMPurify from "isomorphic-dompurify";

/**
* @description: This function will remove all the HTML tags from the string
* @param {string} html
* @return {string}
* @example:
* const html = "<p>Some text</p>";
* const text = stripHTML(html);
* console.log(text); // Some text
*/
export const sanitizeHTML = (htmlString: string) => {
const sanitizedText = DOMPurify.sanitize(htmlString, { ALLOWED_TAGS: [] }); // sanitize the string to remove all HTML tags
return sanitizedText.trim(); // trim the string to remove leading and trailing whitespaces
};
5 changes: 3 additions & 2 deletions packages/helpers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
"devDependencies": {
"@types/node": "^22.5.4",
"@types/react": "^18.3.5",
"typescript": "^5.6.2",
"tsup": "^7.2.0"
"tsup": "^7.2.0",
"typescript": "^5.6.2"
},
"dependencies": {
"isomorphic-dompurify": "^2.16.0",
"react": "^18.3.1"
}
}
12 changes: 10 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4129,7 +4129,7 @@
dependencies:
"@types/react" "*"

"@types/react@*", "@types/react@18.2.48", "@types/react@^16.8.0 || ^17.0.0 || ^18.0.0", "@types/react@^18.2.42", "@types/react@^18.2.48", "@types/react@^18.3.5":
"@types/react@*", "@types/react@^16.8.0 || ^17.0.0 || ^18.0.0", "@types/react@^18.2.42", "@types/react@^18.2.48":
version "18.2.48"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.48.tgz#11df5664642d0bd879c1f58bc1d37205b064e8f1"
integrity sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==
Expand All @@ -4138,6 +4138,14 @@
"@types/scheduler" "*"
csstype "^3.0.2"

"@types/react@^18.3.5":
version "18.3.11"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.11.tgz#9d530601ff843ee0d7030d4227ea4360236bd537"
integrity sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ==
dependencies:
"@types/prop-types" "*"
csstype "^3.0.2"

"@types/reactcss@*":
version "1.2.12"
resolved "https://registry.yarnpkg.com/@types/reactcss/-/reactcss-1.2.12.tgz#57f6f046e7aafbe0288689bd96a2d5664378ca7b"
Expand Down Expand Up @@ -8154,7 +8162,7 @@ isexe@^2.0.0:
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==

isomorphic-dompurify@^2.12.0:
isomorphic-dompurify@^2.12.0, isomorphic-dompurify@^2.16.0:
version "2.16.0"
resolved "https://registry.yarnpkg.com/isomorphic-dompurify/-/isomorphic-dompurify-2.16.0.tgz#c46ec33ae6bde43648bd6163925625949113a696"
integrity sha512-cXhX2owp8rPxafCr0ywqy2CGI/4ceLNgWkWBEvUz64KTbtg3oRL2ZRqq/zW0pzt4YtDjkHLbwcp/lozpKzAQjg==
Expand Down

0 comments on commit add87b4

Please sign in to comment.