[Init] Initial commit - NetMesh terminal manager
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
This commit is contained in:
177
electron/bridges/appLockSystemAuthBridge.test.cjs
Normal file
177
electron/bridges/appLockSystemAuthBridge.test.cjs
Normal file
@@ -0,0 +1,177 @@
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
|
||||
const {
|
||||
createAppLockSystemAuthBridge,
|
||||
normalizeSystemAuthStatus,
|
||||
normalizeSystemAuthUnlockResult,
|
||||
resolveDefaultHelperPath,
|
||||
} = require("./appLockSystemAuthBridge.cjs");
|
||||
|
||||
test("normalizes unsupported status", () => {
|
||||
assert.deepEqual(normalizeSystemAuthStatus(null), {
|
||||
supported: false,
|
||||
available: false,
|
||||
platform: "unsupported",
|
||||
label: null,
|
||||
reason: null,
|
||||
});
|
||||
});
|
||||
|
||||
test("macOS status and unlock use Touch ID systemPreferences", async () => {
|
||||
let promptReason = null;
|
||||
const bridge = createAppLockSystemAuthBridge({
|
||||
platform: "darwin",
|
||||
systemPreferences: {
|
||||
canPromptTouchID: () => true,
|
||||
promptTouchID: async (reason) => {
|
||||
promptReason = reason;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
assert.deepEqual(await bridge.getStatus(), {
|
||||
supported: true,
|
||||
available: true,
|
||||
platform: "darwin",
|
||||
label: "Touch ID",
|
||||
reason: null,
|
||||
});
|
||||
assert.deepEqual(await bridge.requestUnlock(), { ok: true });
|
||||
assert.equal(promptReason, "Unlock Netcatty");
|
||||
});
|
||||
|
||||
test("macOS cancellation maps to cancelled", async () => {
|
||||
const bridge = createAppLockSystemAuthBridge({
|
||||
platform: "darwin",
|
||||
systemPreferences: {
|
||||
canPromptTouchID: () => true,
|
||||
promptTouchID: async () => {
|
||||
throw new Error("User canceled");
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
assert.deepEqual(await bridge.requestUnlock(), { ok: false, error: "cancelled" });
|
||||
});
|
||||
|
||||
test("Windows status and unlock call helper with HWND", async () => {
|
||||
const calls = [];
|
||||
const bridge = createAppLockSystemAuthBridge({
|
||||
platform: "win32",
|
||||
helperPath: "C:\\NetcattyWindowsHello.exe",
|
||||
getNativeWindowHandle: () => Buffer.from("8877665544332211", "hex"),
|
||||
execFile: (file, args, options, callback) => {
|
||||
calls.push({ file, args, options });
|
||||
const command = args[0];
|
||||
const stdout = command === "status"
|
||||
? '{"supported":true,"available":true,"reason":null}'
|
||||
: '{"ok":true}';
|
||||
callback(null, stdout, "");
|
||||
},
|
||||
});
|
||||
|
||||
assert.deepEqual(await bridge.getStatus(), {
|
||||
supported: true,
|
||||
available: true,
|
||||
platform: "win32",
|
||||
label: "Windows Hello",
|
||||
reason: null,
|
||||
});
|
||||
assert.deepEqual(await bridge.requestUnlock(), { ok: true });
|
||||
assert.equal(calls[0].file, "C:\\NetcattyWindowsHello.exe");
|
||||
assert.deepEqual(calls[0].args, ["status"]);
|
||||
assert.equal(calls[0].options.windowsHide, true);
|
||||
assert.equal(calls[0].options.timeout, 15000);
|
||||
assert.deepEqual(calls[1].args, ["verify", "--hwnd", "1234605616436508552", "--message", "Unlock Netcatty"]);
|
||||
assert.equal(calls[1].options.timeout, 120000);
|
||||
});
|
||||
|
||||
test("Windows dev helper path follows the architecture-specific build output", () => {
|
||||
const originalPlatform = Object.getOwnPropertyDescriptor(process, "platform");
|
||||
const originalArch = Object.getOwnPropertyDescriptor(process, "arch");
|
||||
Object.defineProperty(process, "platform", { value: "win32" });
|
||||
Object.defineProperty(process, "arch", { value: "x64" });
|
||||
|
||||
try {
|
||||
const helperPath = resolveDefaultHelperPath({
|
||||
isPackaged: false,
|
||||
resourcesPath: "C:\\fake-electron-resources",
|
||||
});
|
||||
assert.match(helperPath, /windowsHelloHelper[\\/]build[\\/]x64[\\/]NetcattyWindowsHello\.exe$/);
|
||||
} finally {
|
||||
Object.defineProperty(process, "platform", originalPlatform);
|
||||
Object.defineProperty(process, "arch", originalArch);
|
||||
}
|
||||
});
|
||||
|
||||
test("Windows packaged helper path uses the app resources directory", () => {
|
||||
assert.equal(
|
||||
resolveDefaultHelperPath({
|
||||
platform: "win32",
|
||||
isPackaged: true,
|
||||
resourcesPath: "C:\\Netcatty\\resources",
|
||||
arch: "x64",
|
||||
}),
|
||||
"C:\\Netcatty\\resources\\windowsHello\\NetcattyWindowsHello.exe",
|
||||
);
|
||||
});
|
||||
|
||||
test("macOS localized prompt rejection maps to cancelled", async () => {
|
||||
const bridge = createAppLockSystemAuthBridge({
|
||||
platform: "darwin",
|
||||
systemPreferences: {
|
||||
canPromptTouchID: () => true,
|
||||
promptTouchID: async () => {
|
||||
throw new Error("用户已取消认证");
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
assert.deepEqual(await bridge.requestUnlock(), { ok: false, error: "cancelled" });
|
||||
});
|
||||
|
||||
test("Windows helper maps unavailable and cancelled states", async () => {
|
||||
const bridge = createAppLockSystemAuthBridge({
|
||||
platform: "win32",
|
||||
helperPath: "helper.exe",
|
||||
getNativeWindowHandle: () => Buffer.from("0100000000000000", "hex"),
|
||||
execFile: (_file, args, _options, callback) => {
|
||||
const stdout = args[0] === "status"
|
||||
? '{"supported":true,"available":false,"reason":"DisabledByPolicy"}'
|
||||
: '{"ok":false,"error":"RetriesExhausted"}';
|
||||
callback(null, stdout, "");
|
||||
},
|
||||
});
|
||||
|
||||
assert.deepEqual(await bridge.getStatus(), {
|
||||
supported: true,
|
||||
available: false,
|
||||
platform: "win32",
|
||||
label: "Windows Hello",
|
||||
reason: "DisabledByPolicy",
|
||||
});
|
||||
assert.deepEqual(await bridge.requestUnlock(), { ok: false, error: "cancelled" });
|
||||
});
|
||||
|
||||
test("Windows helper failure maps to failed", async () => {
|
||||
const bridge = createAppLockSystemAuthBridge({
|
||||
platform: "win32",
|
||||
helperPath: "helper.exe",
|
||||
getNativeWindowHandle: () => Buffer.from("0100000000000000", "hex"),
|
||||
execFile: (_file, _args, _options, callback) => {
|
||||
callback(new Error("boom"), "", "boom");
|
||||
},
|
||||
});
|
||||
|
||||
assert.deepEqual(await bridge.requestUnlock(), { ok: false, error: "failed" });
|
||||
});
|
||||
|
||||
test("normalizes Windows helper result enums", () => {
|
||||
assert.deepEqual(normalizeSystemAuthUnlockResult({ ok: true }), { ok: true });
|
||||
assert.deepEqual(normalizeSystemAuthUnlockResult({ ok: false, error: "Canceled" }), { ok: false, error: "cancelled" });
|
||||
assert.deepEqual(normalizeSystemAuthUnlockResult({ ok: false, error: "RetriesExhausted" }), { ok: false, error: "cancelled" });
|
||||
assert.deepEqual(normalizeSystemAuthUnlockResult({ ok: false, error: "DeviceBusy" }), { ok: false, error: "unavailable" });
|
||||
assert.deepEqual(normalizeSystemAuthUnlockResult({ ok: false, error: "NotConfiguredForUser" }), { ok: false, error: "unavailable" });
|
||||
assert.deepEqual(normalizeSystemAuthUnlockResult({ ok: false, error: "unexpected" }), { ok: false, error: "failed" });
|
||||
});
|
||||
Reference in New Issue
Block a user