chore: v2.8.7 — Git SSH keys in tabs, safer Artifacts preview and search
- Settings → Git → Your git identity: SSH keys are one tab per host kind (GitHub · GitLab, AWS CodeCommit, More keys, Other hosts); opens on the AWS tab when only an RSA key exists. - Artifacts: a file type the sandboxed preview cannot show (Office, zip, PDF) offers Download only, never a blank Preview. - Artifacts search: `%`/`_`/`\` in a query match literally (LIKE ... ESCAPE). - Skill frontmatter rewrite replaces a key with its continuation lines and quotes values YAML could misread. - Plugin marketplace.json is read with a 1 MB streaming cap. - Artifact lists look each owner up once.
This commit is contained in:
@@ -4,7 +4,8 @@
|
||||
* first, and a member (S3) adds an HTTPS login of their own while the host's
|
||||
* view leaves HTTPS to the shared Git credentials table, and an SSH user per
|
||||
* host is saved — AWS CodeCommit's key ID inside its own RSA section, any
|
||||
* other host under "Other SSH hosts" — so the sections never mix; a named key
|
||||
* other host under "Other SSH hosts" — each kind of host in its own tab, so
|
||||
* the sections never mix; a named key
|
||||
* is made beside the default ones, and a second AWS account is saved under
|
||||
* its own name with the one key it uses.
|
||||
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
||||
@@ -47,6 +48,10 @@ const view = (over: Partial<GitIdentity> = {}): GitIdentity => ({
|
||||
...over,
|
||||
});
|
||||
|
||||
/** Opens one tab of the SSH keys. */
|
||||
const tab = async (name: string | RegExp) =>
|
||||
userEvent.click(await screen.findByRole("tab", { name }));
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
@@ -100,6 +105,7 @@ describe("GitIdentitySettings", () => {
|
||||
view({ ssh: { ...KEY, type: "rsa", publicKey: "ssh-rsa AAAAB3 an@agenthub" } })
|
||||
);
|
||||
render(<GitIdentitySettings />);
|
||||
await tab("AWS CodeCommit");
|
||||
const aws = await screen.findByRole("region", { name: "AWS CodeCommit" });
|
||||
await userEvent.click(within(aws).getByRole("button", { name: "Generate key" }));
|
||||
expect(api.gitIdentity.generateKey).toHaveBeenCalledWith(false, "rsa");
|
||||
@@ -119,11 +125,14 @@ describe("GitIdentitySettings", () => {
|
||||
vi.mocked(api.gitIdentity.removeKey).mockResolvedValue(view({ ssh: ED, sshKeys: [ED] }));
|
||||
render(<GitIdentitySettings />);
|
||||
const gh = await screen.findByRole("region", { name: /GitHub/ });
|
||||
const aws = screen.getByRole("region", { name: "AWS CodeCommit" });
|
||||
expect(within(gh).getByLabelText("Public key ED25519")).toHaveValue(ED.publicKey);
|
||||
expect(within(aws).getByLabelText("Public key RSA")).toHaveValue(RSA.publicKey);
|
||||
// Each section explains only its own host.
|
||||
// One tab at a time: the other host's section is not on screen.
|
||||
expect(screen.queryByRole("region", { name: "AWS CodeCommit" })).toBeNull();
|
||||
expect(within(gh).queryByText(/IAM/)).toBeNull();
|
||||
await tab("AWS CodeCommit");
|
||||
const aws = screen.getByRole("region", { name: "AWS CodeCommit" });
|
||||
expect(screen.queryByRole("region", { name: /GitHub/ })).toBeNull();
|
||||
expect(within(aws).getByLabelText("Public key RSA")).toHaveValue(RSA.publicKey);
|
||||
expect(within(aws).queryByText(/GitHub/)).toBeNull();
|
||||
expect(screen.getByRole("switch", { name: /terminal/ })).toBeChecked();
|
||||
await userEvent.click(within(aws).getByRole("button", { name: "Delete" }));
|
||||
@@ -160,7 +169,7 @@ describe("GitIdentitySettings", () => {
|
||||
view({ ssh: KEY, sshUsers: [{ host: "git.example.com", user: "deploy" }] })
|
||||
);
|
||||
render(<GitIdentitySettings />);
|
||||
await userEvent.click(await screen.findByText("Other SSH hosts (advanced)"));
|
||||
await tab("Other hosts");
|
||||
await userEvent.type(screen.getByLabelText("Host"), "ssh://git.example.com/x");
|
||||
await userEvent.type(screen.getByLabelText("User name"), "deploy");
|
||||
const form = screen.getByLabelText("Host").closest("form")!;
|
||||
@@ -228,13 +237,17 @@ describe("GitIdentitySettings", () => {
|
||||
view({ sshKeys: [RSA], sshUsers: [] })
|
||||
);
|
||||
render(<GitIdentitySettings />);
|
||||
const more = await screen.findByRole("region", { name: "More SSH keys" });
|
||||
// Only an RSA key: the AWS tab opens first.
|
||||
expect(await screen.findByRole("region", { name: "AWS CodeCommit" })).toBeInTheDocument();
|
||||
await tab("More keys");
|
||||
let more = screen.getByRole("region", { name: "More SSH keys" });
|
||||
await userEvent.click(within(more).getByRole("button", { name: "New key" }));
|
||||
await userEvent.type(within(more).getByLabelText("Key name"), "AWS-Prod");
|
||||
await userEvent.click(within(more).getByRole("button", { name: "Generate key" }));
|
||||
expect(api.gitIdentity.generateKey).toHaveBeenCalledWith(false, "rsa", "aws-prod");
|
||||
expect(await within(more).findByLabelText("Public key aws-prod")).toHaveValue("ssh-rsa B prod");
|
||||
|
||||
await tab("AWS CodeCommit");
|
||||
const aws = screen.getByRole("region", { name: "AWS CodeCommit" });
|
||||
await userEvent.type(within(aws).getByLabelText("SSH key ID"), "APKA2");
|
||||
await userEvent.type(within(aws).getByLabelText("Account name"), "aws-prod");
|
||||
@@ -251,6 +264,8 @@ describe("GitIdentitySettings", () => {
|
||||
).toBeInTheDocument();
|
||||
expect(within(aws).getByText("git clone ssh://aws-prod/v1/repos/<repo>")).toBeInTheDocument();
|
||||
|
||||
await tab("More keys (1)");
|
||||
more = screen.getByRole("region", { name: "More SSH keys" });
|
||||
await userEvent.click(within(more).getByRole("button", { name: "Delete aws-prod" }));
|
||||
await waitFor(() =>
|
||||
expect(api.gitIdentity.removeKeyById).toHaveBeenCalledWith("id_rsa_aws-prod")
|
||||
|
||||
Reference in New Issue
Block a user