Align import key validation with server

This commit is contained in:
Dotta committed 2026-05-09 15:07:08 -05:00
1 parent b4c25b8bf0
commit 1618c5726e
2 files changed
+73 -2

No files matched your search

@@ -357,6 +357,77 @@ describe("ImportFromVaultDialog", () => {
});
});
it("requires lowercase operator-entered keys during review", async () => {
const externalRef = "arn:aws:secretsmanager:us-east-1:1:secret:prod/openai-XYZ";
mockSecretsApi.remoteImportPreview.mockResolvedValueOnce(
makePreview([
makeCandidate({
externalRef,
remoteName: "prod/openai",
name: "OpenAI API key",
key: "openai-api-key",
}),
]),
);
const { queryClient } = makeWrapper();
const root = createRoot(container);
await act(async () => {
root.render(
<QueryClientProvider client={queryClient}>
<ImportFromVaultDialog
open
onOpenChange={vi.fn()}
companyId="company-1"
providerConfigs={[awsVault]}
existingSecrets={[]}
/>
</QueryClientProvider>,
);
});
await flush();
await flush();
const row = document.querySelector(
`[data-testid="vault-row-${externalRef}"]`,
) as HTMLElement | null;
await act(async () => {
row?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
});
await flush();
const continueBtn = Array.from(document.querySelectorAll("button")).find(
(btn) => btn.textContent?.includes("Continue"),
);
await act(async () => {
continueBtn!.click();
});
await flush();
const keyInput = document.querySelector(
`[data-testid="review-key-${externalRef}"]`,
) as HTMLInputElement | null;
const valueSetter = Object.getOwnPropertyDescriptor(
window.HTMLInputElement.prototype,
"value",
)?.set;
await act(async () => {
valueSetter?.call(keyInput, "MY_KEY");
keyInput!.dispatchEvent(new Event("input", { bubbles: true }));
});
await flush();
expect(document.body.textContent).toContain("lowercase letters");
const importBtn = Array.from(document.querySelectorAll("button")).find(
(btn) => btn.textContent?.startsWith("Import "),
) as HTMLButtonElement | undefined;
expect(importBtn?.disabled).toBe(true);
await act(async () => {
root.unmount();
});
});
it("submits the operator-entered review description", async () => {
const externalRef = "arn:aws:secretsmanager:us-east-1:1:secret:prod/openai-XYZ";
mockSecretsApi.remoteImportPreview.mockResolvedValueOnce(
@@ -71,7 +71,7 @@ interface DraftSelection {
description: string;
}
const KEY_PATTERN = /^[a-zA-Z0-9_.-]+$/;
const KEY_PATTERN = /^[a-z0-9_.-]+$/;
const PAGE_SIZE = 50;
function isAwsSelectable(config: CompanySecretProviderConfig) {
@@ -267,7 +267,7 @@ function validateDraftRow(
if (draft.name.length > 160) return "Name must be 160 characters or fewer.";
if (!draft.key.trim()) return "Key is required.";
if (!KEY_PATTERN.test(draft.key)) {
return "Key may only contain letters, numbers, dot, underscore, or hyphen.";
return "Key may only contain lowercase letters, numbers, dot, underscore, or hyphen.";
}
if (draft.key.length > 120) return "Key must be 120 characters or fewer.";
if (draft.description.length > 500) return "Description must be 500 characters or fewer.";