From dc655e8722bc688a6d4c7136f0d4a08654947637 Mon Sep 17 00:00:00 2001 From: gongjuyeonhee Date: Sat, 26 Oct 2024 13:24:12 +0900 Subject: [PATCH 1/6] fix: resolve confilct --- src/renderer/hooks/useKeyImport.ts | 39 +++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/renderer/hooks/useKeyImport.ts b/src/renderer/hooks/useKeyImport.ts index 6fc557c9f..2bf8e50f1 100644 --- a/src/renderer/hooks/useKeyImport.ts +++ b/src/renderer/hooks/useKeyImport.ts @@ -13,11 +13,48 @@ export default function useKeyImport() { const [key, setKey] = useState({}); const [error, setError] = useState(null); + // 파일 이름 정규식으로 검증 + const isValidFileName = (fileName: string) => { + const regex = /^[a-z0-9]{3,15}\.(txt|json)$/; + return regex.test(fileName); + }; + + //파일 형식 검증 + const isImageFile = (fileName: string) => { + const imageExtensions = /\.(png|jpg|jpeg|gif)$/i; + return imageExtensions.test(fileName); + }; + const handleSubmit = async () => { let privateKey: RawPrivateKey; if (key.keyFile) { + // QR 디코딩을 사용하지 않고 파일을 그대로 + const fileName = key.keyFile.name; + + // + if (!isValidFileName(fileName)) { + setError(t("Invalid file name format.")); + return; + } + try { - const keystore = await decodeQRCode(key.keyFile); + //qr디코딩 없이 일반 파일로 처리 + const keystore = await key.keyFile.text(); + + //이미지 파일일 경우 qr코드 디코드 + if (isImageFile(fileName)) { + const keystore = await decodeQRCode(key.keyFile); + } + + // JSON 검증 + try { + JSON.parse(keystore); + } catch (e) { + setError(t("Invalid JSON format in the file.")); + return; + } + + // const keystore = await decodeQRCode(key.keyFile); const { id, address }: { id: string; address: string } = JSON.parse(keystore); try { From b02d0f1f8939f456fea7f9f21208b0a1efdea32d Mon Sep 17 00:00:00 2001 From: gongjuyeonhee Date: Sat, 26 Oct 2024 13:37:02 +0900 Subject: [PATCH 2/6] =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/hooks/useKeyImport.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/renderer/hooks/useKeyImport.ts b/src/renderer/hooks/useKeyImport.ts index 2bf8e50f1..1a66a346b 100644 --- a/src/renderer/hooks/useKeyImport.ts +++ b/src/renderer/hooks/useKeyImport.ts @@ -54,7 +54,6 @@ export default function useKeyImport() { return; } - // const keystore = await decodeQRCode(key.keyFile); const { id, address }: { id: string; address: string } = JSON.parse(keystore); try { From 4e5bfe3277c4651b88be2f563bca46458f927bc2 Mon Sep 17 00:00:00 2001 From: gongjuyeonhee Date: Sat, 26 Oct 2024 14:58:11 +0900 Subject: [PATCH 3/6] =?UTF-8?q?json=20=ED=8C=8C=EC=9D=BC=20=EB=82=B4?= =?UTF-8?q?=EC=9A=A9=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/hooks/useKeyImport.ts | 57 ++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/src/renderer/hooks/useKeyImport.ts b/src/renderer/hooks/useKeyImport.ts index 1a66a346b..d8600f286 100644 --- a/src/renderer/hooks/useKeyImport.ts +++ b/src/renderer/hooks/useKeyImport.ts @@ -13,25 +13,64 @@ export default function useKeyImport() { const [key, setKey] = useState({}); const [error, setError] = useState(null); - // 파일 이름 정규식으로 검증 const isValidFileName = (fileName: string) => { - const regex = /^[a-z0-9]{3,15}\.(txt|json)$/; - return regex.test(fileName); + const utcRegex = + /^UTC--\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z--[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; + const jsonRegex = /\.json$/i; + return utcRegex.test(fileName) || jsonRegex.test(fileName); }; //파일 형식 검증 const isImageFile = (fileName: string) => { - const imageExtensions = /\.(png|jpg|jpeg|gif)$/i; + const imageExtensions = /\.(png|jpg|jpeg)$/i; return imageExtensions.test(fileName); }; + // 파일 안 내용 검증 + function validateWeb3SecretStorage(json: any): boolean { + const schema: { [key: string]: any } = { + version: "number", + id: "string", + address: "string", + crypto: { + ciphertext: "string", + cipherparams: { + iv: "string", + }, + cipher: "string", + kdf: "string", + kdfparams: { + dklen: "number", + salt: "string", + n: "number", + r: "number", + p: "number", + }, + mac: "string", + }, + }; + + function validate(obj: any, schema: any): boolean { + for (const key in schema) { + if (typeof schema[key] === "object") { + if (!obj[key] || typeof obj[key] !== "object") return false; + if (!validate(obj[key], schema[key])) return false; + } else if (typeof obj[key] !== schema[key]) { + return false; + } + } + return true; + } + + return validate(json, schema); + } + const handleSubmit = async () => { let privateKey: RawPrivateKey; if (key.keyFile) { // QR 디코딩을 사용하지 않고 파일을 그대로 const fileName = key.keyFile.name; - // if (!isValidFileName(fileName)) { setError(t("Invalid file name format.")); return; @@ -50,7 +89,13 @@ export default function useKeyImport() { try { JSON.parse(keystore); } catch (e) { - setError(t("Invalid JSON format in the file.")); + setError(t("Invalid JSON format")); + return; + } + + // JSON 내용 검증 + if (!validateWeb3SecretStorage(JSON.parse(keystore))) { + setError(t("Invalid keystore JSON")); return; } From a03301fbbd06d597f19f5342ad8be9880c58c54f Mon Sep 17 00:00:00 2001 From: gongjuyeonhee Date: Sat, 26 Oct 2024 15:35:30 +0900 Subject: [PATCH 4/6] =?UTF-8?q?useKeyImports=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/hooks/useKeyImport.ts | 44 ++++++++++++++---------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/src/renderer/hooks/useKeyImport.ts b/src/renderer/hooks/useKeyImport.ts index d8600f286..19dfd195d 100644 --- a/src/renderer/hooks/useKeyImport.ts +++ b/src/renderer/hooks/useKeyImport.ts @@ -40,11 +40,10 @@ export default function useKeyImport() { cipher: "string", kdf: "string", kdfparams: { + c: "number", dklen: "number", + prf: "string", salt: "string", - n: "number", - r: "number", - p: "number", }, mac: "string", }, @@ -68,34 +67,31 @@ export default function useKeyImport() { const handleSubmit = async () => { let privateKey: RawPrivateKey; if (key.keyFile) { - // QR 디코딩을 사용하지 않고 파일을 그대로 const fileName = key.keyFile.name; - if (!isValidFileName(fileName)) { - setError(t("Invalid file name format.")); - return; - } - try { //qr디코딩 없이 일반 파일로 처리 - const keystore = await key.keyFile.text(); + const keyFileText = await key.keyFile.text(); + let keystore; - //이미지 파일일 경우 qr코드 디코드 if (isImageFile(fileName)) { - const keystore = await decodeQRCode(key.keyFile); - } - - // JSON 검증 - try { - JSON.parse(keystore); - } catch (e) { - setError(t("Invalid JSON format")); - return; - } + keystore = await decodeQRCode(key.keyFile); + } else if (!isValidFileName(fileName)) { + try { + JSON.parse(keyFileText); + } catch (e) { + setError(t("Invalid JSON format")); + return; + } - // JSON 내용 검증 - if (!validateWeb3SecretStorage(JSON.parse(keystore))) { - setError(t("Invalid keystore JSON")); + // JSON 내용 검증 + if (!validateWeb3SecretStorage(JSON.parse(keyFileText))) { + setError(t("Invalid keystore JSON")); + return; + } + keystore = JSON.parse(keyFileText); + } else { + setError(t("Invalid keyFile text")); return; } From 348ec10bbefc576bd06b3115e8f80d9842c5c2b2 Mon Sep 17 00:00:00 2001 From: gongjuyeonhee Date: Sat, 26 Oct 2024 15:56:56 +0900 Subject: [PATCH 5/6] =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/hooks/useKeyImport.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/renderer/hooks/useKeyImport.ts b/src/renderer/hooks/useKeyImport.ts index 19dfd195d..97b9e24c6 100644 --- a/src/renderer/hooks/useKeyImport.ts +++ b/src/renderer/hooks/useKeyImport.ts @@ -15,9 +15,8 @@ export default function useKeyImport() { const isValidFileName = (fileName: string) => { const utcRegex = - /^UTC--\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z--[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; - const jsonRegex = /\.json$/i; - return utcRegex.test(fileName) || jsonRegex.test(fileName); + /^UTC--\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z--[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}.json$/i; + return utcRegex.test(fileName); }; //파일 형식 검증 @@ -76,7 +75,7 @@ export default function useKeyImport() { if (isImageFile(fileName)) { keystore = await decodeQRCode(key.keyFile); - } else if (!isValidFileName(fileName)) { + } else if (isValidFileName(fileName)) { try { JSON.parse(keyFileText); } catch (e) { From c36a9a02d2e5081d4d8e8d5467774a88ea2b6472 Mon Sep 17 00:00:00 2001 From: gongjuyeonhee Date: Sat, 26 Oct 2024 16:03:18 +0900 Subject: [PATCH 6/6] =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/hooks/useKeyImport.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/renderer/hooks/useKeyImport.ts b/src/renderer/hooks/useKeyImport.ts index 97b9e24c6..66666983b 100644 --- a/src/renderer/hooks/useKeyImport.ts +++ b/src/renderer/hooks/useKeyImport.ts @@ -76,19 +76,14 @@ export default function useKeyImport() { if (isImageFile(fileName)) { keystore = await decodeQRCode(key.keyFile); } else if (isValidFileName(fileName)) { - try { - JSON.parse(keyFileText); - } catch (e) { - setError(t("Invalid JSON format")); - return; - } + const parsedKeyFile = JSON.parse(keyFileText); // JSON 내용 검증 - if (!validateWeb3SecretStorage(JSON.parse(keyFileText))) { + if (!validateWeb3SecretStorage(parsedKeyFile)) { setError(t("Invalid keystore JSON")); return; } - keystore = JSON.parse(keyFileText); + keystore = keyFileText; } else { setError(t("Invalid keyFile text")); return;