mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-28 06:05:24 +00:00
fix(ssh): accept full passwords in keyboard-interactive prompts (#1569)
This commit is contained in:
1 parent
f412a28bb8
commit
f4164a74b2
2 files changed
+74
-8
No files matched your search
@@ -44,6 +44,7 @@ export function TOTPDialog({
|
||||
|
||||
if (!isOpen) return null;
|
||||
|
||||
const isPassword = mode === "password";
|
||||
const isPush = mode === "push";
|
||||
const isMenu = mode === "menu";
|
||||
const isTotp = !isPush && !isMenu && mode !== "password";
|
||||
@@ -62,16 +63,17 @@ export function TOTPDialog({
|
||||
const input = e.currentTarget.elements.namedItem(
|
||||
"totpCode",
|
||||
) as HTMLInputElement;
|
||||
if (input?.value.trim()) {
|
||||
onSubmit(input.value.trim());
|
||||
}
|
||||
const value = isPassword ? input?.value : input?.value.trim();
|
||||
if (value) onSubmit(value);
|
||||
};
|
||||
|
||||
const title = isPush
|
||||
? t("sshAuth.mfaPushRequired")
|
||||
: isMenu
|
||||
? t("sshAuth.mfaPromptRequired")
|
||||
: t("sshAuth.totpRequired");
|
||||
: isPassword
|
||||
? t("common.password")
|
||||
: isMenu
|
||||
? t("sshAuth.mfaPromptRequired")
|
||||
: t("sshAuth.totpRequired");
|
||||
|
||||
const label = prompt || (isTotp ? t("sshAuth.totpCodeLabel") : undefined);
|
||||
|
||||
@@ -102,7 +104,17 @@ export function TOTPDialog({
|
||||
</div>
|
||||
) : (
|
||||
<form onSubmit={handleSubmit} className="flex flex-col gap-3">
|
||||
{isPush ? null : isMenu ? (
|
||||
{isPush ? null : isPassword ? (
|
||||
<Input
|
||||
id="totpCode"
|
||||
name="totpCode"
|
||||
type="password"
|
||||
autoComplete="current-password"
|
||||
autoFocus
|
||||
placeholder={t("placeholders.enterPassword")}
|
||||
className="rounded-none bg-muted/50 border-border text-sm"
|
||||
/>
|
||||
) : isMenu ? (
|
||||
<Input
|
||||
id="totpCode"
|
||||
name="totpCode"
|
||||
@@ -137,7 +149,11 @@ export function TOTPDialog({
|
||||
<div className="flex justify-end gap-2">
|
||||
{cancel}
|
||||
<button type="submit" className={PROMPT_PRIMARY_BUTTON}>
|
||||
{isPush ? t("sshAuth.mfaSendRequest") : t("sshAuth.totpVerify")}
|
||||
{isPush
|
||||
? t("sshAuth.mfaSendRequest")
|
||||
: isPassword
|
||||
? t("common.connect")
|
||||
: t("sshAuth.totpVerify")}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
import React from "react";
|
||||
import { fireEvent, render, screen } from "@testing-library/react";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { TOTPDialog } from "@/ssh/dialogs/TOTPDialog";
|
||||
|
||||
vi.mock("react-i18next", () => ({
|
||||
useTranslation: () => ({ t: (key: string) => key }),
|
||||
}));
|
||||
|
||||
describe("SSH password prompts", () => {
|
||||
it("accepts a full password and preserves whitespace", () => {
|
||||
const onSubmit = vi.fn();
|
||||
const { container } = render(
|
||||
<TOTPDialog
|
||||
isOpen
|
||||
prompt="Password:"
|
||||
mode="password"
|
||||
onSubmit={onSubmit}
|
||||
onCancel={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
const input = container.querySelector("input")!;
|
||||
expect(input.type).toBe("password");
|
||||
expect(input).not.toHaveAttribute("maxLength");
|
||||
expect(input).not.toHaveAttribute("pattern");
|
||||
expect(input).not.toHaveAttribute("inputMode", "numeric");
|
||||
fireEvent.change(input, { target: { value: " LongPassword!123 " } });
|
||||
fireEvent.submit(container.querySelector("form")!);
|
||||
expect(onSubmit).toHaveBeenCalledWith(" LongPassword!123 ");
|
||||
expect(screen.queryByText("sshAuth.totpRequired")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("still restricts verification codes to digits", () => {
|
||||
const { container } = render(
|
||||
<TOTPDialog
|
||||
isOpen
|
||||
prompt="Code:"
|
||||
mode="totp"
|
||||
onSubmit={vi.fn()}
|
||||
onCancel={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
expect(container.querySelector("input")).toHaveAttribute(
|
||||
"pattern",
|
||||
"[0-9]*",
|
||||
);
|
||||
expect(container.querySelector("input")).toHaveAttribute("maxLength", "8");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user