keyfabe 0.1.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/clone.js +21 -14
- package/dist/commands/clone.js.map +1 -1
- package/dist/commands/delete.d.ts +1 -1
- package/dist/commands/delete.js +17 -3
- package/dist/commands/delete.js.map +1 -1
- package/dist/commands/doctor.js +31 -21
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/export.js +2 -3
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/import.js +5 -5
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/list.d.ts +3 -1
- package/dist/commands/list.js +22 -10
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/read.js +14 -8
- package/dist/commands/read.js.map +1 -1
- package/dist/commands/rename.d.ts +1 -1
- package/dist/commands/rename.js +24 -4
- package/dist/commands/rename.js.map +1 -1
- package/dist/commands/setup.js +65 -56
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/show.d.ts +1 -1
- package/dist/commands/show.js +19 -10
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/write.d.ts +1 -1
- package/dist/commands/write.js +15 -6
- package/dist/commands/write.js.map +1 -1
- package/dist/index.js +49 -6
- package/dist/index.js.map +1 -1
- package/dist/lib/card-ops.js +39 -16
- package/dist/lib/card-ops.js.map +1 -1
- package/dist/lib/display.d.ts +1 -0
- package/dist/lib/display.js +9 -8
- package/dist/lib/display.js.map +1 -1
- package/dist/lib/parsers.d.ts +1 -0
- package/dist/lib/parsers.js +3 -2
- package/dist/lib/parsers.js.map +1 -1
- package/dist/lib/pm3.js +2 -2
- package/dist/lib/pm3.js.map +1 -1
- package/dist/lib/prompts.d.ts +2 -1
- package/dist/lib/prompts.js +25 -17
- package/dist/lib/prompts.js.map +1 -1
- package/package.json +3 -3
package/dist/commands/clone.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import ora from "ora";
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
3
2
|
import { writeAndVerify } from "../lib/card-ops.js";
|
|
4
|
-
import { printCardInfo } from "../lib/display.js";
|
|
3
|
+
import { printCardInfo, printDoctorHint } from "../lib/display.js";
|
|
5
4
|
import { parseLfSearch } from "../lib/parsers.js";
|
|
6
5
|
import { Pm3Error, pm3Exec, requireDevice } from "../lib/pm3.js";
|
|
7
6
|
import { promptName, waitForEnter } from "../lib/prompts.js";
|
|
@@ -11,36 +10,43 @@ const READ_RETRY_DELAY = 2000;
|
|
|
11
10
|
export async function clone() {
|
|
12
11
|
if (!(await requireDevice()))
|
|
13
12
|
return false;
|
|
14
|
-
|
|
13
|
+
p.intro("Keyfob Clone");
|
|
15
14
|
// Step 1: Read original
|
|
16
15
|
await waitForEnter("Place your original keyfob on the antenna.");
|
|
17
16
|
let card = null;
|
|
18
17
|
for (let attempt = 1; attempt <= MAX_READ_RETRIES; attempt++) {
|
|
19
|
-
const
|
|
18
|
+
const s = p.spinner();
|
|
19
|
+
s.start(`Reading original (attempt ${attempt}/${MAX_READ_RETRIES})...`);
|
|
20
20
|
try {
|
|
21
21
|
const { stdout } = await pm3Exec("lf search");
|
|
22
22
|
card = parseLfSearch(stdout);
|
|
23
23
|
if (card) {
|
|
24
|
-
|
|
24
|
+
s.stop("Original card read");
|
|
25
25
|
break;
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
s.stop("No card detected.");
|
|
28
|
+
p.log.error("No card detected.");
|
|
28
29
|
}
|
|
29
30
|
catch (err) {
|
|
30
31
|
if (err instanceof Pm3Error) {
|
|
31
|
-
|
|
32
|
+
s.stop(err.message);
|
|
33
|
+
p.log.error(err.message);
|
|
34
|
+
if (err.message.includes("not found")) {
|
|
35
|
+
printDoctorHint();
|
|
36
|
+
}
|
|
32
37
|
}
|
|
33
38
|
else {
|
|
34
|
-
|
|
39
|
+
s.stop("Read failed.");
|
|
40
|
+
p.log.error("Read failed.");
|
|
35
41
|
}
|
|
36
42
|
}
|
|
37
43
|
if (attempt < MAX_READ_RETRIES) {
|
|
38
|
-
|
|
44
|
+
p.log.info(`Retrying in ${READ_RETRY_DELAY / 1000}s...`);
|
|
39
45
|
await new Promise((r) => setTimeout(r, READ_RETRY_DELAY));
|
|
40
46
|
}
|
|
41
47
|
}
|
|
42
48
|
if (!card) {
|
|
43
|
-
|
|
49
|
+
p.log.error("Failed to read original card after all attempts.");
|
|
44
50
|
return false;
|
|
45
51
|
}
|
|
46
52
|
printCardInfo(card);
|
|
@@ -48,7 +54,7 @@ export async function clone() {
|
|
|
48
54
|
await waitForEnter("Remove original and place a blank T55x7 fob on the antenna.");
|
|
49
55
|
const success = await writeAndVerify(card);
|
|
50
56
|
if (success) {
|
|
51
|
-
|
|
57
|
+
p.log.success("Clone successful!");
|
|
52
58
|
const name = await promptName();
|
|
53
59
|
if (name) {
|
|
54
60
|
await saveFob({
|
|
@@ -58,11 +64,12 @@ export async function clone() {
|
|
|
58
64
|
encoding: card.encoding,
|
|
59
65
|
savedAt: new Date().toISOString(),
|
|
60
66
|
});
|
|
61
|
-
|
|
67
|
+
p.log.success(`Saved as "${name}".`);
|
|
62
68
|
}
|
|
69
|
+
p.outro("Done!");
|
|
63
70
|
return true;
|
|
64
71
|
}
|
|
65
|
-
|
|
72
|
+
p.log.error("Clone failed.");
|
|
66
73
|
return false;
|
|
67
74
|
}
|
|
68
75
|
//# sourceMappingURL=clone.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clone.js","sourceRoot":"","sources":["../../src/commands/clone.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"clone.js","sourceRoot":"","sources":["../../src/commands/clone.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function deleteFob(name
|
|
1
|
+
export declare function deleteFob(name?: string): Promise<boolean>;
|
package/dist/commands/delete.js
CHANGED
|
@@ -1,13 +1,27 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
2
|
import { printFobNotFound } from "../lib/display.js";
|
|
3
|
-
import {
|
|
3
|
+
import { confirm, selectFob } from "../lib/prompts.js";
|
|
4
|
+
import { loadFobs, removeFob } from "../lib/store.js";
|
|
4
5
|
export async function deleteFob(name) {
|
|
6
|
+
if (!name) {
|
|
7
|
+
const fobs = await loadFobs();
|
|
8
|
+
if (fobs.length === 0) {
|
|
9
|
+
p.log.warn("No saved fobs. Use `keyfabe read` or `keyfabe clone` first.");
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
name = await selectFob(fobs, "Which fob to delete?");
|
|
13
|
+
}
|
|
14
|
+
const shouldDelete = await confirm(`Delete "${name}"?`);
|
|
15
|
+
if (!shouldDelete) {
|
|
16
|
+
p.cancel("Deletion cancelled.");
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
5
19
|
const removed = await removeFob(name);
|
|
6
20
|
if (!removed) {
|
|
7
21
|
printFobNotFound(name);
|
|
8
22
|
return false;
|
|
9
23
|
}
|
|
10
|
-
|
|
24
|
+
p.log.success(`Deleted "${name}".`);
|
|
11
25
|
return true;
|
|
12
26
|
}
|
|
13
27
|
//# sourceMappingURL=delete.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAa;IACzC,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,MAAM,IAAI,GAAG,MAAM,QAAQ,EAAE,CAAC;QAC9B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpB,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;YAC1E,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,IAAI,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC;IACxD,IAAI,CAAC,YAAY,EAAE,CAAC;QAChB,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;QAChC,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACvB,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC;IACpC,OAAO,IAAI,CAAC;AAChB,CAAC"}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -1,73 +1,83 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
1
2
|
import chalk from "chalk";
|
|
2
|
-
import ora from "ora";
|
|
3
3
|
import { HF_VOLTAGE_THRESHOLD, LF_VOLTAGE_THRESHOLD, printBrewInstall } from "../lib/display.js";
|
|
4
4
|
import { parseHwStatus, parseHwTune } from "../lib/parsers.js";
|
|
5
5
|
import { detectPort, Pm3Error, pm3Exec } from "../lib/pm3.js";
|
|
6
6
|
export async function doctor() {
|
|
7
|
-
|
|
7
|
+
p.intro("Proxmark3 Health Check");
|
|
8
8
|
// 1. Port detection
|
|
9
9
|
const port = await detectPort();
|
|
10
10
|
if (port) {
|
|
11
|
-
|
|
11
|
+
p.log.success(`Port: ${port}`);
|
|
12
12
|
}
|
|
13
13
|
else {
|
|
14
|
-
|
|
14
|
+
p.log.error("No Proxmark3 detected. Check USB connection.");
|
|
15
15
|
return false;
|
|
16
16
|
}
|
|
17
17
|
// 2. Communication check
|
|
18
|
-
const
|
|
18
|
+
const s = p.spinner();
|
|
19
|
+
s.start("Checking device communication...");
|
|
19
20
|
try {
|
|
20
21
|
const { stdout } = await pm3Exec("hw status");
|
|
21
22
|
const status = parseHwStatus(stdout);
|
|
23
|
+
if (status.isStockFirmware) {
|
|
24
|
+
s.stop("Stock firmware detected.");
|
|
25
|
+
p.log.warn("Stock firmware detected. Run `keyfabe setup` to flash Iceman firmware.");
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
22
28
|
if (!status.connected) {
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
s.stop("Cannot communicate with device.");
|
|
30
|
+
p.log.warn("Cannot communicate with device. Check connection and try `keyfabe setup`.");
|
|
25
31
|
return false;
|
|
26
32
|
}
|
|
27
|
-
|
|
28
|
-
|
|
33
|
+
s.stop("Device communication OK");
|
|
34
|
+
p.log.success(`Firmware: ${status.firmwareVersion}`);
|
|
29
35
|
}
|
|
30
36
|
catch (err) {
|
|
31
37
|
if (err instanceof Pm3Error) {
|
|
32
38
|
if (err.message.includes("not found")) {
|
|
33
|
-
|
|
39
|
+
s.stop("pm3 command not found.");
|
|
34
40
|
printBrewInstall();
|
|
35
41
|
}
|
|
36
42
|
else {
|
|
37
|
-
|
|
43
|
+
s.stop(err.message);
|
|
38
44
|
}
|
|
39
45
|
}
|
|
40
46
|
else {
|
|
41
|
-
|
|
47
|
+
s.stop("Failed to communicate with device.");
|
|
42
48
|
}
|
|
43
49
|
return false;
|
|
44
50
|
}
|
|
45
51
|
// 3. Antenna tuning
|
|
46
|
-
const tuneSpinner =
|
|
52
|
+
const tuneSpinner = p.spinner();
|
|
53
|
+
tuneSpinner.start("Checking antenna tuning...");
|
|
47
54
|
try {
|
|
48
55
|
const { stdout } = await pm3Exec("hw tune");
|
|
49
56
|
const tune = parseHwTune(stdout);
|
|
50
|
-
tuneSpinner.
|
|
57
|
+
tuneSpinner.stop("Antenna tuning complete");
|
|
51
58
|
const lfColor = tune.lfVoltage >= LF_VOLTAGE_THRESHOLD ? chalk.green : chalk.red;
|
|
52
59
|
const hfColor = tune.hfVoltage >= HF_VOLTAGE_THRESHOLD ? chalk.green : chalk.red;
|
|
53
|
-
|
|
54
|
-
|
|
60
|
+
const voltageLines = [
|
|
61
|
+
lfColor(`LF antenna: ${tune.lfVoltage.toFixed(2)}V (125 kHz)`),
|
|
62
|
+
hfColor(`HF antenna: ${tune.hfVoltage.toFixed(2)}V (13.56 MHz)`),
|
|
63
|
+
];
|
|
64
|
+
p.note(voltageLines.join("\n"), "Antenna Tuning");
|
|
55
65
|
if (tune.lfVoltage < LF_VOLTAGE_THRESHOLD) {
|
|
56
|
-
|
|
66
|
+
p.log.warn("LF antenna reading low. Check antenna connection.");
|
|
57
67
|
}
|
|
58
68
|
if (tune.hfVoltage < HF_VOLTAGE_THRESHOLD) {
|
|
59
|
-
|
|
69
|
+
p.log.warn("HF antenna reading low. Check antenna connection.");
|
|
60
70
|
}
|
|
61
71
|
}
|
|
62
72
|
catch (err) {
|
|
63
73
|
if (err instanceof Pm3Error) {
|
|
64
|
-
tuneSpinner.
|
|
74
|
+
tuneSpinner.stop(err.message);
|
|
65
75
|
}
|
|
66
76
|
else {
|
|
67
|
-
tuneSpinner.
|
|
77
|
+
tuneSpinner.stop("Failed to check antenna tuning.");
|
|
68
78
|
}
|
|
69
79
|
}
|
|
70
|
-
|
|
80
|
+
p.outro("Device is healthy!");
|
|
71
81
|
return true;
|
|
72
82
|
}
|
|
73
83
|
//# sourceMappingURL=doctor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/export.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
1
|
import { loadFobs } from "../lib/store.js";
|
|
3
2
|
export async function exportFobs() {
|
|
4
3
|
const fobs = await loadFobs();
|
|
5
4
|
if (fobs.length === 0) {
|
|
6
|
-
console.error(
|
|
5
|
+
console.error("No saved fobs to export.");
|
|
7
6
|
return false;
|
|
8
7
|
}
|
|
9
8
|
// Output clean JSON to stdout for piping
|
|
10
9
|
process.stdout.write(`${JSON.stringify(fobs, null, 2)}\n`);
|
|
11
|
-
console.error(
|
|
10
|
+
console.error(`Exported ${fobs.length} fob(s).`);
|
|
12
11
|
return true;
|
|
13
12
|
}
|
|
14
13
|
//# sourceMappingURL=export.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,UAAU;IAC5B,MAAM,IAAI,GAAG,MAAM,QAAQ,EAAE,CAAC;IAE9B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC1C,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,yCAAyC;IACzC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAC3D,OAAO,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,MAAM,UAAU,CAAC,CAAC;IACjD,OAAO,IAAI,CAAC;AAChB,CAAC"}
|
package/dist/commands/import.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
|
-
import
|
|
2
|
+
import * as p from "@clack/prompts";
|
|
3
3
|
import { importFobs } from "../lib/store.js";
|
|
4
4
|
function validateFobs(data) {
|
|
5
5
|
if (!Array.isArray(data))
|
|
@@ -17,7 +17,7 @@ export async function importFile(filePath) {
|
|
|
17
17
|
raw = await readFile(filePath, "utf-8");
|
|
18
18
|
}
|
|
19
19
|
catch {
|
|
20
|
-
|
|
20
|
+
p.log.error(`Cannot read file: ${filePath}`);
|
|
21
21
|
return false;
|
|
22
22
|
}
|
|
23
23
|
let data;
|
|
@@ -25,15 +25,15 @@ export async function importFile(filePath) {
|
|
|
25
25
|
data = JSON.parse(raw);
|
|
26
26
|
}
|
|
27
27
|
catch {
|
|
28
|
-
|
|
28
|
+
p.log.error("Invalid JSON.");
|
|
29
29
|
return false;
|
|
30
30
|
}
|
|
31
31
|
if (!validateFobs(data)) {
|
|
32
|
-
|
|
32
|
+
p.log.error("Invalid format. Expected an array of fob objects with name, type, id, and savedAt.");
|
|
33
33
|
return false;
|
|
34
34
|
}
|
|
35
35
|
const { added, updated } = await importFobs(data);
|
|
36
|
-
|
|
36
|
+
p.log.success(`Imported ${added} new, updated ${updated} existing.`);
|
|
37
37
|
return true;
|
|
38
38
|
}
|
|
39
39
|
//# sourceMappingURL=import.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/commands/import.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,MAAM,
|
|
1
|
+
{"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/commands/import.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAEpC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,SAAS,YAAY,CAAC,IAAa;IAC/B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,OAAO,IAAI,CAAC,KAAK,CACb,CAAC,IAAI,EAAE,EAAE,CACL,OAAO,IAAI,KAAK,QAAQ;QACxB,IAAI,KAAK,IAAI;QACb,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;QAC7B,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;QAC7B,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ;QAC3B,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CACvC,CAAC;AACN,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC7C,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACD,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACL,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC;QAC7C,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACD,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACL,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAC7B,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,oFAAoF,CAAC,CAAC;QAClG,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IAClD,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,KAAK,iBAAiB,OAAO,YAAY,CAAC,CAAC;IACrE,OAAO,IAAI,CAAC;AAChB,CAAC"}
|
package/dist/commands/list.d.ts
CHANGED
package/dist/commands/list.js
CHANGED
|
@@ -1,26 +1,38 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
2
|
import { loadFobs } from "../lib/store.js";
|
|
3
|
-
export async function list() {
|
|
3
|
+
export async function list(options = {}) {
|
|
4
4
|
const fobs = await loadFobs();
|
|
5
|
+
if (options.json) {
|
|
6
|
+
console.log(JSON.stringify(fobs, null, 2));
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
5
9
|
if (fobs.length === 0) {
|
|
6
|
-
|
|
10
|
+
p.log.info("No saved fobs. Use `keyfabe read` or `keyfabe clone` to save one.");
|
|
7
11
|
return true;
|
|
8
12
|
}
|
|
13
|
+
const hasEncoding = fobs.some((f) => f.encoding);
|
|
9
14
|
const cols = {
|
|
10
15
|
name: Math.max(12, ...fobs.map((f) => f.name.length + 2)),
|
|
11
16
|
type: Math.max(10, ...fobs.map((f) => f.type.length + 2)),
|
|
12
17
|
id: Math.max(16, ...fobs.map((f) => f.id.length + 2)),
|
|
18
|
+
encoding: hasEncoding ? Math.max(12, ...fobs.map((f) => (f.encoding ?? "").length + 2)) : 0,
|
|
13
19
|
};
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
let header = "Name".padEnd(cols.name) + "Type".padEnd(cols.type) + "ID".padEnd(cols.id);
|
|
21
|
+
if (hasEncoding) {
|
|
22
|
+
header += "Encoding".padEnd(cols.encoding);
|
|
23
|
+
}
|
|
24
|
+
header += "Saved";
|
|
25
|
+
const rows = [];
|
|
19
26
|
for (const fob of fobs) {
|
|
20
27
|
const date = fob.savedAt.slice(0, 10);
|
|
21
|
-
|
|
28
|
+
let row = fob.name.padEnd(cols.name) + fob.type.padEnd(cols.type) + fob.id.padEnd(cols.id);
|
|
29
|
+
if (hasEncoding) {
|
|
30
|
+
row += (fob.encoding ?? "").padEnd(cols.encoding);
|
|
31
|
+
}
|
|
32
|
+
row += date;
|
|
33
|
+
rows.push(row);
|
|
22
34
|
}
|
|
23
|
-
|
|
35
|
+
p.note(`${header}\n${rows.join("\n")}`, `Saved Fobs (${fobs.length})`);
|
|
24
36
|
return true;
|
|
25
37
|
}
|
|
26
38
|
//# sourceMappingURL=list.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,UAA8B,EAAE;IACvD,MAAM,IAAI,GAAG,MAAM,QAAQ,EAAE,CAAC;IAE9B,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpB,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC;QAChF,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAEjD,MAAM,IAAI,GAAG;QACT,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACzD,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACzD,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACrD,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KAC9F,CAAC;IAEF,IAAI,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxF,IAAI,WAAW,EAAE,CAAC;QACd,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;IACD,MAAM,IAAI,OAAO,CAAC;IAElB,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACtC,IAAI,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3F,IAAI,WAAW,EAAE,CAAC;YACd,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtD,CAAC;QACD,GAAG,IAAI,IAAI,CAAC;QACZ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAED,CAAC,CAAC,IAAI,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,eAAe,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IACvE,OAAO,IAAI,CAAC;AAChB,CAAC"}
|
package/dist/commands/read.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { printCardInfo } from "../lib/display.js";
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import { printCardInfo, printDoctorHint } from "../lib/display.js";
|
|
4
3
|
import { parseLfSearch } from "../lib/parsers.js";
|
|
5
4
|
import { Pm3Error, pm3Exec, requireDevice } from "../lib/pm3.js";
|
|
6
5
|
import { promptName } from "../lib/prompts.js";
|
|
@@ -8,23 +7,30 @@ import { saveFob } from "../lib/store.js";
|
|
|
8
7
|
export async function read() {
|
|
9
8
|
if (!(await requireDevice()))
|
|
10
9
|
return false;
|
|
10
|
+
p.intro("Read Card");
|
|
11
11
|
let card = null;
|
|
12
|
-
const
|
|
12
|
+
const s = p.spinner();
|
|
13
|
+
s.start("Searching for card (LF)...");
|
|
13
14
|
try {
|
|
14
15
|
const { stdout } = await pm3Exec("lf search");
|
|
15
16
|
card = parseLfSearch(stdout);
|
|
16
17
|
}
|
|
17
18
|
catch (err) {
|
|
18
19
|
if (err instanceof Pm3Error) {
|
|
19
|
-
|
|
20
|
+
s.stop(err.message);
|
|
21
|
+
p.log.error(err.message);
|
|
22
|
+
if (err.message.includes("not found")) {
|
|
23
|
+
printDoctorHint();
|
|
24
|
+
}
|
|
20
25
|
return false;
|
|
21
26
|
}
|
|
22
27
|
}
|
|
23
28
|
if (!card) {
|
|
24
|
-
|
|
29
|
+
s.stop("No card detected. Make sure the fob is flat against the antenna.");
|
|
30
|
+
p.log.error("No card detected. Make sure the fob is flat against the antenna.");
|
|
25
31
|
return false;
|
|
26
32
|
}
|
|
27
|
-
|
|
33
|
+
s.stop("Card detected");
|
|
28
34
|
printCardInfo(card);
|
|
29
35
|
// Prompt to save
|
|
30
36
|
const name = await promptName();
|
|
@@ -36,7 +42,7 @@ export async function read() {
|
|
|
36
42
|
encoding: card.encoding,
|
|
37
43
|
savedAt: new Date().toISOString(),
|
|
38
44
|
});
|
|
39
|
-
|
|
45
|
+
p.log.success(`Saved as "${name}".`);
|
|
40
46
|
}
|
|
41
47
|
return true;
|
|
42
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/commands/read.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/commands/read.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,IAAI;IACtB,IAAI,CAAC,CAAC,MAAM,aAAa,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAE3C,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAErB,IAAI,IAAI,GAAqC,IAAI,CAAC;IAElD,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IACtB,CAAC,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IACtC,IAAI,CAAC;QACD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;QAC9C,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;YAC1B,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACpB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACzB,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBACpC,eAAe,EAAE,CAAC;YACtB,CAAC;YACD,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,CAAC,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;QAC3E,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;QAChF,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACxB,aAAa,CAAC,IAAI,CAAC,CAAC;IAEpB,iBAAiB;IACjB,MAAM,IAAI,GAAG,MAAM,UAAU,EAAE,CAAC;IAChC,IAAI,IAAI,EAAE,CAAC;QACP,MAAM,OAAO,CAAC;YACV,IAAI;YACJ,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC,CAAC;QACH,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function rename(oldName
|
|
1
|
+
export declare function rename(oldName?: string, newName?: string): Promise<boolean>;
|
package/dist/commands/rename.js
CHANGED
|
@@ -1,17 +1,37 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
2
|
import { printFobNotFound } from "../lib/display.js";
|
|
3
|
-
import {
|
|
3
|
+
import { selectFob } from "../lib/prompts.js";
|
|
4
|
+
import { loadFobs, renameFob } from "../lib/store.js";
|
|
5
|
+
function handleCancel(value) {
|
|
6
|
+
if (p.isCancel(value)) {
|
|
7
|
+
p.cancel("Operation cancelled.");
|
|
8
|
+
process.exit(0);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
4
11
|
export async function rename(oldName, newName) {
|
|
12
|
+
if (!oldName) {
|
|
13
|
+
const fobs = await loadFobs();
|
|
14
|
+
if (fobs.length === 0) {
|
|
15
|
+
p.log.warn("No saved fobs. Use `keyfabe read` or `keyfabe clone` first.");
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
oldName = await selectFob(fobs, "Which fob to rename?");
|
|
19
|
+
}
|
|
20
|
+
if (!newName) {
|
|
21
|
+
const value = await p.text({ message: "New name", placeholder: "e.g. front-door" });
|
|
22
|
+
handleCancel(value);
|
|
23
|
+
newName = value;
|
|
24
|
+
}
|
|
5
25
|
const result = await renameFob(oldName, newName);
|
|
6
26
|
if (result === "not-found") {
|
|
7
27
|
printFobNotFound(oldName);
|
|
8
28
|
return false;
|
|
9
29
|
}
|
|
10
30
|
if (result === "name-taken") {
|
|
11
|
-
|
|
31
|
+
p.log.error(`A fob named "${newName}" already exists. Delete it first or choose a different name.`);
|
|
12
32
|
return false;
|
|
13
33
|
}
|
|
14
|
-
|
|
34
|
+
p.log.success(`Renamed "${oldName}" to "${newName}".`);
|
|
15
35
|
return true;
|
|
16
36
|
}
|
|
17
37
|
//# sourceMappingURL=rename.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rename.js","sourceRoot":"","sources":["../../src/commands/rename.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,
|
|
1
|
+
{"version":3,"file":"rename.js","sourceRoot":"","sources":["../../src/commands/rename.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEtD,SAAS,YAAY,CAAC,KAAc;IAChC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACpB,CAAC,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAgB,EAAE,OAAgB;IAC3D,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,MAAM,IAAI,GAAG,MAAM,QAAQ,EAAE,CAAC;QAC9B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpB,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;YAC1E,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC,CAAC;QACpF,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,OAAO,GAAG,KAAe,CAAC;IAC9B,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,OAAiB,CAAC,CAAC;IAE3D,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;QACzB,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC1B,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;QAC1B,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,gBAAgB,OAAO,+DAA+D,CAAC,CAAC;QACpG,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,OAAO,SAAS,OAAO,IAAI,CAAC,CAAC;IACvD,OAAO,IAAI,CAAC;AAChB,CAAC"}
|