mirror of
https://github.com/binaricat/Netcatty.git
synced 2026-10-30 02:21:47 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8cbcb73b61 | ||
|
|
d3eb3007bb |
No files matched your search
@@ -1,29 +0,0 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { DEFAULT_KEY_BINDINGS, keyStringToKeyboardEvent } from './models/keyBindings.ts';
|
||||
import { checkAppShortcut } from '../application/state/useGlobalHotkeys.ts';
|
||||
|
||||
function shortcut(key: string, isMac = false, bindings = DEFAULT_KEY_BINDINGS) {
|
||||
const event = keyStringToKeyboardEvent(key);
|
||||
assert.ok(event);
|
||||
return checkAppShortcut(event, bindings, isMac)?.action ?? null;
|
||||
}
|
||||
|
||||
test('default shortcuts leave Ctrl+L available to the terminal on both schemes', () => {
|
||||
assert.equal(shortcut('Ctrl + L'), null);
|
||||
assert.equal(shortcut('Ctrl + L', true), null);
|
||||
});
|
||||
|
||||
test('local terminal remains available through New Local Tab and the macOS shortcut', () => {
|
||||
assert.equal(shortcut('Ctrl + T'), 'newTab');
|
||||
assert.equal(shortcut('⌘ + T', true), 'newTab');
|
||||
assert.equal(shortcut('⌘ + L', true), 'openLocal');
|
||||
});
|
||||
|
||||
test('an explicitly configured Ctrl+L still opens a local terminal', () => {
|
||||
const customBindings = DEFAULT_KEY_BINDINGS.map(binding => binding.id === 'open-local'
|
||||
? { ...binding, pc: 'Ctrl + L' }
|
||||
: binding);
|
||||
assert.equal(shortcut('Ctrl + L', false, customBindings), 'openLocal');
|
||||
});
|
||||
@@ -264,7 +264,7 @@ export const DEFAULT_KEY_BINDINGS: KeyBinding[] = [
|
||||
|
||||
// App Features
|
||||
{ id: 'open-hosts', action: 'openHosts', label: 'Open Hosts Page', mac: 'Disabled', pc: 'Disabled', category: 'app' },
|
||||
{ id: 'open-local', action: 'openLocal', label: 'Open Local Terminal', mac: '⌘ + L', pc: 'Disabled', category: 'app' },
|
||||
{ id: 'open-local', action: 'openLocal', label: 'Open Local Terminal', mac: '⌘ + L', pc: 'Ctrl + L', category: 'app' },
|
||||
{ id: 'open-sftp', action: 'openSftp', label: 'Open SFTP', mac: '⌘ + Shift + O', pc: 'Ctrl + Shift + O', category: 'app' },
|
||||
{ id: 'port-forwarding', action: 'portForwarding', label: 'Open Port Forwarding', mac: '⌘ + P', pc: 'Ctrl + P', category: 'app' },
|
||||
{ id: 'command-palette', action: 'commandPalette', label: 'Open Command Palette', mac: '⌘ + K', pc: 'Ctrl + K', category: 'app' },
|
||||
|
||||
@@ -635,7 +635,13 @@ function createSessionOpsApi(ctx) {
|
||||
_rc_cwd=$(readlink "/proc/$1/cwd" 2>/dev/null)
|
||||
if [ -n "$_rc_cwd" ]; then printf '%s\\n' "$_rc_cwd"; return 0; fi
|
||||
if command -v lsof >/dev/null 2>&1; then
|
||||
_rc_cwd=$(LC_ALL=C lsof -a -p "$1" -d cwd -Fn 2>/dev/null | sed -n 's/^n//p' | head -n1)
|
||||
# An unknown-type record can put a readlink error in its name field.
|
||||
# Only a confirmed directory name is usable as an upload destination.
|
||||
_rc_cwd=$(LC_ALL=C lsof -a -p "$1" -d cwd -Fnt 2>/dev/null | awk '
|
||||
/^f/ { is_dir=0 }
|
||||
/^t/ { is_dir=($0 == "tDIR" || $0 == "tVDIR") }
|
||||
/^n/ && is_dir { print substr($0, 2); exit }
|
||||
')
|
||||
if [ -n "$_rc_cwd" ]; then printf 'NETCATTY_LSOF_CWD=%s\\n' "$_rc_cwd"; return 0; fi
|
||||
fi
|
||||
return 1
|
||||
|
||||
@@ -29,7 +29,7 @@ function makeApi(session, siblingSessions = [], overrides = {}) {
|
||||
sessions,
|
||||
setTimeout: overrides.setTimeout || setTimeout,
|
||||
clearTimeout: overrides.clearTimeout || clearTimeout,
|
||||
quoteShellArg,
|
||||
quoteShellArg: overrides.quoteShellArg || quoteShellArg,
|
||||
log: () => {},
|
||||
});
|
||||
}
|
||||
@@ -123,6 +123,47 @@ test("session cwd probe decodes the marked lsof pathname", async () => {
|
||||
assert.deepEqual(result, { success: true, cwd: "/srv/中文" });
|
||||
});
|
||||
|
||||
test("lsof cwd fallback accepts only directory records, not diagnostic names (#3237)", async () => {
|
||||
let script;
|
||||
const api = makeApi({
|
||||
shellPid: "4242",
|
||||
connRef: { count: 1 },
|
||||
stream: {},
|
||||
conn: {
|
||||
exec(_command, callback) {
|
||||
callback(null, makePwdStream("/srv/app", "4242"));
|
||||
},
|
||||
},
|
||||
}, [], {
|
||||
quoteShellArg(value) {
|
||||
if (!script && value.includes("read_shell_cwd()")) script = value;
|
||||
return quoteShellArg(value);
|
||||
},
|
||||
});
|
||||
await api.getSessionPwd(null, { sessionId: "session-1" });
|
||||
const helper = script.match(/ read_shell_cwd\(\) \{[\s\S]*?\n \}/)?.[0];
|
||||
assert.ok(helper, "exercise the actual remote cwd helper");
|
||||
const { spawnSync } = require("node:child_process");
|
||||
for (const [output, expected] of [
|
||||
["p4242\nfcwd\ntunknown\nn/proc/4242/cwd (readlink: Permission denied)\n", null],
|
||||
["p4242\nfcwd\ntunknown\nn/proc/4242/cwd (readlink: No such file or directory)\n", null],
|
||||
["p4242\nfcwd\nn/proc/4242/cwd\n", null],
|
||||
["p4242\nfcwd\ntDIR\nn/srv/app\n", "/srv/app"],
|
||||
["p4242\nfcwd\ntVDIR\nn/usr/home/alice\n", "/usr/home/alice"],
|
||||
["p4242\nfcwd\ntDIR\nn/tmp/literal (readlink: Permission denied)\n", "/tmp/literal (readlink: Permission denied)"],
|
||||
["p4242\nfcwd\ntDIR\nn/tmp/\\xe4\\xb8\\xad\\xe6\\x96\\x87\n", "/tmp/\\xe4\\xb8\\xad\\xe6\\x96\\x87"],
|
||||
]) {
|
||||
const result = spawnSync("sh", ["-c", `
|
||||
readlink() { return 1; }
|
||||
lsof() { printf '%s' "$LSOF_TEST_OUTPUT"; }
|
||||
${helper}
|
||||
read_shell_cwd 4242
|
||||
`], { encoding: "utf8", env: { ...process.env, LSOF_TEST_OUTPUT: output } });
|
||||
assert.equal(result.status, expected === null ? 1 : 0, output);
|
||||
assert.equal(result.stdout, expected === null ? "" : `NETCATTY_LSOF_CWD=${expected}\n`, output);
|
||||
}
|
||||
});
|
||||
|
||||
test("session cwd probe closes a remote command that exceeds its timeout", async () => {
|
||||
const stream = new EventEmitter();
|
||||
stream.stderr = new EventEmitter();
|
||||
|
||||
Reference in new issue
Block a user