ds-01 1.0.4 → 1.0.5
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/add.d.ts.map +1 -1
- package/dist/commands/add.js +57 -31
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +46 -17
- package/dist/commands/logout.d.ts.map +1 -1
- package/dist/commands/logout.js +27 -7
- package/dist/index.js +2 -0
- package/dist/test-key.d.ts +2 -0
- package/dist/test-key.d.ts.map +1 -0
- package/dist/test-key.js +7 -0
- package/dist/utils/config.d.ts +0 -1
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +0 -13
- package/dist/utils/deviceKey.d.ts +3 -0
- package/dist/utils/deviceKey.d.ts.map +1 -0
- package/dist/utils/deviceKey.js +13 -0
- package/dist/utils/secureKeyStore.d.ts +10 -0
- package/dist/utils/secureKeyStore.d.ts.map +1 -0
- package/dist/utils/secureKeyStore.js +266 -0
- package/package.json +2 -1
- package/src/commands/add.ts +231 -76
- package/src/commands/login.ts +75 -22
- package/src/commands/logout.ts +39 -10
- package/src/index.ts +2 -0
- package/src/native/macos-key-helper.swift +206 -0
- package/src/test-key.ts +20 -0
- package/src/utils/config.ts +1 -12
- package/src/utils/deviceKey.ts +19 -0
- package/src/utils/secureKeyStore.ts +361 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgEpC,eAAO,MAAM,GAAG,SAkRZ,CAAC"}
|
package/dist/commands/add.js
CHANGED
|
@@ -4,24 +4,24 @@ import pc from "picocolors";
|
|
|
4
4
|
import fs from "fs";
|
|
5
5
|
import path from "path";
|
|
6
6
|
import { execSync } from "child_process";
|
|
7
|
-
import { getToken
|
|
7
|
+
import { getToken } from "../utils/config.js";
|
|
8
|
+
import { signWithDeviceKey } from "../utils/secureKeyStore.js";
|
|
9
|
+
import machineIdPkg from "node-machine-id";
|
|
10
|
+
const { machineIdSync } = machineIdPkg;
|
|
8
11
|
const API_BASE_URL = process.env.DS01_API_URL || "https://ds-01.vercel.app";
|
|
9
12
|
// Helper to verify Tailwind exists before doing anything
|
|
10
13
|
function checkTailwindInstallation() {
|
|
11
14
|
const targetDir = process.cwd();
|
|
12
15
|
const pkgJsonPath = path.join(targetDir, "package.json");
|
|
13
|
-
// 1. Ensure they are in a valid Node.js project
|
|
14
16
|
if (!fs.existsSync(pkgJsonPath)) {
|
|
15
17
|
cancel(pc.red("No package.json found. Please run this command inside a Node.js project."));
|
|
16
18
|
process.exit(1);
|
|
17
19
|
}
|
|
18
|
-
// 2. Read package.json dependencies
|
|
19
20
|
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
|
|
20
21
|
const allDeps = {
|
|
21
22
|
...pkgJson.dependencies,
|
|
22
23
|
...pkgJson.devDependencies,
|
|
23
24
|
};
|
|
24
|
-
// 3. Strict Tailwind Check
|
|
25
25
|
if (!allDeps["tailwindcss"]) {
|
|
26
26
|
cancel(pc.red("Tailwind CSS is missing from your project dependencies.\n") +
|
|
27
27
|
pc.gray("DS01 components rely strictly on Tailwind CSS for styling.\n\n") +
|
|
@@ -37,10 +37,8 @@ export const add = new Command()
|
|
|
37
37
|
.description("Add a component from DS01 to your project")
|
|
38
38
|
.argument("<component>", "The name of the component (e.g., premium-section)")
|
|
39
39
|
.action(async (componentName) => {
|
|
40
|
-
console.log();
|
|
41
|
-
// 1. Premium Header
|
|
40
|
+
console.log();
|
|
42
41
|
intro(`${pc.bgWhite(pc.black(pc.bold(" DS01 ")))} ${pc.gray("Adding Component")}`);
|
|
43
|
-
// 2. Run Pre-Flight Tailwind Check
|
|
44
42
|
checkTailwindInstallation();
|
|
45
43
|
const cwd = process.cwd();
|
|
46
44
|
const configPath = path.join(cwd, "ds01.config.json");
|
|
@@ -49,9 +47,8 @@ export const add = new Command()
|
|
|
49
47
|
process.exit(1);
|
|
50
48
|
}
|
|
51
49
|
const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
52
|
-
// Read the GLOBAL credentials, not the local project config
|
|
53
50
|
const token = getToken();
|
|
54
|
-
const machineId =
|
|
51
|
+
const machineId = machineIdSync();
|
|
55
52
|
if (!token || !machineId) {
|
|
56
53
|
cancel(pc.red("You are not authenticated. Run 'npx ds-01 login' first."));
|
|
57
54
|
process.exit(1);
|
|
@@ -59,11 +56,31 @@ export const add = new Command()
|
|
|
59
56
|
const s = spinner();
|
|
60
57
|
s.start(`Fetching ${pc.cyan(`<${componentName} />`)} from registry...`);
|
|
61
58
|
try {
|
|
62
|
-
//
|
|
59
|
+
// --------------------------------------------------
|
|
60
|
+
// 1. Create request-specific message
|
|
61
|
+
// --------------------------------------------------
|
|
62
|
+
const timestamp = Date.now().toString();
|
|
63
|
+
const message = [
|
|
64
|
+
"GET",
|
|
65
|
+
`/api/registry/${componentName}`,
|
|
66
|
+
timestamp,
|
|
67
|
+
machineId,
|
|
68
|
+
].join("\n");
|
|
69
|
+
// --------------------------------------------------
|
|
70
|
+
// 2. Sign message using the device private key
|
|
71
|
+
// --------------------------------------------------
|
|
72
|
+
const signature = await signWithDeviceKey(new TextEncoder().encode(message));
|
|
73
|
+
const signatureBase64 = Buffer.from(signature).toString("base64");
|
|
74
|
+
// --------------------------------------------------
|
|
75
|
+
// 3. Send token + machine ID + signature
|
|
76
|
+
// --------------------------------------------------
|
|
63
77
|
const response = await fetch(`${API_BASE_URL}/api/registry/${componentName}`, {
|
|
78
|
+
method: "GET",
|
|
64
79
|
headers: {
|
|
65
80
|
Authorization: `Bearer ${token}`,
|
|
66
|
-
"X-Machine-ID": machineId,
|
|
81
|
+
"X-Machine-ID": machineId,
|
|
82
|
+
"X-DS01-Timestamp": timestamp,
|
|
83
|
+
"X-DS01-Signature": signatureBase64,
|
|
67
84
|
},
|
|
68
85
|
});
|
|
69
86
|
if (!response.ok) {
|
|
@@ -72,54 +89,63 @@ export const add = new Command()
|
|
|
72
89
|
process.exit(1);
|
|
73
90
|
}
|
|
74
91
|
const componentData = await response.json();
|
|
75
|
-
//
|
|
92
|
+
// --------------------------------------------------
|
|
93
|
+
// 4. Create component folder
|
|
94
|
+
// --------------------------------------------------
|
|
76
95
|
const targetDir = path.join(cwd, config.componentsPath, componentName);
|
|
77
96
|
if (!fs.existsSync(targetDir)) {
|
|
78
|
-
fs.mkdirSync(targetDir, {
|
|
97
|
+
fs.mkdirSync(targetDir, {
|
|
98
|
+
recursive: true,
|
|
99
|
+
});
|
|
79
100
|
}
|
|
80
|
-
//
|
|
81
|
-
//
|
|
101
|
+
// --------------------------------------------------
|
|
102
|
+
// 5. Extract bundled file names
|
|
103
|
+
// --------------------------------------------------
|
|
82
104
|
const bundledFileNames = componentData.files.map((file) => file.name.replace(/\.[^/.]+$/, ""));
|
|
83
|
-
//
|
|
105
|
+
// --------------------------------------------------
|
|
106
|
+
// 6. Write component files
|
|
107
|
+
// --------------------------------------------------
|
|
84
108
|
for (const file of componentData.files) {
|
|
85
|
-
// Because the server sends just the basename (e.g., PremiumHero.tsx),
|
|
86
|
-
// path.join inherently flattens all files into the single targetDir folder.
|
|
87
109
|
const filePath = path.join(targetDir, file.name);
|
|
88
110
|
let content = file.content;
|
|
89
|
-
// 🛠️ DYNAMIC IMPORT REWRITER
|
|
90
111
|
bundledFileNames.forEach((fileName) => {
|
|
91
|
-
// Finds any relative import pointing to a bundled file (e.g., "../Section", "../../Section")
|
|
92
|
-
// and rewrites it strictly to a sibling import (e.g., "./Section")
|
|
93
112
|
const regex = new RegExp(`from\\s+["']\\.[^"']*?\\/${fileName}["']`, "g");
|
|
94
113
|
content = content.replace(regex, `from "./${fileName}"`);
|
|
95
114
|
});
|
|
96
115
|
fs.writeFileSync(filePath, content);
|
|
97
116
|
}
|
|
98
117
|
s.stop(pc.green(`Downloaded ${componentData.files.length} files into ${pc.white(`/${config.componentsPath}/${componentName}`)}`));
|
|
99
|
-
//
|
|
100
|
-
|
|
118
|
+
// --------------------------------------------------
|
|
119
|
+
// 7. Install dependencies
|
|
120
|
+
// --------------------------------------------------
|
|
121
|
+
if (componentData.dependencies &&
|
|
122
|
+
componentData.dependencies.length > 0) {
|
|
101
123
|
const depsToInstall = componentData.dependencies.join(" ");
|
|
102
124
|
s.start(`Installing missing dependencies: ${pc.cyan(depsToInstall)}...`);
|
|
103
125
|
try {
|
|
104
|
-
|
|
105
|
-
|
|
126
|
+
execSync(`npm install ${depsToInstall}`, {
|
|
127
|
+
stdio: "ignore",
|
|
128
|
+
});
|
|
106
129
|
s.stop(pc.green(`Dependencies installed successfully: ${pc.gray(depsToInstall)}`));
|
|
107
130
|
}
|
|
108
|
-
catch
|
|
131
|
+
catch {
|
|
109
132
|
s.stop(pc.red("Failed to auto-install dependencies."));
|
|
110
133
|
note(`Please run: ${pc.cyan(`npm install ${depsToInstall}`)} manually.`, "Manual Action Required");
|
|
111
134
|
}
|
|
112
135
|
}
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
|
|
136
|
+
// --------------------------------------------------
|
|
137
|
+
// 8. Success
|
|
138
|
+
// --------------------------------------------------
|
|
139
|
+
const mainFile = bundledFileNames.find((name) => name.toLowerCase() ===
|
|
140
|
+
componentName.toLowerCase()) || bundledFileNames[0];
|
|
116
141
|
outro(`${pc.white("✔")} ${pc.bold(`Component <${componentName} /> is ready!`)}\n` +
|
|
117
|
-
pc.gray(
|
|
142
|
+
pc.gray("Import it: ") +
|
|
118
143
|
pc.cyan(`import { ${mainFile} } from "@/${config.componentsPath}/${componentName}/${mainFile}"`));
|
|
119
144
|
}
|
|
120
145
|
catch (error) {
|
|
121
146
|
s.stop(pc.red("An error occurred during injection."));
|
|
122
|
-
cancel(pc.gray(error
|
|
147
|
+
cancel(pc.gray(error?.message ||
|
|
148
|
+
"Unknown CLI Error"));
|
|
123
149
|
process.exit(1);
|
|
124
150
|
}
|
|
125
151
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC,eAAO,MAAM,KAAK,SA2Id,CAAC"}
|
package/dist/commands/login.js
CHANGED
|
@@ -4,24 +4,40 @@ import pc from "picocolors";
|
|
|
4
4
|
import open from "open";
|
|
5
5
|
import machineIdPkg from "node-machine-id";
|
|
6
6
|
import { saveToken } from "../utils/config.js";
|
|
7
|
+
import { createDeviceKey, getDevicePublicKey, } from "../utils/secureKeyStore.js";
|
|
7
8
|
const API_BASE_URL = process.env.DS01_API_URL || "https://ds-01.vercel.app";
|
|
8
9
|
const { machineIdSync } = machineIdPkg;
|
|
9
10
|
export const login = new Command()
|
|
10
11
|
.name("login")
|
|
11
12
|
.description("Authenticate your terminal with DS01 via browser")
|
|
12
13
|
.action(async () => {
|
|
13
|
-
console.log();
|
|
14
|
-
// 1. Header banner
|
|
14
|
+
console.log();
|
|
15
15
|
intro(`${pc.bgWhite(pc.black(pc.bold(" DS01 ")))} ${pc.gray("v1.0.0 — Terminal Authentication")}`);
|
|
16
16
|
const s = spinner();
|
|
17
17
|
try {
|
|
18
|
-
//
|
|
19
|
-
|
|
18
|
+
// --------------------------------------------------
|
|
19
|
+
// 1. Create / load the device's secure key
|
|
20
|
+
// --------------------------------------------------
|
|
21
|
+
s.start("Preparing secure device identity...");
|
|
22
|
+
await createDeviceKey();
|
|
23
|
+
// Only the PUBLIC certificate/key leaves the machine.
|
|
24
|
+
const publicKey = await getDevicePublicKey();
|
|
25
|
+
// Existing machine fingerprint.
|
|
20
26
|
const hardwareId = machineIdSync();
|
|
27
|
+
// --------------------------------------------------
|
|
28
|
+
// 2. Start device authorization
|
|
29
|
+
// --------------------------------------------------
|
|
30
|
+
s.start("Requesting pairing code...");
|
|
21
31
|
const initResponse = await fetch(`${API_BASE_URL}/api/auth/device/code`, {
|
|
22
32
|
method: "POST",
|
|
23
|
-
headers: {
|
|
24
|
-
|
|
33
|
+
headers: {
|
|
34
|
+
"Content-Type": "application/json",
|
|
35
|
+
},
|
|
36
|
+
body: JSON.stringify({
|
|
37
|
+
machineId: hardwareId,
|
|
38
|
+
publicKey,
|
|
39
|
+
publicKeyType: process.platform === "win32" ? "windows-rsa" : "macos-ec",
|
|
40
|
+
}),
|
|
25
41
|
});
|
|
26
42
|
if (!initResponse.ok) {
|
|
27
43
|
s.stop(pc.red("Failed to reach DS01 authorization server."));
|
|
@@ -29,18 +45,24 @@ export const login = new Command()
|
|
|
29
45
|
process.exit(1);
|
|
30
46
|
}
|
|
31
47
|
const { deviceCode, userCode, verificationUrl, interval } = await initResponse.json();
|
|
32
|
-
|
|
33
|
-
|
|
48
|
+
if (!deviceCode || !userCode || !verificationUrl) {
|
|
49
|
+
throw new Error("Authorization server returned an invalid device response.");
|
|
50
|
+
}
|
|
51
|
+
s.stop(pc.green("Secure device identity registered."));
|
|
52
|
+
// --------------------------------------------------
|
|
53
|
+
// 3. Ask user to approve in browser
|
|
54
|
+
// --------------------------------------------------
|
|
34
55
|
note(`${pc.bold("Pairing Code:")} ${pc.cyan(pc.bold(` ${userCode} `))}\n` +
|
|
35
56
|
`${pc.bold("Verification URL:")} ${pc.underline(verificationUrl)}`, "Action Required");
|
|
36
|
-
// 4. Auto-launch Browser
|
|
37
57
|
try {
|
|
38
58
|
await open(verificationUrl);
|
|
39
59
|
}
|
|
40
60
|
catch {
|
|
41
|
-
//
|
|
61
|
+
// Browser launch failure is non-fatal.
|
|
42
62
|
}
|
|
43
|
-
//
|
|
63
|
+
// --------------------------------------------------
|
|
64
|
+
// 4. Poll for authorization
|
|
65
|
+
// --------------------------------------------------
|
|
44
66
|
s.start("Waiting for web authorization...");
|
|
45
67
|
let token = null;
|
|
46
68
|
const pollInterval = (interval || 5) * 1000;
|
|
@@ -48,8 +70,13 @@ export const login = new Command()
|
|
|
48
70
|
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
49
71
|
const tokenResponse = await fetch(`${API_BASE_URL}/api/auth/device/token`, {
|
|
50
72
|
method: "POST",
|
|
51
|
-
headers: {
|
|
52
|
-
|
|
73
|
+
headers: {
|
|
74
|
+
"Content-Type": "application/json",
|
|
75
|
+
},
|
|
76
|
+
body: JSON.stringify({
|
|
77
|
+
deviceCode,
|
|
78
|
+
machineId: hardwareId,
|
|
79
|
+
}),
|
|
53
80
|
});
|
|
54
81
|
const tokenData = await tokenResponse.json();
|
|
55
82
|
if (tokenResponse.ok && tokenData.accessToken) {
|
|
@@ -61,15 +88,17 @@ export const login = new Command()
|
|
|
61
88
|
process.exit(1);
|
|
62
89
|
}
|
|
63
90
|
}
|
|
64
|
-
//
|
|
91
|
+
// --------------------------------------------------
|
|
92
|
+
// 5. Save CLI token + machine ID
|
|
93
|
+
// --------------------------------------------------
|
|
65
94
|
saveToken(token, hardwareId);
|
|
66
95
|
s.stop(pc.green("Hardware signature linked & token verified!"));
|
|
67
|
-
|
|
68
|
-
|
|
96
|
+
outro(`${pc.white("✔")} ${pc.bold("Terminal synced successfully")}\n` +
|
|
97
|
+
pc.gray("Secure device key and session token are ready."));
|
|
69
98
|
}
|
|
70
99
|
catch (error) {
|
|
71
100
|
s.stop(pc.red("An error occurred during login."));
|
|
72
|
-
cancel(pc.gray(error
|
|
101
|
+
cancel(pc.gray(error?.message || "Unknown CLI Error"));
|
|
73
102
|
process.exit(1);
|
|
74
103
|
}
|
|
75
104
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,eAAO,MAAM,MAAM,SAiDf,CAAC"}
|
package/dist/commands/logout.js
CHANGED
|
@@ -2,24 +2,44 @@ import { Command } from "commander";
|
|
|
2
2
|
import chalk from "chalk";
|
|
3
3
|
import ora from "ora";
|
|
4
4
|
import { deleteToken, getToken } from "../utils/config.js";
|
|
5
|
+
import machineIdPkg from "node-machine-id";
|
|
6
|
+
const { machineIdSync } = machineIdPkg;
|
|
7
|
+
const API_BASE_URL = process.env.DS01_API_URL || "https://ds-01.vercel.app";
|
|
5
8
|
export const logout = new Command()
|
|
6
9
|
.name("logout")
|
|
7
|
-
.description("Log out of your DS01 account and
|
|
10
|
+
.description("Log out of your DS01 account and revoke the CLI session")
|
|
8
11
|
.action(async () => {
|
|
9
12
|
const token = getToken();
|
|
10
|
-
|
|
13
|
+
const machineId = machineIdSync();
|
|
14
|
+
if (!token || !machineId) {
|
|
11
15
|
console.log(chalk.yellow("You are already logged out."));
|
|
12
16
|
return;
|
|
13
17
|
}
|
|
14
|
-
const spinner = ora("
|
|
18
|
+
const spinner = ora("Revoking CLI session...").start();
|
|
15
19
|
try {
|
|
16
|
-
|
|
20
|
+
const response = await fetch(`${API_BASE_URL}/api/auth/cli/logout`, {
|
|
21
|
+
method: "POST",
|
|
22
|
+
headers: {
|
|
23
|
+
Authorization: `Bearer ${token}`,
|
|
24
|
+
"X-Machine-ID": machineId,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
// NEW: Do not silently delete local credentials if the server
|
|
28
|
+
// failed to revoke the session.
|
|
29
|
+
if (!response.ok) {
|
|
30
|
+
const data = await response.json().catch(() => null);
|
|
31
|
+
throw new Error(data?.error || `Logout failed (HTTP ${response.status})`);
|
|
32
|
+
}
|
|
33
|
+
// NEW: Delete local credentials only after the server confirms
|
|
34
|
+
// that the CLI session has been revoked.
|
|
35
|
+
console.log("✅ Server confirmed CLI session was revoked.");
|
|
17
36
|
deleteToken();
|
|
37
|
+
console.log("✅ Local credentials deleted.");
|
|
18
38
|
spinner.succeed(chalk.green("Successfully logged out."));
|
|
19
|
-
console.log(chalk.gray("Your local credentials have been cleared."));
|
|
39
|
+
console.log(chalk.gray("Your CLI session has been revoked and local credentials have been cleared."));
|
|
20
40
|
}
|
|
21
41
|
catch (error) {
|
|
22
|
-
spinner.fail(chalk.red("Failed to log out
|
|
23
|
-
console.error(error);
|
|
42
|
+
spinner.fail(chalk.red("Failed to log out."));
|
|
43
|
+
console.error(chalk.red(error.message || "Unknown logout error."));
|
|
24
44
|
}
|
|
25
45
|
});
|
package/dist/index.js
CHANGED
|
@@ -17,4 +17,6 @@ program.addCommand(logout);
|
|
|
17
17
|
program.addCommand(init);
|
|
18
18
|
program.addCommand(add); // <-- 2. Register the add command!
|
|
19
19
|
// Parse the arguments from the terminal
|
|
20
|
+
// It is the point where Commander reads the user's terminal input and decides
|
|
21
|
+
// which registered command's .action() function should execute.
|
|
20
22
|
program.parse(process.argv);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-key.d.ts","sourceRoot":"","sources":["../src/test-key.ts"],"names":[],"mappings":""}
|
package/dist/test-key.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createDeviceKey, getDevicePublicKey, signWithDeviceKey, } from "./utils/secureKeyStore.js";
|
|
2
|
+
await createDeviceKey();
|
|
3
|
+
const publicKey = await getDevicePublicKey();
|
|
4
|
+
console.log("Public key:", publicKey);
|
|
5
|
+
const message = new TextEncoder().encode("hello DS01");
|
|
6
|
+
const signature = await signWithDeviceKey(message);
|
|
7
|
+
console.log("Signature:", Buffer.from(signature).toString("base64"));
|
package/dist/utils/config.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAQA,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAczD;AAED,wBAAgB,QAAQ,IAAI,MAAM,GAAG,IAAI,CAWxC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAQA,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAczD;AAED,wBAAgB,QAAQ,IAAI,MAAM,GAAG,IAAI,CAWxC;AAID,wBAAgB,WAAW,SAI1B"}
|
package/dist/utils/config.js
CHANGED
|
@@ -30,19 +30,6 @@ export function getToken() {
|
|
|
30
30
|
}
|
|
31
31
|
return null;
|
|
32
32
|
}
|
|
33
|
-
export function getMachineId() {
|
|
34
|
-
if (fs.existsSync(credentialsPath)) {
|
|
35
|
-
try {
|
|
36
|
-
const data = fs.readFileSync(credentialsPath, "utf-8");
|
|
37
|
-
const parsed = JSON.parse(data);
|
|
38
|
-
return parsed.machineId || null;
|
|
39
|
-
}
|
|
40
|
-
catch {
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
33
|
export function deleteToken() {
|
|
47
34
|
if (fs.existsSync(credentialsPath)) {
|
|
48
35
|
fs.unlinkSync(credentialsPath);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deviceKey.d.ts","sourceRoot":"","sources":["../../src/utils/deviceKey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAIxC,wBAAsB,qBAAqB,qCAc1C"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { webcrypto } from "node:crypto";
|
|
2
|
+
const { subtle } = webcrypto;
|
|
3
|
+
export async function generateDeviceKeyPair() {
|
|
4
|
+
// Generate an asymmetric key pair:
|
|
5
|
+
// - publicKey → can be shared with the server
|
|
6
|
+
// - privateKey → stays on this device
|
|
7
|
+
const keyPair = await subtle.generateKey({
|
|
8
|
+
name: "ECDSA",
|
|
9
|
+
namedCurve: "P-256",
|
|
10
|
+
}, false, // 🔐 Private key is NON-EXPORTABLE
|
|
11
|
+
["sign", "verify"]);
|
|
12
|
+
return keyPair;
|
|
13
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ---------------------------------------------------------
|
|
3
|
+
* PUBLIC API
|
|
4
|
+
* ---------------------------------------------------------
|
|
5
|
+
*/
|
|
6
|
+
export declare function createDeviceKey(): Promise<void>;
|
|
7
|
+
export declare function getDevicePublicKey(): Promise<string>;
|
|
8
|
+
export declare function signWithDeviceKey(data: Uint8Array): Promise<Uint8Array>;
|
|
9
|
+
export declare function deleteDeviceKey(): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=secureKeyStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secureKeyStore.d.ts","sourceRoot":"","sources":["../../src/utils/secureKeyStore.ts"],"names":[],"mappings":"AAwTA;;;;GAIG;AAEH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CASrD;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAQ1D;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,UAAU,CAAC,CAQrB;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CASrD"}
|