mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 06:05:24 +00:00
fix(hosts): display protocol credential usernames for non-SSH hosts (#1572)
This commit is contained in:
1 parent
bb4b345feb
commit
42c5682243
4 files changed
+88
-4
No files matched your search
@@ -434,12 +434,25 @@ export async function loadProtocolAuthSummaries(
|
||||
const rows =
|
||||
await createCurrentHostProtocolAuthRepository().listRowsForHosts(ids);
|
||||
const keys = new Map<string, Buffer | null>();
|
||||
const usernames = new Map<string, string | null>();
|
||||
for (const row of rows) {
|
||||
if (!keys.has(row.userId)) {
|
||||
keys.set(row.userId, DataCrypto.getUserDataKey(row.userId));
|
||||
}
|
||||
const own = result.get(row.hostId) ?? {};
|
||||
own[row.protocol] = summarize(row, keys.get(row.userId) ?? null);
|
||||
const summary = summarize(row, keys.get(row.userId) ?? null);
|
||||
if (row.authType === "credential" && row.credentialId) {
|
||||
const key = `${row.userId}:${row.credentialId}`;
|
||||
if (!usernames.has(key)) {
|
||||
const credential = await findUsableCredential(
|
||||
row.credentialId,
|
||||
row.userId,
|
||||
);
|
||||
usernames.set(key, credential?.username || null);
|
||||
}
|
||||
summary.username = usernames.get(key) ?? null;
|
||||
}
|
||||
own[row.protocol] = summary;
|
||||
result.set(row.hostId, own);
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -329,6 +329,23 @@ describe("a plugin protocol core does not know", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("summarizes the usable credential username without exposing its secret", async () => {
|
||||
const patch = readProtocolAuthPayload({
|
||||
protocolAuth: { spice: { authType: "credential", credentialId: 6 } },
|
||||
});
|
||||
await writeProtocolAuth("owner", HOST_ID, patch!, { isOwner: true });
|
||||
const summaries = await loadProtocolAuthSummaries([{ id: HOST_ID }]);
|
||||
expect(summaries.get(HOST_ID)?.spice.username).toBe("cred-user");
|
||||
expect(JSON.stringify(summaries.get(HOST_ID))).not.toContain("cred-pass");
|
||||
const recipient = sanitizeHostForRecipient(
|
||||
{ protocolAuth: summaries.get(HOST_ID) },
|
||||
"connect",
|
||||
);
|
||||
expect(recipient.protocolAuth).toEqual({
|
||||
spice: { authType: "credential" },
|
||||
});
|
||||
});
|
||||
|
||||
it("lets a shared editor change the login but not its credential", async () => {
|
||||
await storeLogin();
|
||||
const rename = readProtocolAuthPayload({
|
||||
|
||||
@@ -148,10 +148,19 @@ const DOUBLE_CLICK_WINDOW_MS = 250;
|
||||
const DEFAULT_ROW_FIELDS = defaultHostRowFields();
|
||||
|
||||
export function formatHostAddress(
|
||||
host: Pick<Host, "username" | "ip" | "port">,
|
||||
host: Pick<Host, "username" | "ip" | "port"> &
|
||||
Partial<Pick<Host, "enableSsh" | "pluginSettings" | "protocolAuth">>,
|
||||
fields: Pick<HostRowFields, "showUsername" | "showPort">,
|
||||
): string {
|
||||
const user = fields.showUsername && host.username ? `${host.username}@` : "";
|
||||
const protocol =
|
||||
host.enableSsh === false ? enabledHostProtocols(host)[0] : undefined;
|
||||
const username =
|
||||
host.enableSsh === false
|
||||
? protocol
|
||||
? host.protocolAuth?.[protocol.id]?.username
|
||||
: undefined
|
||||
: host.username;
|
||||
const user = fields.showUsername && username ? `${username}@` : "";
|
||||
const port = fields.showPort && host.port ? `:${host.port}` : "";
|
||||
return `${user}${host.ip}${port}`;
|
||||
}
|
||||
@@ -787,7 +796,12 @@ export function HostItem({
|
||||
<DropdownMenuItem
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
writeClipboardText(`${host.username}@${host.ip}`);
|
||||
writeClipboardText(
|
||||
formatHostAddress(host, {
|
||||
showUsername: true,
|
||||
showPort: false,
|
||||
}),
|
||||
);
|
||||
toast.success(t("hosts.copiedToClipboard"));
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { registerHostProtocol } from "@/sidebar/host-protocols";
|
||||
import {
|
||||
act,
|
||||
cleanup,
|
||||
@@ -402,3 +403,42 @@ describe("HostItem row fields", () => {
|
||||
).toBe("root@10.0.0.5");
|
||||
});
|
||||
});
|
||||
|
||||
it("uses the enabled protocol username for non-SSH hosts", () => {
|
||||
const dispose = registerHostProtocol({
|
||||
id: "rdp",
|
||||
pluginId: "remote-desktop",
|
||||
settingKey: "enableRdp",
|
||||
defaultPort: 3389,
|
||||
titleKey: "rdp",
|
||||
icon: () => null,
|
||||
});
|
||||
try {
|
||||
const host: Host = {
|
||||
...baseHost,
|
||||
enableSsh: false,
|
||||
pluginSettings: { "remote-desktop": { enableRdp: true } },
|
||||
protocolAuth: {
|
||||
rdp: {
|
||||
authType: "credential",
|
||||
credentialId: 6,
|
||||
username: "Administrator",
|
||||
fields: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
const fields = { showUsername: true, showPort: false };
|
||||
expect(formatHostAddress(host, fields)).toBe("Administrator@10.0.0.5");
|
||||
expect(formatHostAddress({ ...host, enableSsh: true }, fields)).toBe(
|
||||
"root@10.0.0.5",
|
||||
);
|
||||
expect(formatHostAddress({ ...host, protocolAuth: {} }, fields)).toBe(
|
||||
"10.0.0.5",
|
||||
);
|
||||
expect(formatHostAddress(host, { ...fields, showUsername: false })).toBe(
|
||||
"10.0.0.5",
|
||||
);
|
||||
} finally {
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user