@elding/cli 0.9.2 → 0.9.4
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/deploy.d.ts +1 -0
- package/dist/commands/deploy.js +38 -0
- package/dist/commands/doctor.js +12 -12
- package/dist/commands/init.js +8 -8
- package/dist/commands/keys.js +4 -4
- package/dist/commands/login.js +12 -12
- package/dist/commands/logout.js +3 -3
- package/dist/commands/open.js +2 -2
- package/dist/commands/proxy.js +20 -11
- package/dist/commands/run.js +19 -12
- package/dist/commands/sets.js +2 -2
- package/dist/commands/status.js +6 -6
- package/dist/commands/use.js +4 -4
- package/dist/index.js +28 -18
- package/dist/lib/api.d.ts +4 -0
- package/dist/lib/api.js +20 -8
- package/dist/lib/apiUrl.js +4 -4
- package/dist/lib/config.js +2 -2
- package/dist/lib/proxyServer.js +5 -5
- package/dist/lib/session.js +2 -2
- package/dist/lib/terminal.js +1 -1
- package/dist/lib/trust.js +5 -5
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function deploy(): Promise<void>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deploy = deploy;
|
|
4
|
+
const config_js_1 = require("../lib/config.js");
|
|
5
|
+
const api_js_1 = require("../lib/api.js");
|
|
6
|
+
const terminal_js_1 = require("../lib/terminal.js");
|
|
7
|
+
// `elding deploy` : génère une clé de déploiement (visible dans l'onglet Clés API)
|
|
8
|
+
// et affiche les 2 variables d'environnement à coller en production.
|
|
9
|
+
async function deploy() {
|
|
10
|
+
const { default: chalk } = await import("chalk");
|
|
11
|
+
const { default: ora } = await import("ora");
|
|
12
|
+
const config = (0, config_js_1.readConfig)();
|
|
13
|
+
if (!config) {
|
|
14
|
+
console.error(chalk.red("Not signed in. Run `elding login` first."));
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
const project = (0, config_js_1.readProject)();
|
|
18
|
+
if (!project) {
|
|
19
|
+
console.error(chalk.red("Project not linked. Run `elding init` first."));
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
const spinner = ora("Creating deployment key...").start();
|
|
23
|
+
let result;
|
|
24
|
+
try {
|
|
25
|
+
const accessToken = await (0, api_js_1.exchangeToken)(config.refreshToken);
|
|
26
|
+
result = await (0, api_js_1.createDeployToken)(accessToken);
|
|
27
|
+
spinner.stop();
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
spinner.fail(chalk.red((0, terminal_js_1.safeText)(err.message, 200) || "Creation failed."));
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
console.log(chalk.green(`✓ Key "${(0, terminal_js_1.safeText)(result.label, 80)}" created (visible in the API Keys tab).`));
|
|
34
|
+
console.log(chalk.dim("\nAdd these 2 environment variables to your host (Vercel, etc.):\n"));
|
|
35
|
+
console.log(` ELDING_REFRESH_TOKEN=${result.refreshToken}`);
|
|
36
|
+
console.log(` ELDING_SET_ID=${(0, terminal_js_1.safeText)(project.setId, 64)}`);
|
|
37
|
+
console.log(chalk.yellow("\n⚠ The key is shown only once. Copy it now."));
|
|
38
|
+
}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -13,46 +13,46 @@ async function doctor() {
|
|
|
13
13
|
// 1. Token local
|
|
14
14
|
const config = (0, config_js_1.readConfig)();
|
|
15
15
|
if (!config) {
|
|
16
|
-
fail("
|
|
16
|
+
fail("Not signed in — run `elding login`");
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
|
-
ok("
|
|
19
|
+
ok("Local token present (OS keychain)");
|
|
20
20
|
// 2. Token valide + utilisateur
|
|
21
21
|
let accessToken;
|
|
22
22
|
try {
|
|
23
23
|
accessToken = await (0, api_js_1.exchangeToken)(config.refreshToken);
|
|
24
24
|
const me = await (0, api_js_1.getMe)(accessToken);
|
|
25
|
-
ok(`
|
|
25
|
+
ok(`Authenticated: ${(0, terminal_js_1.safeText)(me.email)}`);
|
|
26
26
|
}
|
|
27
27
|
catch {
|
|
28
|
-
fail("Token
|
|
28
|
+
fail("Token expired or revoked — run `elding login` again");
|
|
29
29
|
return;
|
|
30
30
|
}
|
|
31
31
|
// 3. Set du projet
|
|
32
32
|
const project = (0, config_js_1.readProject)();
|
|
33
33
|
if (!project) {
|
|
34
|
-
warn("
|
|
34
|
+
warn("No set configured — run `elding init` or `elding use <set>`");
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
|
-
ok(`
|
|
37
|
+
ok(`Active set: ${(0, terminal_js_1.safeText)(project.setName)}`);
|
|
38
38
|
// 4. Clés + verrouillage host
|
|
39
39
|
try {
|
|
40
40
|
const keys = await (0, api_js_1.listKeys)(accessToken, project.setId);
|
|
41
41
|
if (keys.length === 0)
|
|
42
|
-
warn("
|
|
42
|
+
warn("The set contains no keys");
|
|
43
43
|
else {
|
|
44
44
|
const locked = keys.filter((k) => k.allowedHost).length;
|
|
45
|
-
ok(`${keys.length}
|
|
45
|
+
ok(`${keys.length} key(s) — ${locked} locked to a domain`);
|
|
46
46
|
if (locked < keys.length)
|
|
47
|
-
warn(`${keys.length - locked}
|
|
47
|
+
warn(`${keys.length - locked} key(s) without a domain: exfiltratable via the proxy`);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
catch {
|
|
51
|
-
fail("
|
|
51
|
+
fail("Could not read the set's keys");
|
|
52
52
|
}
|
|
53
53
|
// 5. Proxy
|
|
54
54
|
if (process.env.ELDING_PROXY_URL)
|
|
55
|
-
ok(`Proxy
|
|
55
|
+
ok(`Proxy active: ${process.env.ELDING_PROXY_URL}`);
|
|
56
56
|
else
|
|
57
|
-
console.log(chalk.dim("○ Proxy
|
|
57
|
+
console.log(chalk.dim("○ Proxy inactive (normal outside `elding proxy`)"));
|
|
58
58
|
}
|
package/dist/commands/init.js
CHANGED
|
@@ -10,16 +10,16 @@ async function init() {
|
|
|
10
10
|
const { default: inquirer } = await import("inquirer");
|
|
11
11
|
const config = (0, config_js_1.readConfig)();
|
|
12
12
|
if (!config) {
|
|
13
|
-
console.error(chalk.red("
|
|
13
|
+
console.error(chalk.red("Not signed in. Run `elding login` first."));
|
|
14
14
|
process.exit(1);
|
|
15
15
|
}
|
|
16
|
-
const spinner = ora("
|
|
16
|
+
const spinner = ora("Fetching sets...").start();
|
|
17
17
|
let accessToken;
|
|
18
18
|
try {
|
|
19
19
|
accessToken = await (0, api_js_1.exchangeToken)(config.refreshToken);
|
|
20
20
|
}
|
|
21
21
|
catch (err) {
|
|
22
|
-
spinner.fail(chalk.red("
|
|
22
|
+
spinner.fail(chalk.red("Could not get an access token. Run `elding login` again."));
|
|
23
23
|
process.exit(1);
|
|
24
24
|
}
|
|
25
25
|
let sets;
|
|
@@ -28,11 +28,11 @@ async function init() {
|
|
|
28
28
|
spinner.stop();
|
|
29
29
|
}
|
|
30
30
|
catch (err) {
|
|
31
|
-
spinner.fail(chalk.red("
|
|
31
|
+
spinner.fail(chalk.red("Could not fetch sets."));
|
|
32
32
|
process.exit(1);
|
|
33
33
|
}
|
|
34
34
|
if (sets.length === 0) {
|
|
35
|
-
console.log(chalk.yellow("
|
|
35
|
+
console.log(chalk.yellow("No sets found. Create one in the vault."));
|
|
36
36
|
process.exit(0);
|
|
37
37
|
}
|
|
38
38
|
// Étape 1 : choisir l'organisation (toujours, pour une approche projet cohérente)
|
|
@@ -41,7 +41,7 @@ async function init() {
|
|
|
41
41
|
{
|
|
42
42
|
type: "select",
|
|
43
43
|
name: "workspaceId",
|
|
44
|
-
message: "
|
|
44
|
+
message: "Which organization?",
|
|
45
45
|
choices: orgs.map(([id, name]) => ({ name: (0, terminal_js_1.safeText)(name), value: id })),
|
|
46
46
|
},
|
|
47
47
|
]);
|
|
@@ -52,7 +52,7 @@ async function init() {
|
|
|
52
52
|
{
|
|
53
53
|
type: "select",
|
|
54
54
|
name: "setId",
|
|
55
|
-
message: "
|
|
55
|
+
message: "Which set should this project use?",
|
|
56
56
|
choices: orgSets.map((s) => {
|
|
57
57
|
const env = s.environment ? ENV_LABELS[s.environment] : undefined;
|
|
58
58
|
return { name: env ? `${(0, terminal_js_1.safeText)(s.name)} (${env})` : (0, terminal_js_1.safeText)(s.name), value: s.id };
|
|
@@ -68,5 +68,5 @@ async function init() {
|
|
|
68
68
|
};
|
|
69
69
|
(0, config_js_1.writeProject)(project);
|
|
70
70
|
(0, config_js_1.trustProject)(project);
|
|
71
|
-
console.log(chalk.green(`✓ Set "${(0, terminal_js_1.safeText)(selected.name)}" (${(0, terminal_js_1.safeText)(selected.workspaceName)})
|
|
71
|
+
console.log(chalk.green(`✓ Set "${(0, terminal_js_1.safeText)(selected.name)}" (${(0, terminal_js_1.safeText)(selected.workspaceName)}) saved in .elding.json`));
|
|
72
72
|
}
|
package/dist/commands/keys.js
CHANGED
|
@@ -10,22 +10,22 @@ async function keys() {
|
|
|
10
10
|
const { default: ora } = await import("ora");
|
|
11
11
|
const project = (0, config_js_1.readProject)();
|
|
12
12
|
if (!project) {
|
|
13
|
-
console.error(chalk.red("
|
|
13
|
+
console.error(chalk.red("Project not initialized. Run `elding init` or `elding use <set>`."));
|
|
14
14
|
process.exit(1);
|
|
15
15
|
}
|
|
16
|
-
const spinner = ora("
|
|
16
|
+
const spinner = ora("Fetching keys...").start();
|
|
17
17
|
const accessToken = await (0, session_js_1.requireAccessToken)();
|
|
18
18
|
const list = await (0, api_js_1.listKeys)(accessToken, project.setId);
|
|
19
19
|
spinner.stop();
|
|
20
20
|
console.log(chalk.dim(`Set : ${(0, terminal_js_1.safeText)(project.setName)}`));
|
|
21
21
|
if (list.length === 0) {
|
|
22
|
-
console.log(chalk.yellow("
|
|
22
|
+
console.log(chalk.yellow("No keys in this set."));
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
25
|
for (const k of list) {
|
|
26
26
|
const host = k.allowedHost
|
|
27
27
|
? chalk.dim(` → ${(0, terminal_js_1.safeText)(k.allowedHost)}`)
|
|
28
|
-
: chalk.yellow(" →
|
|
28
|
+
: chalk.yellow(" → no domain (not locked)");
|
|
29
29
|
console.log(` ${(0, terminal_js_1.safeText)(k.name)}${host}`);
|
|
30
30
|
}
|
|
31
31
|
}
|
package/dist/commands/login.js
CHANGED
|
@@ -15,11 +15,11 @@ async function login() {
|
|
|
15
15
|
const { default: open } = await import("open");
|
|
16
16
|
const { default: ora } = await import("ora");
|
|
17
17
|
const state = crypto_1.default.randomBytes(16).toString("hex");
|
|
18
|
-
const spinner = ora("
|
|
18
|
+
const spinner = ora("Waiting for authorization in the browser...").start();
|
|
19
19
|
const token = await new Promise((resolve, reject) => {
|
|
20
20
|
const timeout = setTimeout(() => {
|
|
21
21
|
server.close();
|
|
22
|
-
reject(new Error("Timeout —
|
|
22
|
+
reject(new Error("Timeout — no response after 5 minutes"));
|
|
23
23
|
}, TIMEOUT_MS);
|
|
24
24
|
const server = http_1.default.createServer(async (req, res) => {
|
|
25
25
|
const addr = server.address();
|
|
@@ -32,7 +32,7 @@ async function login() {
|
|
|
32
32
|
/^[A-Za-z0-9._~-]{16,512}$/.test(receivedCode);
|
|
33
33
|
if (receivedState !== state || !codeValid) {
|
|
34
34
|
res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
|
|
35
|
-
res.end("<p>
|
|
35
|
+
res.end("<p>Invalid parameters. Close this tab.</p>");
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
try {
|
|
@@ -42,7 +42,7 @@ async function login() {
|
|
|
42
42
|
"Referrer-Policy": "no-referrer",
|
|
43
43
|
"Cache-Control": "no-store",
|
|
44
44
|
});
|
|
45
|
-
res.end(`<!DOCTYPE html><html lang="
|
|
45
|
+
res.end(`<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Elding</title><script>history.replaceState(null,"","/")</script><style>
|
|
46
46
|
*{margin:0;padding:0;box-sizing:border-box}
|
|
47
47
|
html,body{height:100%}
|
|
48
48
|
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;background:#fff;color:#000;display:flex;align-items:center;justify-content:center;text-align:center}
|
|
@@ -51,9 +51,9 @@ async function login() {
|
|
|
51
51
|
p{font-size:1rem;color:#6b7280}
|
|
52
52
|
</style></head><body>
|
|
53
53
|
<div class="wrap">
|
|
54
|
-
<h1>
|
|
55
|
-
<p>
|
|
56
|
-
<p>
|
|
54
|
+
<h1>All set, code with peace of mind</h1>
|
|
55
|
+
<p>You are signed in to Elding.</p>
|
|
56
|
+
<p>You can now close this window.</p>
|
|
57
57
|
</div>
|
|
58
58
|
</body></html>`);
|
|
59
59
|
clearTimeout(timeout);
|
|
@@ -62,7 +62,7 @@ async function login() {
|
|
|
62
62
|
}
|
|
63
63
|
catch (err) {
|
|
64
64
|
res.writeHead(502, { "Content-Type": "text/html; charset=utf-8" });
|
|
65
|
-
res.end("<p>
|
|
65
|
+
res.end("<p>Could not finalize authentication. Close this tab and run login again.</p>");
|
|
66
66
|
clearTimeout(timeout);
|
|
67
67
|
server.close();
|
|
68
68
|
reject(new Error((0, terminal_js_1.safeError)(err)));
|
|
@@ -80,12 +80,12 @@ async function login() {
|
|
|
80
80
|
`?state=${encodeURIComponent(state)}` +
|
|
81
81
|
`&callback=${encodeURIComponent(callbackUrl)}`;
|
|
82
82
|
open(authUrl).catch((err) => {
|
|
83
|
-
spinner.warn(
|
|
84
|
-
console.log(chalk.cyan(`
|
|
83
|
+
spinner.warn("Could not open the browser automatically.");
|
|
84
|
+
console.log(chalk.cyan(`Open manually: ${authUrl}`));
|
|
85
85
|
});
|
|
86
86
|
});
|
|
87
87
|
});
|
|
88
88
|
(0, config_js_1.writeConfig)({ refreshToken: token });
|
|
89
|
-
spinner.succeed(chalk.green("
|
|
90
|
-
console.log(chalk.dim("Token
|
|
89
|
+
spinner.succeed(chalk.green("Signed in successfully."));
|
|
90
|
+
console.log(chalk.dim("Token saved in your OS keychain."));
|
|
91
91
|
}
|
package/dist/commands/logout.js
CHANGED
|
@@ -8,12 +8,12 @@ async function logout() {
|
|
|
8
8
|
const { default: ora } = await import("ora");
|
|
9
9
|
const config = (0, config_js_1.readConfig)();
|
|
10
10
|
if (!config) {
|
|
11
|
-
console.log(chalk.dim("
|
|
11
|
+
console.log(chalk.dim("Already signed out."));
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
|
-
const spinner = ora("
|
|
14
|
+
const spinner = ora("Signing out...").start();
|
|
15
15
|
// Révoque côté serveur (best-effort) puis efface le token local
|
|
16
16
|
await (0, api_js_1.revokeToken)(config.refreshToken);
|
|
17
17
|
(0, config_js_1.clearConfig)();
|
|
18
|
-
spinner.succeed(chalk.green("
|
|
18
|
+
spinner.succeed(chalk.green("Signed out. Token revoked and removed locally."));
|
|
19
19
|
}
|
package/dist/commands/open.js
CHANGED
|
@@ -7,7 +7,7 @@ async function open() {
|
|
|
7
7
|
const { default: openUrl } = await import("open");
|
|
8
8
|
const url = `${api_js_1.BASE_URL}/vault`;
|
|
9
9
|
await openUrl(url).catch(() => {
|
|
10
|
-
console.log(chalk.cyan(`
|
|
10
|
+
console.log(chalk.cyan(`Open manually: ${url}`));
|
|
11
11
|
});
|
|
12
|
-
console.log(chalk.dim(`Vault
|
|
12
|
+
console.log(chalk.dim(`Vault opened: ${url}`));
|
|
13
13
|
}
|
package/dist/commands/proxy.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.proxy = proxy;
|
|
4
7
|
const child_process_1 = require("child_process");
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
5
9
|
const config_js_1 = require("../lib/config.js");
|
|
6
10
|
const api_js_1 = require("../lib/api.js");
|
|
7
11
|
const proxyServer_js_1 = require("../lib/proxyServer.js");
|
|
@@ -13,19 +17,19 @@ async function proxy(cmd, args, options = {}) {
|
|
|
13
17
|
const { default: ora } = await import("ora");
|
|
14
18
|
const config = (0, config_js_1.readConfig)();
|
|
15
19
|
if (!config) {
|
|
16
|
-
console.error(chalk.red("
|
|
20
|
+
console.error(chalk.red("Not signed in. Run `elding login` first."));
|
|
17
21
|
process.exit(1);
|
|
18
22
|
}
|
|
19
23
|
const project = (0, config_js_1.readProject)();
|
|
20
24
|
if (!project) {
|
|
21
|
-
console.error(chalk.red("
|
|
25
|
+
console.error(chalk.red("Project not initialized. Run `elding init` first."));
|
|
22
26
|
process.exit(1);
|
|
23
27
|
}
|
|
24
28
|
await (0, trust_js_1.ensureProjectTrusted)(project);
|
|
25
29
|
if (!options.shell && /\s/.test(cmd)) {
|
|
26
|
-
throw new Error("
|
|
30
|
+
throw new Error("Invalid command without --shell. Pass the binary and its arguments separately, or add --shell explicitly.");
|
|
27
31
|
}
|
|
28
|
-
const spinner = ora("
|
|
32
|
+
const spinner = ora("Starting proxy...").start();
|
|
29
33
|
let secrets;
|
|
30
34
|
let hosts;
|
|
31
35
|
try {
|
|
@@ -40,22 +44,27 @@ async function proxy(cmd, args, options = {}) {
|
|
|
40
44
|
? (0, logBatcher_js_1.createLogBatcher)(config.refreshToken, project.setId, project.setName)
|
|
41
45
|
: null;
|
|
42
46
|
const server = await (0, proxyServer_js_1.startProxy)(secrets, hosts, !!options.verbose, batcher ? (e) => batcher.add(e) : undefined);
|
|
43
|
-
spinner.succeed(chalk.green(`Proxy
|
|
44
|
-
console.log(chalk.dim("
|
|
47
|
+
spinner.succeed(chalk.green(`Proxy active on ${server.url} — ${Object.keys(secrets).length} secret(s) for ${(0, terminal_js_1.safeText)(project.setName)}`));
|
|
48
|
+
console.log(chalk.dim("Keys stay in the proxy, never in the app's memory."));
|
|
45
49
|
if (!options.reportLogs)
|
|
46
|
-
console.log(chalk.dim("
|
|
50
|
+
console.log(chalk.dim("Cloud proxy logs disabled (--no-report-logs)."));
|
|
47
51
|
else
|
|
48
|
-
console.log(chalk.dim("
|
|
52
|
+
console.log(chalk.dim("Request metadata sent to the vault (never the values). Disable with --no-report-logs."));
|
|
53
|
+
// Résout les binaires locaux (next, vite...) comme le ferait npm, en
|
|
54
|
+
// cross-platform : path.delimiter = ";" sur Windows, ":" sur POSIX.
|
|
55
|
+
const localBin = path_1.default.join(process.cwd(), "node_modules", ".bin");
|
|
56
|
+
// Sur Windows, les binaires sont des shims `.cmd` : il faut un shell pour les
|
|
57
|
+
// exécuter (sinon `next` échoue en ENOENT). Sur POSIX, on respecte --shell.
|
|
58
|
+
const useShell = process.platform === "win32" ? true : !!options.shell;
|
|
49
59
|
const child = (0, child_process_1.spawn)(cmd, args, {
|
|
50
60
|
env: {
|
|
51
61
|
...process.env,
|
|
52
|
-
|
|
53
|
-
PATH: `${process.cwd()}/node_modules/.bin:${process.env.PATH ?? ""}`,
|
|
62
|
+
PATH: `${localBin}${path_1.default.delimiter}${process.env.PATH ?? ""}`,
|
|
54
63
|
ELDING_PROXY_URL: server.url,
|
|
55
64
|
ELDING_PROXY_TOKEN: server.token,
|
|
56
65
|
},
|
|
57
66
|
stdio: "inherit",
|
|
58
|
-
shell:
|
|
67
|
+
shell: useShell,
|
|
59
68
|
});
|
|
60
69
|
const shutdown = async () => {
|
|
61
70
|
server.close();
|
package/dist/commands/run.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.run = run;
|
|
4
7
|
const child_process_1 = require("child_process");
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
5
9
|
const config_js_1 = require("../lib/config.js");
|
|
6
10
|
const api_js_1 = require("../lib/api.js");
|
|
7
11
|
const env_js_1 = require("../lib/env.js");
|
|
@@ -12,48 +16,51 @@ async function run(cmd, args, options = {}) {
|
|
|
12
16
|
const { default: ora } = await import("ora");
|
|
13
17
|
const config = (0, config_js_1.readConfig)();
|
|
14
18
|
if (!config) {
|
|
15
|
-
console.error(chalk.red("
|
|
19
|
+
console.error(chalk.red("Not signed in. Run `elding login` first."));
|
|
16
20
|
process.exit(1);
|
|
17
21
|
}
|
|
18
22
|
const project = (0, config_js_1.readProject)();
|
|
19
23
|
if (!project) {
|
|
20
|
-
console.error(chalk.red("
|
|
24
|
+
console.error(chalk.red("Project not initialized. Run `elding init` first."));
|
|
21
25
|
process.exit(1);
|
|
22
26
|
}
|
|
23
27
|
await (0, trust_js_1.ensureProjectTrusted)(project);
|
|
24
28
|
if (!options.shell && /\s/.test(cmd)) {
|
|
25
|
-
throw new Error("
|
|
29
|
+
throw new Error("Invalid command without --shell. Pass the binary and its arguments separately, or add --shell explicitly.");
|
|
26
30
|
}
|
|
27
|
-
const spinner = ora("
|
|
31
|
+
const spinner = ora("Fetching secrets...").start();
|
|
28
32
|
let secrets;
|
|
29
33
|
try {
|
|
30
34
|
const accessToken = await (0, api_js_1.exchangeToken)(config.refreshToken);
|
|
31
35
|
({ secrets } = await (0, api_js_1.fetchSecrets)(accessToken, project.setId, "run"));
|
|
32
|
-
spinner.succeed(chalk.green(`${Object.keys(secrets).length} secret(s)
|
|
36
|
+
spinner.succeed(chalk.green(`${Object.keys(secrets).length} secret(s) loaded for ${(0, terminal_js_1.safeText)(project.setName)}.`));
|
|
33
37
|
}
|
|
34
38
|
catch (err) {
|
|
35
39
|
spinner.fail(chalk.red((0, terminal_js_1.safeError)(err)));
|
|
36
40
|
process.exit(1);
|
|
37
41
|
}
|
|
38
|
-
console.error(chalk.yellow("⚠
|
|
39
|
-
console.error(chalk.dim("
|
|
42
|
+
console.error(chalk.yellow("⚠ Run mode: keys are injected in clear text into process.env (readable by your AI and your dependencies)."));
|
|
43
|
+
console.error(chalk.dim(" To keep keys out of your app entirely, prefer `elding proxy`."));
|
|
40
44
|
const { env: safeSecrets, rejected } = (0, env_js_1.filterSecretsForEnv)(secrets);
|
|
41
45
|
if (rejected.length > 0) {
|
|
42
|
-
throw new Error(`Secrets
|
|
46
|
+
throw new Error(`Secrets rejected because their names are unsafe for the environment: ${rejected.map((name) => (0, terminal_js_1.safeText)(name, 80)).join(", ")}`);
|
|
43
47
|
}
|
|
48
|
+
// Résout les binaires locaux (next, vite...) en cross-platform.
|
|
49
|
+
const localBin = path_1.default.join(process.cwd(), "node_modules", ".bin");
|
|
44
50
|
const env = {
|
|
45
51
|
...process.env,
|
|
46
|
-
|
|
47
|
-
PATH: `${process.cwd()}/node_modules/.bin:${process.env.PATH ?? ""}`,
|
|
52
|
+
PATH: `${localBin}${path_1.default.delimiter}${process.env.PATH ?? ""}`,
|
|
48
53
|
...safeSecrets,
|
|
49
54
|
};
|
|
55
|
+
// Sur Windows, les binaires locaux sont des shims `.cmd` : shell requis.
|
|
56
|
+
const useShell = process.platform === "win32" ? true : !!options.shell;
|
|
50
57
|
const result = (0, child_process_1.spawnSync)(cmd, args, {
|
|
51
58
|
env,
|
|
52
59
|
stdio: "inherit",
|
|
53
|
-
shell:
|
|
60
|
+
shell: useShell,
|
|
54
61
|
});
|
|
55
62
|
if (result.error) {
|
|
56
|
-
console.error(chalk.red(`
|
|
63
|
+
console.error(chalk.red(`Could not run the command: ${result.error.message}`));
|
|
57
64
|
process.exit(1);
|
|
58
65
|
}
|
|
59
66
|
process.exit(result.status ?? 0);
|
package/dist/commands/sets.js
CHANGED
|
@@ -8,12 +8,12 @@ const terminal_js_1 = require("../lib/terminal.js");
|
|
|
8
8
|
async function sets() {
|
|
9
9
|
const { default: chalk } = await import("chalk");
|
|
10
10
|
const { default: ora } = await import("ora");
|
|
11
|
-
const spinner = ora("
|
|
11
|
+
const spinner = ora("Fetching sets...").start();
|
|
12
12
|
const accessToken = await (0, session_js_1.requireAccessToken)();
|
|
13
13
|
const list = await (0, api_js_1.listSets)(accessToken);
|
|
14
14
|
spinner.stop();
|
|
15
15
|
if (list.length === 0) {
|
|
16
|
-
console.log(chalk.yellow("
|
|
16
|
+
console.log(chalk.yellow("No sets. Create one in the vault."));
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
19
|
const activeId = (0, config_js_1.readProject)()?.setId;
|
package/dist/commands/status.js
CHANGED
|
@@ -8,7 +8,7 @@ async function status() {
|
|
|
8
8
|
const { default: chalk } = await import("chalk");
|
|
9
9
|
const config = (0, config_js_1.readConfig)();
|
|
10
10
|
if (!config) {
|
|
11
|
-
console.log(chalk.yellow("
|
|
11
|
+
console.log(chalk.yellow("Not signed in.") + chalk.dim(" Run `elding login`."));
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
14
|
// Vérifie la validité du token + récupère l'utilisateur
|
|
@@ -18,13 +18,13 @@ async function status() {
|
|
|
18
18
|
user = await (0, api_js_1.getMe)(accessToken);
|
|
19
19
|
}
|
|
20
20
|
catch {
|
|
21
|
-
console.log(chalk.red("Token
|
|
21
|
+
console.log(chalk.red("Token expired or revoked.") + chalk.dim(" Run `elding login` again."));
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
24
|
const project = (0, config_js_1.readProject)();
|
|
25
25
|
const proxyActive = !!process.env.ELDING_PROXY_URL;
|
|
26
|
-
console.log(chalk.green("●
|
|
27
|
-
console.log(` ${chalk.dim("
|
|
28
|
-
console.log(` ${chalk.dim("
|
|
29
|
-
console.log(` ${chalk.dim("Proxy")} ${proxyActive ? chalk.green("
|
|
26
|
+
console.log(chalk.green("● Signed in"));
|
|
27
|
+
console.log(` ${chalk.dim("User")} ${(0, terminal_js_1.safeText)(user.email)}${user.name ? chalk.dim(` (${(0, terminal_js_1.safeText)(user.name)})`) : ""}`);
|
|
28
|
+
console.log(` ${chalk.dim("Active set")} ${project ? `${(0, terminal_js_1.safeText)(project.setName)} ${chalk.dim(`(${(0, terminal_js_1.safeText)(project.setId)})`)}` : chalk.yellow("none — `elding init`")}`);
|
|
29
|
+
console.log(` ${chalk.dim("Proxy")} ${proxyActive ? chalk.green("active") : chalk.dim("inactive")}`);
|
|
30
30
|
}
|
package/dist/commands/use.js
CHANGED
|
@@ -8,7 +8,7 @@ const terminal_js_1 = require("../lib/terminal.js");
|
|
|
8
8
|
async function use(nameArg) {
|
|
9
9
|
const { default: chalk } = await import("chalk");
|
|
10
10
|
const { default: ora } = await import("ora");
|
|
11
|
-
const spinner = ora("
|
|
11
|
+
const spinner = ora("Fetching sets...").start();
|
|
12
12
|
const accessToken = await (0, session_js_1.requireAccessToken)();
|
|
13
13
|
const list = await (0, api_js_1.listSets)(accessToken);
|
|
14
14
|
spinner.stop();
|
|
@@ -16,11 +16,11 @@ async function use(nameArg) {
|
|
|
16
16
|
const matches = list.filter((s) => s.name.toLowerCase() === query);
|
|
17
17
|
const candidates = matches.length ? matches : list.filter((s) => s.name.toLowerCase().includes(query));
|
|
18
18
|
if (candidates.length === 0) {
|
|
19
|
-
console.error(chalk.red(`
|
|
19
|
+
console.error(chalk.red(`No set named "${(0, terminal_js_1.safeText)(nameArg)}".`) + chalk.dim(" See `elding sets`."));
|
|
20
20
|
process.exit(1);
|
|
21
21
|
}
|
|
22
22
|
if (candidates.length > 1) {
|
|
23
|
-
console.error(chalk.red(`
|
|
23
|
+
console.error(chalk.red(`Several sets match "${(0, terminal_js_1.safeText)(nameArg)}":`));
|
|
24
24
|
candidates.forEach((s) => console.error(chalk.dim(` - ${(0, terminal_js_1.safeText)(s.name)}`)));
|
|
25
25
|
process.exit(1);
|
|
26
26
|
}
|
|
@@ -33,5 +33,5 @@ async function use(nameArg) {
|
|
|
33
33
|
};
|
|
34
34
|
(0, config_js_1.writeProject)(project);
|
|
35
35
|
(0, config_js_1.trustProject)(project);
|
|
36
|
-
console.log(chalk.green(`✓
|
|
36
|
+
console.log(chalk.green(`✓ Active set: "${(0, terminal_js_1.safeText)(set.name)}"`));
|
|
37
37
|
}
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
4
4
|
const commander_1 = require("commander");
|
|
5
5
|
const login_js_1 = require("./commands/login.js");
|
|
6
6
|
const init_js_1 = require("./commands/init.js");
|
|
7
|
+
const deploy_js_1 = require("./commands/deploy.js");
|
|
7
8
|
const run_js_1 = require("./commands/run.js");
|
|
8
9
|
const proxy_js_1 = require("./commands/proxy.js");
|
|
9
10
|
const logout_js_1 = require("./commands/logout.js");
|
|
@@ -17,13 +18,13 @@ const whoami_js_1 = require("./commands/whoami.js");
|
|
|
17
18
|
const program = new commander_1.Command();
|
|
18
19
|
program
|
|
19
20
|
.name("elding")
|
|
20
|
-
.description("Elding CLI — secrets
|
|
21
|
-
.version("0.
|
|
21
|
+
.description("Elding CLI — secrets from the vault, zero .env")
|
|
22
|
+
.version("0.9.3")
|
|
22
23
|
// Permet aux sous-commandes de passer les flags de la commande wrappée (next dev --turbopack...).
|
|
23
24
|
.enablePositionalOptions();
|
|
24
25
|
program
|
|
25
26
|
.command("login")
|
|
26
|
-
.description("
|
|
27
|
+
.description("Authenticate the CLI through the browser")
|
|
27
28
|
.action(async () => {
|
|
28
29
|
await (0, login_js_1.login)().catch((err) => {
|
|
29
30
|
console.error(err.message);
|
|
@@ -32,17 +33,26 @@ program
|
|
|
32
33
|
});
|
|
33
34
|
program
|
|
34
35
|
.command("init")
|
|
35
|
-
.description("
|
|
36
|
+
.description("Link this project to a secret set")
|
|
36
37
|
.action(async () => {
|
|
37
38
|
await (0, init_js_1.init)().catch((err) => {
|
|
38
39
|
console.error(err.message);
|
|
39
40
|
process.exit(1);
|
|
40
41
|
});
|
|
41
42
|
});
|
|
43
|
+
program
|
|
44
|
+
.command("deploy")
|
|
45
|
+
.description("Generate a deployment key and the env variables for production")
|
|
46
|
+
.action(async () => {
|
|
47
|
+
await (0, deploy_js_1.deploy)().catch((err) => {
|
|
48
|
+
console.error(err.message);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
42
52
|
program
|
|
43
53
|
.command("run <cmd> [args...]")
|
|
44
|
-
.description("
|
|
45
|
-
.option("--shell", "
|
|
54
|
+
.description("Run a command with secrets injected as environment variables")
|
|
55
|
+
.option("--shell", "Run through the system shell (use only if necessary)")
|
|
46
56
|
.passThroughOptions()
|
|
47
57
|
.allowUnknownOption()
|
|
48
58
|
.action(async (cmd, args = [], options) => {
|
|
@@ -53,10 +63,10 @@ program
|
|
|
53
63
|
});
|
|
54
64
|
program
|
|
55
65
|
.command("proxy <cmd> [args...]")
|
|
56
|
-
.description("
|
|
57
|
-
.option("-v, --verbose", "
|
|
58
|
-
.option("--no-report-logs", "
|
|
59
|
-
.option("--shell", "
|
|
66
|
+
.description("Run a command behind a local proxy that injects keys — never in the app's memory")
|
|
67
|
+
.option("-v, --verbose", "Log every request (method/host/status/latency)")
|
|
68
|
+
.option("--no-report-logs", "Do not send proxy request metadata to the vault")
|
|
69
|
+
.option("--shell", "Run through the system shell (use only if necessary)")
|
|
60
70
|
.passThroughOptions()
|
|
61
71
|
.allowUnknownOption()
|
|
62
72
|
.action(async (cmd, args = [], options) => {
|
|
@@ -71,7 +81,7 @@ program
|
|
|
71
81
|
});
|
|
72
82
|
program
|
|
73
83
|
.command("logout")
|
|
74
|
-
.description("
|
|
84
|
+
.description("Revoke the token and remove it locally")
|
|
75
85
|
.action(async () => {
|
|
76
86
|
await (0, logout_js_1.logout)().catch((err) => {
|
|
77
87
|
console.error(err.message);
|
|
@@ -80,7 +90,7 @@ program
|
|
|
80
90
|
});
|
|
81
91
|
program
|
|
82
92
|
.command("status")
|
|
83
|
-
.description("
|
|
93
|
+
.description("Show sign-in status, active set and proxy")
|
|
84
94
|
.action(async () => {
|
|
85
95
|
await (0, status_js_1.status)().catch((err) => {
|
|
86
96
|
console.error(err.message);
|
|
@@ -89,7 +99,7 @@ program
|
|
|
89
99
|
});
|
|
90
100
|
program
|
|
91
101
|
.command("sets")
|
|
92
|
-
.description("
|
|
102
|
+
.description("List accessible sets")
|
|
93
103
|
.action(async () => {
|
|
94
104
|
await (0, sets_js_1.sets)().catch((err) => {
|
|
95
105
|
console.error(err.message);
|
|
@@ -98,7 +108,7 @@ program
|
|
|
98
108
|
});
|
|
99
109
|
program
|
|
100
110
|
.command("use <name>")
|
|
101
|
-
.description("
|
|
111
|
+
.description("Switch the project's active set")
|
|
102
112
|
.action(async (name) => {
|
|
103
113
|
await (0, use_js_1.use)(name).catch((err) => {
|
|
104
114
|
console.error(err.message);
|
|
@@ -107,7 +117,7 @@ program
|
|
|
107
117
|
});
|
|
108
118
|
program
|
|
109
119
|
.command("keys")
|
|
110
|
-
.description("
|
|
120
|
+
.description("List the key names of the active set (never the values)")
|
|
111
121
|
.action(async () => {
|
|
112
122
|
await (0, keys_js_1.keys)().catch((err) => {
|
|
113
123
|
console.error(err.message);
|
|
@@ -116,7 +126,7 @@ program
|
|
|
116
126
|
});
|
|
117
127
|
program
|
|
118
128
|
.command("doctor")
|
|
119
|
-
.description("
|
|
129
|
+
.description("Diagnose the configuration (sign-in, set, keys, proxy)")
|
|
120
130
|
.action(async () => {
|
|
121
131
|
await (0, doctor_js_1.doctor)().catch((err) => {
|
|
122
132
|
console.error(err.message);
|
|
@@ -125,7 +135,7 @@ program
|
|
|
125
135
|
});
|
|
126
136
|
program
|
|
127
137
|
.command("open")
|
|
128
|
-
.description("
|
|
138
|
+
.description("Open the vault in the browser")
|
|
129
139
|
.action(async () => {
|
|
130
140
|
await (0, open_js_1.open)().catch((err) => {
|
|
131
141
|
console.error(err.message);
|
|
@@ -134,7 +144,7 @@ program
|
|
|
134
144
|
});
|
|
135
145
|
program
|
|
136
146
|
.command("whoami")
|
|
137
|
-
.description("
|
|
147
|
+
.description("Show the signed-in user")
|
|
138
148
|
.action(async () => {
|
|
139
149
|
await (0, whoami_js_1.whoami)().catch((err) => {
|
|
140
150
|
console.error(err.message);
|
package/dist/lib/api.d.ts
CHANGED
|
@@ -12,6 +12,10 @@ export type KeyItem = {
|
|
|
12
12
|
};
|
|
13
13
|
export declare function listKeys(accessToken: string, setId: string): Promise<KeyItem[]>;
|
|
14
14
|
export declare function exchangeToken(refreshToken: string): Promise<string>;
|
|
15
|
+
export declare function createDeployToken(accessToken: string, label?: string): Promise<{
|
|
16
|
+
refreshToken: string;
|
|
17
|
+
label: string;
|
|
18
|
+
}>;
|
|
15
19
|
export declare function exchangeLoginCode(code: string, state: string, callbackUrl: string): Promise<string>;
|
|
16
20
|
export declare function reportProxyLogs(accessToken: string, setId: string, setName: string, entries: unknown[]): Promise<void>;
|
|
17
21
|
export declare function revokeToken(refreshToken: string): Promise<void>;
|
package/dist/lib/api.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.BASE_URL = void 0;
|
|
4
4
|
exports.listKeys = listKeys;
|
|
5
5
|
exports.exchangeToken = exchangeToken;
|
|
6
|
+
exports.createDeployToken = createDeployToken;
|
|
6
7
|
exports.exchangeLoginCode = exchangeLoginCode;
|
|
7
8
|
exports.reportProxyLogs = reportProxyLogs;
|
|
8
9
|
exports.revokeToken = revokeToken;
|
|
@@ -24,26 +25,37 @@ async function listKeys(accessToken, setId) {
|
|
|
24
25
|
}
|
|
25
26
|
async function exchangeToken(refreshToken) {
|
|
26
27
|
if (!REFRESH_TOKEN.test(refreshToken))
|
|
27
|
-
throw new Error("
|
|
28
|
+
throw new Error("Invalid local token. Run `elding login` again.");
|
|
28
29
|
const body = await requestJson("/api/cli/auth/token", {
|
|
29
30
|
method: "POST",
|
|
30
31
|
headers: { "Content-Type": "application/json" },
|
|
31
32
|
body: JSON.stringify({ refreshToken }),
|
|
32
33
|
});
|
|
33
34
|
if (!body.success || !body.accessToken)
|
|
34
|
-
throw new Error((0, terminal_js_1.safeText)(body.error, 200) || "
|
|
35
|
+
throw new Error((0, terminal_js_1.safeText)(body.error, 200) || "Could not get an access token");
|
|
35
36
|
return body.accessToken;
|
|
36
37
|
}
|
|
38
|
+
// Crée une clé API de service (déploiement). Apparaît dans l'onglet Clés API.
|
|
39
|
+
async function createDeployToken(accessToken, label) {
|
|
40
|
+
const body = await requestJson("/api/cli/deploy-token", {
|
|
41
|
+
method: "POST",
|
|
42
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${accessToken}` },
|
|
43
|
+
body: JSON.stringify({ label }),
|
|
44
|
+
});
|
|
45
|
+
if (!body.success || !body.refreshToken)
|
|
46
|
+
throw new Error((0, terminal_js_1.safeText)(body.error, 200) || "Could not create the deployment key");
|
|
47
|
+
return { refreshToken: body.refreshToken, label: body.label ?? "Deployment" };
|
|
48
|
+
}
|
|
37
49
|
async function exchangeLoginCode(code, state, callbackUrl) {
|
|
38
50
|
if (!LOGIN_CODE.test(code))
|
|
39
|
-
throw new Error("
|
|
51
|
+
throw new Error("Invalid authorization code.");
|
|
40
52
|
const body = await requestJson("/api/cli/auth/exchange", {
|
|
41
53
|
method: "POST",
|
|
42
54
|
headers: { "Content-Type": "application/json" },
|
|
43
55
|
body: JSON.stringify({ code, state, callbackUrl }),
|
|
44
56
|
});
|
|
45
57
|
if (!body.success || !body.refreshToken || !REFRESH_TOKEN.test(body.refreshToken)) {
|
|
46
|
-
throw new Error((0, terminal_js_1.safeText)(body.error, 200) || "
|
|
58
|
+
throw new Error((0, terminal_js_1.safeText)(body.error, 200) || "Could not finalize authentication.");
|
|
47
59
|
}
|
|
48
60
|
return body.refreshToken;
|
|
49
61
|
}
|
|
@@ -70,7 +82,7 @@ async function getMe(accessToken) {
|
|
|
70
82
|
headers: { Authorization: `Bearer ${accessToken}` },
|
|
71
83
|
});
|
|
72
84
|
if (!body.success || !body.user)
|
|
73
|
-
throw new Error("
|
|
85
|
+
throw new Error("Invalid response");
|
|
74
86
|
return body.user;
|
|
75
87
|
}
|
|
76
88
|
async function listSets(accessToken) {
|
|
@@ -84,7 +96,7 @@ async function fetchSecrets(accessToken, setId, mode = "proxy") {
|
|
|
84
96
|
headers: { Authorization: `Bearer ${accessToken}` },
|
|
85
97
|
});
|
|
86
98
|
if (!body.success || !body.secrets || typeof body.secrets !== "object")
|
|
87
|
-
throw new Error("
|
|
99
|
+
throw new Error("Invalid response");
|
|
88
100
|
return {
|
|
89
101
|
secrets: sanitizeSecrets(body.secrets),
|
|
90
102
|
hosts: body.hosts && typeof body.hosts === "object" ? sanitizeSecrets(body.hosts) : {},
|
|
@@ -112,9 +124,9 @@ async function requestJson(path, init) {
|
|
|
112
124
|
});
|
|
113
125
|
const body = (await res.json().catch(() => null));
|
|
114
126
|
if (!res.ok) {
|
|
115
|
-
throw new Error((0, terminal_js_1.safeText)(body?.error, 200) || `
|
|
127
|
+
throw new Error((0, terminal_js_1.safeText)(body?.error, 200) || `Error ${res.status}`);
|
|
116
128
|
}
|
|
117
129
|
if (!body || typeof body !== "object")
|
|
118
|
-
throw new Error("
|
|
130
|
+
throw new Error("Invalid response");
|
|
119
131
|
return body;
|
|
120
132
|
}
|
package/dist/lib/apiUrl.js
CHANGED
|
@@ -28,17 +28,17 @@ function resolveBaseUrl(raw = process.env.ELDING_API_URL) {
|
|
|
28
28
|
url = new URL(input);
|
|
29
29
|
}
|
|
30
30
|
catch {
|
|
31
|
-
throw new Error("ELDING_API_URL
|
|
31
|
+
throw new Error("Invalid ELDING_API_URL.");
|
|
32
32
|
}
|
|
33
33
|
if (url.username || url.password) {
|
|
34
|
-
throw new Error("ELDING_API_URL
|
|
34
|
+
throw new Error("ELDING_API_URL must not contain credentials.");
|
|
35
35
|
}
|
|
36
36
|
if (url.pathname !== "/" || url.search || url.hash) {
|
|
37
|
-
throw new Error("ELDING_API_URL
|
|
37
|
+
throw new Error("ELDING_API_URL must be an origin only, for example https://elding.app.");
|
|
38
38
|
}
|
|
39
39
|
if (url.protocol === "https:")
|
|
40
40
|
return url.origin;
|
|
41
41
|
if (url.protocol === "http:" && isLoopbackHost(url.hostname))
|
|
42
42
|
return url.origin;
|
|
43
|
-
throw new Error("ELDING_API_URL
|
|
43
|
+
throw new Error("ELDING_API_URL must use HTTPS, except for localhost during development.");
|
|
44
44
|
}
|
package/dist/lib/config.js
CHANGED
|
@@ -62,7 +62,7 @@ function ensureConfigDir() {
|
|
|
62
62
|
try {
|
|
63
63
|
const stat = fs_1.default.lstatSync(CONFIG_DIR);
|
|
64
64
|
if (stat.isSymbolicLink() || !stat.isDirectory()) {
|
|
65
|
-
throw new Error(`${CONFIG_DIR}
|
|
65
|
+
throw new Error(`${CONFIG_DIR} must be a non-symbolic directory.`);
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
catch (err) {
|
|
@@ -123,7 +123,7 @@ function isProjectTrusted(project, cwd = process.cwd()) {
|
|
|
123
123
|
function trustProject(project, cwd = process.cwd()) {
|
|
124
124
|
const config = readConfig();
|
|
125
125
|
if (!config)
|
|
126
|
-
throw new Error("
|
|
126
|
+
throw new Error("Not signed in. Run `elding login` first.");
|
|
127
127
|
writeConfig({
|
|
128
128
|
...config,
|
|
129
129
|
trustedProjects: {
|
package/dist/lib/proxyServer.js
CHANGED
|
@@ -144,13 +144,13 @@ function startProxy(secrets, hosts = {}, verbose = false, onLog) {
|
|
|
144
144
|
for (const m of val.matchAll(PLACEHOLDER)) {
|
|
145
145
|
const name = m[1];
|
|
146
146
|
if (!Object.prototype.hasOwnProperty.call(secrets, name))
|
|
147
|
-
return `${name}
|
|
147
|
+
return `${name} is unknown`;
|
|
148
148
|
const allowed = hosts[name];
|
|
149
149
|
if (!allowed)
|
|
150
|
-
return `${name}
|
|
150
|
+
return `${name} has no allowed domain`;
|
|
151
151
|
const allowedHost = normalizeAllowedHost(allowed);
|
|
152
152
|
if (!allowedHost || allowedHost !== targetHost)
|
|
153
|
-
return `${name}
|
|
153
|
+
return `${name} is not allowed`;
|
|
154
154
|
}
|
|
155
155
|
return null;
|
|
156
156
|
};
|
|
@@ -193,7 +193,7 @@ function startProxy(secrets, hosts = {}, verbose = false, onLog) {
|
|
|
193
193
|
const targetHost = normalizeHostname(targetUrl.hostname);
|
|
194
194
|
const resolved = await resolvePublicAddresses(targetHost);
|
|
195
195
|
if (resolved.length === 0) {
|
|
196
|
-
log(req.method ?? "?", targetHost, req.url ?? "/", "BLOCKED", Date.now() - started, "host
|
|
196
|
+
log(req.method ?? "?", targetHost, req.url ?? "/", "BLOCKED", Date.now() - started, "blocked host");
|
|
197
197
|
res.writeHead(403);
|
|
198
198
|
res.end("blocked host");
|
|
199
199
|
return;
|
|
@@ -211,7 +211,7 @@ function startProxy(secrets, hosts = {}, verbose = false, onLog) {
|
|
|
211
211
|
continue;
|
|
212
212
|
log(req.method ?? "?", targetHost, upstream.pathname, "BLOCKED", Date.now() - started, bad);
|
|
213
213
|
res.writeHead(403);
|
|
214
|
-
res.end(`secret
|
|
214
|
+
res.end(`blocked secret: ${bad}`);
|
|
215
215
|
return;
|
|
216
216
|
}
|
|
217
217
|
}
|
package/dist/lib/session.js
CHANGED
|
@@ -7,11 +7,11 @@ const api_js_1 = require("./api.js");
|
|
|
7
7
|
async function requireAccessToken() {
|
|
8
8
|
const config = (0, config_js_1.readConfig)();
|
|
9
9
|
if (!config)
|
|
10
|
-
throw new Error("
|
|
10
|
+
throw new Error("Not signed in. Run `elding login` first.");
|
|
11
11
|
try {
|
|
12
12
|
return await (0, api_js_1.exchangeToken)(config.refreshToken);
|
|
13
13
|
}
|
|
14
14
|
catch {
|
|
15
|
-
throw new Error("Token
|
|
15
|
+
throw new Error("Token expired or revoked. Run `elding login` again.");
|
|
16
16
|
}
|
|
17
17
|
}
|
package/dist/lib/terminal.js
CHANGED
|
@@ -11,5 +11,5 @@ function safeText(value, maxLength = 500) {
|
|
|
11
11
|
.slice(0, maxLength);
|
|
12
12
|
}
|
|
13
13
|
function safeError(value) {
|
|
14
|
-
return safeText(value instanceof Error ? value.message : value, 300) || "
|
|
14
|
+
return safeText(value instanceof Error ? value.message : value, 300) || "Unknown error";
|
|
15
15
|
}
|
package/dist/lib/trust.js
CHANGED
|
@@ -15,15 +15,15 @@ async function ensureProjectTrusted(project) {
|
|
|
15
15
|
const target = `${(0, terminal_js_1.safeText)(project.setName)} (${(0, terminal_js_1.safeText)(project.setId)})`;
|
|
16
16
|
const workspace = project.workspaceName ? ` / ${(0, terminal_js_1.safeText)(project.workspaceName)}` : "";
|
|
17
17
|
if (!process_1.stdin.isTTY || !process_1.stdout.isTTY) {
|
|
18
|
-
throw new Error(`
|
|
18
|
+
throw new Error(`Project not approved for set ${target}${workspace}. Run \`elding init\` or \`elding use <set>\` interactively.`);
|
|
19
19
|
}
|
|
20
20
|
const rl = promises_1.default.createInterface({ input: process_1.stdin, output: process_1.stdout });
|
|
21
21
|
try {
|
|
22
|
-
console.log(`
|
|
23
|
-
console.log(`
|
|
24
|
-
const answer = await rl.question("
|
|
22
|
+
console.log(`Project: ${(0, terminal_js_1.safeText)(location)}`);
|
|
23
|
+
console.log(`Elding set: ${target}${workspace}`);
|
|
24
|
+
const answer = await rl.question("Approve this project for this set? [y/N] ");
|
|
25
25
|
if (!/^y(es)?$/i.test(answer.trim())) {
|
|
26
|
-
throw new Error("
|
|
26
|
+
throw new Error("Project not approved.");
|
|
27
27
|
}
|
|
28
28
|
(0, config_js_1.trustProject)(project);
|
|
29
29
|
}
|