mirror of
https://github.com/formbricks/formbricks.git
synced 2026-02-17 12:31:05 -06:00
chore: make env permissions optional in api key (#5309)
Co-authored-by: Victor Santos <victor@formbricks.com>
This commit is contained in:
committed by
GitHub
parent
a171f9cb00
commit
b685032b34
@@ -1,4 +1,3 @@
|
||||
import { ApiKeyPermission } from "@prisma/client";
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
import { cleanup, render, screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
@@ -123,6 +122,9 @@ describe("AddApiKeyModal", () => {
|
||||
it("handles permission changes", async () => {
|
||||
render(<AddApiKeyModal {...defaultProps} />);
|
||||
|
||||
const addButton = screen.getByRole("button", { name: /add_permission/i });
|
||||
await userEvent.click(addButton);
|
||||
|
||||
// Open project dropdown for the first permission row
|
||||
const projectDropdowns = screen.getAllByRole("button", { name: /Project 1/i });
|
||||
await userEvent.click(projectDropdowns[0]);
|
||||
@@ -143,6 +145,8 @@ describe("AddApiKeyModal", () => {
|
||||
const addButton = screen.getByRole("button", { name: /add_permission/i });
|
||||
await userEvent.click(addButton);
|
||||
|
||||
await userEvent.click(addButton);
|
||||
|
||||
// Verify new permission row is added
|
||||
const deleteButtons = screen.getAllByRole("button", { name: "" }); // Trash icons
|
||||
expect(deleteButtons).toHaveLength(2);
|
||||
@@ -161,6 +165,9 @@ describe("AddApiKeyModal", () => {
|
||||
const labelInput = screen.getByPlaceholderText("e.g. GitHub, PostHog, Slack") as HTMLInputElement;
|
||||
await userEvent.type(labelInput, "Test API Key");
|
||||
|
||||
const addButton = screen.getByRole("button", { name: /add_permission/i });
|
||||
await userEvent.click(addButton);
|
||||
|
||||
// Click submit
|
||||
const submitButton = screen.getByRole("button", {
|
||||
name: "environments.project.api_keys.add_api_key",
|
||||
@@ -172,7 +179,7 @@ describe("AddApiKeyModal", () => {
|
||||
environmentPermissions: [
|
||||
{
|
||||
environmentId: "env1",
|
||||
permission: ApiKeyPermission.read,
|
||||
permission: "read",
|
||||
},
|
||||
],
|
||||
organizationAccess: {
|
||||
@@ -203,12 +210,7 @@ describe("AddApiKeyModal", () => {
|
||||
|
||||
expect(mockOnSubmit).toHaveBeenCalledWith({
|
||||
label: "Test API Key",
|
||||
environmentPermissions: [
|
||||
{
|
||||
environmentId: "env1",
|
||||
permission: ApiKeyPermission.read,
|
||||
},
|
||||
],
|
||||
environmentPermissions: [],
|
||||
organizationAccess: {
|
||||
accessControl: {
|
||||
read: true,
|
||||
@@ -218,7 +220,7 @@ describe("AddApiKeyModal", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("disables submit button when label is empty", async () => {
|
||||
it("disables submit button when label is empty and there are not environment permissions", async () => {
|
||||
render(<AddApiKeyModal {...defaultProps} />);
|
||||
const submitButton = screen.getByRole("button", {
|
||||
name: "environments.project.api_keys.add_api_key",
|
||||
@@ -228,6 +230,9 @@ describe("AddApiKeyModal", () => {
|
||||
// Initially disabled
|
||||
expect(submitButton).toBeDisabled();
|
||||
|
||||
const addButton = screen.getByRole("button", { name: /add_permission/i });
|
||||
await userEvent.click(addButton);
|
||||
|
||||
// After typing, it should be enabled
|
||||
await userEvent.type(labelInput, "Test");
|
||||
expect(submitButton).not.toBeDisabled();
|
||||
|
||||
@@ -89,9 +89,7 @@ export const AddApiKeyModal = ({
|
||||
};
|
||||
|
||||
// Initialize with one permission by default
|
||||
const [selectedPermissions, setSelectedPermissions] = useState<Record<string, PermissionRecord>>(() =>
|
||||
getInitialPermissions()
|
||||
);
|
||||
const [selectedPermissions, setSelectedPermissions] = useState<Record<string, PermissionRecord>>({});
|
||||
|
||||
const projectOptions: ProjectOption[] = projects.map((project) => ({
|
||||
id: project.id,
|
||||
@@ -106,14 +104,12 @@ export const AddApiKeyModal = ({
|
||||
|
||||
const addPermission = () => {
|
||||
const newIndex = Object.keys(selectedPermissions).length;
|
||||
if (projects.length > 0 && projects[0].environments.length > 0) {
|
||||
const initialPermission = getInitialPermissions()["permission-0"];
|
||||
if (initialPermission) {
|
||||
setSelectedPermissions({
|
||||
...selectedPermissions,
|
||||
[`permission-${newIndex}`]: initialPermission,
|
||||
});
|
||||
}
|
||||
const initialPermission = getInitialPermissions()["permission-0"];
|
||||
if (initialPermission) {
|
||||
setSelectedPermissions({
|
||||
...selectedPermissions,
|
||||
[`permission-${newIndex}`]: initialPermission,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -176,7 +172,7 @@ export const AddApiKeyModal = ({
|
||||
});
|
||||
|
||||
reset();
|
||||
setSelectedPermissions(getInitialPermissions());
|
||||
setSelectedPermissions({});
|
||||
setSelectedOrganizationAccess(defaultOrganizationAccess);
|
||||
};
|
||||
|
||||
@@ -191,11 +187,16 @@ export const AddApiKeyModal = ({
|
||||
if (!apiKeyLabel?.trim()) {
|
||||
return true;
|
||||
}
|
||||
// Check if there are any valid permissions
|
||||
if (Object.keys(selectedPermissions).length === 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
// Check if at least one project permission is set or one organization access toggle is ON
|
||||
const hasProjectAccess = Object.keys(selectedPermissions).length > 0;
|
||||
|
||||
const hasOrganizationAccess = Object.values(selectedOrganizationAccess).some((accessGroup) =>
|
||||
Object.values(accessGroup).some((value) => value === true)
|
||||
);
|
||||
|
||||
// Disable submit if no access rights are granted
|
||||
return !(hasProjectAccess || hasOrganizationAccess);
|
||||
};
|
||||
|
||||
const setSelectedOrganizationAccessValue = (key: string, accessType: string, value: boolean) => {
|
||||
@@ -335,15 +336,8 @@ export const AddApiKeyModal = ({
|
||||
<button
|
||||
type="button"
|
||||
className="p-2"
|
||||
onClick={() => removePermission(permissionIndex)}
|
||||
disabled={Object.keys(selectedPermissions).length <= 1}>
|
||||
<Trash2Icon
|
||||
className={`h-5 w-5 ${
|
||||
Object.keys(selectedPermissions).length <= 1
|
||||
? "text-slate-300"
|
||||
: "text-slate-500 hover:text-red-500"
|
||||
}`}
|
||||
/>
|
||||
onClick={() => removePermission(permissionIndex)}>
|
||||
<Trash2Icon className={"h-5 w-5 text-slate-500 hover:text-red-500"} />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
@@ -403,7 +397,7 @@ export const AddApiKeyModal = ({
|
||||
onClick={() => {
|
||||
setOpen(false);
|
||||
reset();
|
||||
setSelectedPermissions(getInitialPermissions());
|
||||
setSelectedPermissions({});
|
||||
}}>
|
||||
{t("common.cancel")}
|
||||
</Button>
|
||||
|
||||
@@ -265,7 +265,7 @@ describe("EditAPIKeys", () => {
|
||||
organizationId: "org1",
|
||||
apiKeyData: {
|
||||
label: "New Key",
|
||||
environmentPermissions: [{ environmentId: "env1", permission: ApiKeyPermission.read }],
|
||||
environmentPermissions: [],
|
||||
organizationAccess: {
|
||||
accessControl: { read: true, write: false },
|
||||
},
|
||||
|
||||
@@ -98,9 +98,15 @@ export const ViewPermissionModal = ({
|
||||
data-testid="api-key-label"
|
||||
{...register("label", { required: true, validate: (value) => value.trim() !== "" })}
|
||||
/>
|
||||
{/* Permission rows */}
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label>{t("environments.project.api_keys.permissions")}</Label>
|
||||
{apiKey.apiKeyEnvironments?.length === 0 && (
|
||||
<div className="text-center text-sm">
|
||||
{t("environments.project.api_keys.no_env_permissions_found")}
|
||||
</div>
|
||||
)}
|
||||
<div className="space-y-2">
|
||||
{/* Permission rows */}
|
||||
{apiKey.apiKeyEnvironments?.map((permission) => {
|
||||
|
||||
@@ -18,6 +18,7 @@ export async function loginAndGetApiKey(page: Page, users: UsersFixture) {
|
||||
await page.getByRole("button", { name: "Add API Key" }).isVisible();
|
||||
await page.getByRole("button", { name: "Add API Key" }).click();
|
||||
await page.getByPlaceholder("e.g. GitHub, PostHog, Slack").fill("E2E Test API Key");
|
||||
await page.getByRole("button", { name: "+ Add permission" }).click();
|
||||
await page.getByRole("button", { name: "development" }).click();
|
||||
await page.getByRole("menuitem", { name: "production" }).click();
|
||||
await page.getByRole("button", { name: "read" }).click();
|
||||
|
||||
@@ -788,6 +788,7 @@
|
||||
"api_key_updated": "API-Schlüssel aktualisiert",
|
||||
"duplicate_access": "Doppelter Projektzugriff nicht erlaubt",
|
||||
"no_api_keys_yet": "Du hast noch keine API-Schlüssel",
|
||||
"no_env_permissions_found": "Keine Umgebungsberechtigungen gefunden",
|
||||
"organization_access": "Organisationszugang",
|
||||
"permissions": "Berechtigungen",
|
||||
"project_access": "Projektzugriff",
|
||||
|
||||
@@ -788,6 +788,7 @@
|
||||
"api_key_updated": "API Key updated",
|
||||
"duplicate_access": "Duplicate project access not allowed",
|
||||
"no_api_keys_yet": "You don't have any API keys yet",
|
||||
"no_env_permissions_found": "No environment permissions found",
|
||||
"organization_access": "Organization Access",
|
||||
"permissions": "Permissions",
|
||||
"project_access": "Project Access",
|
||||
|
||||
@@ -788,6 +788,7 @@
|
||||
"api_key_updated": "Clé API mise à jour",
|
||||
"duplicate_access": "L'accès en double au projet n'est pas autorisé",
|
||||
"no_api_keys_yet": "Vous n'avez pas encore de clés API.",
|
||||
"no_env_permissions_found": "Aucune autorisation d'environnement trouvée",
|
||||
"organization_access": "Accès à l'organisation",
|
||||
"permissions": "Permissions",
|
||||
"project_access": "Accès au projet",
|
||||
|
||||
@@ -788,6 +788,7 @@
|
||||
"api_key_updated": "Chave de API atualizada",
|
||||
"duplicate_access": "Acesso duplicado ao projeto não permitido",
|
||||
"no_api_keys_yet": "Você ainda não tem nenhuma chave de API",
|
||||
"no_env_permissions_found": "Nenhuma permissão de ambiente encontrada",
|
||||
"organization_access": "Acesso à Organização",
|
||||
"permissions": "Permissões",
|
||||
"project_access": "Acesso ao Projeto",
|
||||
|
||||
@@ -788,6 +788,7 @@
|
||||
"api_key_updated": "Chave API atualizada",
|
||||
"duplicate_access": "Acesso duplicado ao projeto não permitido",
|
||||
"no_api_keys_yet": "Ainda não tem nenhuma chave API",
|
||||
"no_env_permissions_found": "Nenhuma permissão de ambiente encontrada",
|
||||
"organization_access": "Acesso à Organização",
|
||||
"permissions": "Permissões",
|
||||
"project_access": "Acesso ao Projeto",
|
||||
|
||||
@@ -788,6 +788,7 @@
|
||||
"api_key_updated": "API 金鑰已更新",
|
||||
"duplicate_access": "不允許重複的 project 存取",
|
||||
"no_api_keys_yet": "您還沒有任何 API 金鑰",
|
||||
"no_env_permissions_found": "找不到環境權限",
|
||||
"organization_access": "組織 Access",
|
||||
"permissions": "權限",
|
||||
"project_access": "專案存取",
|
||||
|
||||
Reference in New Issue
Block a user