codiedev 0.7.9 → 0.7.10
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/connect.js +69 -14
- package/dist/secret.d.ts +1 -0
- package/dist/secret.js +14 -0
- package/package.json +1 -1
package/dist/connect.js
CHANGED
|
@@ -42,11 +42,73 @@ const connectFlow_1 = require("./connectFlow");
|
|
|
42
42
|
const version_1 = require("./version");
|
|
43
43
|
const upgradeNudge_1 = require("./upgradeNudge");
|
|
44
44
|
const BACKEND_URL = process.env.CODIEDEV_URL || "https://judicious-falcon-861.convex.site";
|
|
45
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Reads a line from stdin without echoing the typed/pasted characters —
|
|
47
|
+
* for tokens, passwords, anything that shouldn't end up in terminal
|
|
48
|
+
* scrollback or screenshots. Echoes `*` per character so the user gets
|
|
49
|
+
* visual feedback that input is being received.
|
|
50
|
+
*
|
|
51
|
+
* Falls back to the regular `prompt()` if stdin isn't a TTY (e.g., piped
|
|
52
|
+
* input in CI). Without a TTY there's no echo to suppress anyway, and
|
|
53
|
+
* raw mode would error.
|
|
54
|
+
*/
|
|
55
|
+
function promptHidden(question) {
|
|
46
56
|
return new Promise((resolve) => {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
57
|
+
const stdin = process.stdin;
|
|
58
|
+
const stdout = process.stdout;
|
|
59
|
+
if (!stdin.isTTY) {
|
|
60
|
+
// CI / piped input — no terminal to mute. Fall back to readline.
|
|
61
|
+
const rl = readline.createInterface({ input: stdin, output: stdout });
|
|
62
|
+
rl.question(question, (answer) => {
|
|
63
|
+
rl.close();
|
|
64
|
+
resolve(answer.trim());
|
|
65
|
+
});
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
stdout.write(question);
|
|
69
|
+
let buf = "";
|
|
70
|
+
const cleanup = () => {
|
|
71
|
+
stdin.removeListener("data", onData);
|
|
72
|
+
stdin.setRawMode(false);
|
|
73
|
+
stdin.pause();
|
|
74
|
+
};
|
|
75
|
+
const onData = (chunk) => {
|
|
76
|
+
const key = chunk.toString("utf8");
|
|
77
|
+
// Iterate so a single `chunk` containing a multi-char paste still
|
|
78
|
+
// masks each character individually.
|
|
79
|
+
for (const ch of key) {
|
|
80
|
+
// Ctrl+C — abort like a normal terminal interrupt.
|
|
81
|
+
if (ch === "") {
|
|
82
|
+
cleanup();
|
|
83
|
+
stdout.write("\n");
|
|
84
|
+
process.exit(130);
|
|
85
|
+
}
|
|
86
|
+
// Enter — finalize.
|
|
87
|
+
if (ch === "\r" || ch === "\n") {
|
|
88
|
+
cleanup();
|
|
89
|
+
stdout.write("\n");
|
|
90
|
+
resolve(buf.trim());
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
// Backspace / DEL — erase one masked char.
|
|
94
|
+
if (ch === "" || ch === "\b") {
|
|
95
|
+
if (buf.length > 0) {
|
|
96
|
+
buf = buf.slice(0, -1);
|
|
97
|
+
stdout.write("\b \b");
|
|
98
|
+
}
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
// Ignore other control bytes (escape sequences from arrow keys, etc.)
|
|
102
|
+
if (ch.charCodeAt(0) < 0x20)
|
|
103
|
+
continue;
|
|
104
|
+
buf += ch;
|
|
105
|
+
stdout.write("*");
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
stdin.setRawMode(true);
|
|
109
|
+
stdin.resume();
|
|
110
|
+
stdin.setEncoding("utf8");
|
|
111
|
+
stdin.on("data", onData);
|
|
50
112
|
});
|
|
51
113
|
}
|
|
52
114
|
function postJson(url, body) {
|
|
@@ -109,16 +171,9 @@ async function runConnect(args = []) {
|
|
|
109
171
|
console.log(`Reusing API token from ~/.codiedev/config.json (run with --force to use a new one).\n`);
|
|
110
172
|
}
|
|
111
173
|
else {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
});
|
|
116
|
-
try {
|
|
117
|
-
token = await prompt(rl, "Enter your CodieDev API token: ");
|
|
118
|
-
}
|
|
119
|
-
finally {
|
|
120
|
-
rl.close();
|
|
121
|
-
}
|
|
174
|
+
// Hidden prompt — masks the token with `*` as it's typed/pasted so it
|
|
175
|
+
// doesn't end up in terminal scrollback or screenshots.
|
|
176
|
+
token = await promptHidden("Enter your CodieDev API token: ");
|
|
122
177
|
if (!token) {
|
|
123
178
|
console.error("Error: API token is required.");
|
|
124
179
|
process.exit(1);
|
package/dist/secret.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function maskToken(token: string | null | undefined): string;
|
package/dist/secret.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Display helpers for credential-shaped strings. Use anywhere a token /
|
|
3
|
+
// secret might end up in user-visible output (logs, success lines, error
|
|
4
|
+
// messages) so a stray `console.log` can't leak the full value.
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.maskToken = maskToken;
|
|
7
|
+
const PREFIX_LEN = 12;
|
|
8
|
+
function maskToken(token) {
|
|
9
|
+
if (typeof token !== "string" || token.length === 0)
|
|
10
|
+
return "";
|
|
11
|
+
if (token.length <= PREFIX_LEN)
|
|
12
|
+
return token;
|
|
13
|
+
return `${token.slice(0, PREFIX_LEN)}...`;
|
|
14
|
+
}
|
package/package.json
CHANGED