Skip to content

Commit d451b67

Browse files
authored
Merge pull request #2562 from planetarium/fix/PLD-1393-create-keystore-dir-on-qr-import
fix(import): create keystore dir on QR/keyfile import (PLD-1393)
2 parents f8df9b9 + 0d9f428 commit d451b67

2 files changed

Lines changed: 62 additions & 0 deletions

File tree

__tests__/qrDecode.test.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import fs from "fs";
2+
import os from "os";
3+
import path from "path";
4+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
5+
import { checkAndSaveFile } from "src/utils/qrDecode";
6+
7+
const SAMPLE_KEYSTORE = JSON.stringify({
8+
version: 3,
9+
id: "00000000-0000-0000-0000-000000000000",
10+
address: "0000000000000000000000000000000000000000",
11+
});
12+
const SAMPLE_UUID = "00000000-0000-0000-0000-000000000000";
13+
14+
describe("checkAndSaveFile", () => {
15+
let baseDir: string;
16+
17+
beforeEach(() => {
18+
baseDir = fs.mkdtempSync(path.join(os.tmpdir(), "qr-decode-test-"));
19+
});
20+
21+
afterEach(() => {
22+
fs.rmSync(baseDir, { recursive: true, force: true });
23+
});
24+
25+
it("creates the keystore directory when it does not exist (PLD-1393)", async () => {
26+
// Simulate a PC that has never created an account: the keystore folder
27+
// does not exist yet.
28+
const keyStorePath = path.join(baseDir, "planetarium", "keystore");
29+
expect(fs.existsSync(keyStorePath)).toBe(false);
30+
31+
await expect(
32+
checkAndSaveFile(keyStorePath, SAMPLE_KEYSTORE, SAMPLE_UUID),
33+
).resolves.toBeUndefined();
34+
35+
expect(fs.existsSync(keyStorePath)).toBe(true);
36+
const files = fs.readdirSync(keyStorePath);
37+
expect(files.some((f) => f.includes(SAMPLE_UUID))).toBe(true);
38+
});
39+
40+
it("saves into an already-existing directory", async () => {
41+
await expect(
42+
checkAndSaveFile(baseDir, SAMPLE_KEYSTORE, SAMPLE_UUID),
43+
).resolves.toBeUndefined();
44+
45+
const files = fs.readdirSync(baseDir);
46+
expect(files.some((f) => f.includes(SAMPLE_UUID))).toBe(true);
47+
});
48+
49+
it("rejects when a key with the same uuid already exists", async () => {
50+
await checkAndSaveFile(baseDir, SAMPLE_KEYSTORE, SAMPLE_UUID);
51+
52+
await expect(
53+
checkAndSaveFile(baseDir, SAMPLE_KEYSTORE, SAMPLE_UUID),
54+
).rejects.toThrow("This key already exists.");
55+
});
56+
});

src/utils/qrDecode.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ export async function checkAndSaveFile(
5454
): Promise<void> {
5555
return new Promise((resolve, reject) => {
5656
try {
57+
// Ensure the keystore directory exists. On a PC that has never created
58+
// an account (e.g. a mobile-only user importing via QR for the first
59+
// time), the keystore folder is missing and readdirSync/writeFileSync
60+
// would throw ENOENT. This mirrors Web3KeyStore.import's behavior.
61+
fs.mkdirSync(dirPath, { recursive: true });
62+
5763
const files = fs.readdirSync(dirPath);
5864

5965
const fileExists = files.some((file) => file.includes(uuid));

0 commit comments

Comments
 (0)