feat: improve validation secret reference

This commit is contained in:
Salman
2024-03-16 00:12:50 +05:30
parent ec64753795
commit 1193e33890
3 changed files with 34 additions and 6 deletions
@@ -5,14 +5,12 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
import { useWorkspace } from "@app/context"; import { useWorkspace } from "@app/context";
import { REGEX_SECRET_REFERENCE_FIND, REGEX_SECRET_REFERENCE_INVALID } from "@app/helpers/secret-reference";
import { useToggle } from "@app/hooks"; import { useToggle } from "@app/hooks";
import { useGetUserWsKey } from "@app/hooks/api"; import { useGetUserWsKey } from "@app/hooks/api";
import { useGetFoldersByEnv } from "@app/hooks/api/secretFolders/queries"; import { useGetFoldersByEnv } from "@app/hooks/api/secretFolders/queries";
import { useGetProjectSecrets } from "@app/hooks/api/secrets/queries"; import { useGetProjectSecrets } from "@app/hooks/api/secrets/queries";
const REGEX_REFERENCE = /(\${([^}]*)})/g;
const REGEX_REFERENCE_INVALID = /(?:\/|\\|\n|\.$|^\.)/g;
const replaceContentWithDot = (str: string) => { const replaceContentWithDot = (str: string) => {
let finalStr = ""; let finalStr = "";
for (let i = 0; i < str.length; i += 1) { for (let i = 0; i < str.length; i += 1) {
@@ -28,7 +26,7 @@ const syntaxHighlight = (content?: string | null, isVisible?: boolean) => {
if (!isVisible) return replaceContentWithDot(content); if (!isVisible) return replaceContentWithDot(content);
let skipNext = false; let skipNext = false;
const formattedContent = content.split(REGEX_REFERENCE).flatMap((el, i) => { const formattedContent = content.split(REGEX_SECRET_REFERENCE_FIND).flatMap((el, i) => {
const isInterpolationSyntax = el.startsWith("${") && el.endsWith("}"); const isInterpolationSyntax = el.startsWith("${") && el.endsWith("}");
if (isInterpolationSyntax) { if (isInterpolationSyntax) {
skipNext = true; skipNext = true;
@@ -38,7 +36,7 @@ const syntaxHighlight = (content?: string | null, isVisible?: boolean) => {
<span <span
className={twMerge( className={twMerge(
"ph-no-capture text-yellow-200/80", "ph-no-capture text-yellow-200/80",
REGEX_REFERENCE_INVALID.test(el.slice(2, -1)) && REGEX_SECRET_REFERENCE_INVALID.test(el.slice(2, -1)) &&
"underline decoration-red decoration-wavy" "underline decoration-red decoration-wavy"
)} )}
> >
@@ -169,7 +167,7 @@ export const SecretInput = forwardRef<HTMLTextAreaElement, Props>(
}, [secrets, environment, referenceKey]); }, [secrets, environment, referenceKey]);
function findMatch(str: string, start: number) { function findMatch(str: string, start: number) {
const matches = [...str.matchAll(REGEX_REFERENCE)]; const matches = [...str.matchAll(REGEX_SECRET_REFERENCE_FIND)];
for (let i = 0; i < matches.length; i += 1) { for (let i = 0; i < matches.length; i += 1) {
const match = matches[i]; const match = matches[i];
if ( if (
+27
View File
@@ -0,0 +1,27 @@
export const REGEX_SECRET_REFERENCE_FIND = /(\${([^}]*)})/g;
export const REGEX_SECRET_REFERENCE_INVALID = /(?:\/|\\|\n|\.$|^\.)/;
export function isValidSecretReferenceValue(str: string): boolean {
try {
if (!str) return true;
let skipNext = false;
str.split(REGEX_SECRET_REFERENCE_FIND).flatMap((el) => {
if (skipNext) {
skipNext = false;
return [];
}
const isInterpolationSyntax = el.startsWith("${") && el.endsWith("}");
if (!isInterpolationSyntax) return [];
skipNext = true;
if (REGEX_SECRET_REFERENCE_INVALID.test(el.slice(2, -1)))
throw new Error("Invalid reference");
return el;
});
return true;
} catch (e) {
return false;
}
}
@@ -7,6 +7,7 @@ import {
encryptSymmetric encryptSymmetric
} from "@app/components/utilities/cryptography/crypto"; } from "@app/components/utilities/cryptography/crypto";
import { apiRequest } from "@app/config/request"; import { apiRequest } from "@app/config/request";
import { isValidSecretReferenceValue } from "@app/helpers/secret-reference";
import { secretApprovalRequestKeys } from "../secretApprovalRequest/queries"; import { secretApprovalRequestKeys } from "../secretApprovalRequest/queries";
import { secretSnapshotKeys } from "../secretSnapshots/queries"; import { secretSnapshotKeys } from "../secretSnapshots/queries";
@@ -83,6 +84,7 @@ export const useCreateSecretV3 = ({
secretComment, secretComment,
skipMultilineEncoding skipMultilineEncoding
}) => { }) => {
if (!isValidSecretReferenceValue(secretValue)) throw new Error("Invalid secret reference");
const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY") as string; const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY") as string;
const randomBytes = latestFileKey const randomBytes = latestFileKey
@@ -144,6 +146,7 @@ export const useUpdateSecretV3 = ({
newSecretName, newSecretName,
skipMultilineEncoding skipMultilineEncoding
}) => { }) => {
if (!isValidSecretReferenceValue(secretValue)) throw new Error("Invalid secret reference");
const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY") as string; const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY") as string;
const randomBytes = latestFileKey const randomBytes = latestFileKey