Compare commits

..

7 Commits

Author SHA1 Message Date
Sheen Capadngan
3e3f42a8f7 doc: add groups endpoints to api reference documentation 2024-09-25 15:31:54 +08:00
Daniel Hougaard
da86338bfe Merge pull request #2480 from Infisical/daniel/fix-better-not-found-error
fix: throw not found when entity is not found
2024-09-24 21:08:42 +04:00
Vlad Matsiiako
fe8a1e6ce6 Merge pull request #2476 from Infisical/daniel/fix-missing-vars-count
fix(dashboard): fix imports missing secrets counter
2024-09-24 09:46:31 -07:00
Maidul Islam
55aa3f7b58 Merge pull request #2479 from Infisical/misc/audit-log-page-warning-and-auto-select
misc: added maintenance notice to audit log page
2024-09-24 12:41:49 -04:00
Sheen Capadngan
59f3581370 misc: made it specific for cloud 2024-09-25 00:31:13 +08:00
Sheen Capadngan
ccae63936c misc: added maintenance notice to audit log page and handled project auto-select 2024-09-25 00:27:36 +08:00
Daniel Hougaard
fc39b3b0dd fix(dashboard): fix imports missing secrets counter 2024-09-24 17:24:38 +04:00
21 changed files with 133 additions and 19 deletions

View File

@@ -48,7 +48,7 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => {
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
schema: {
params: z.object({
id: z.string()
id: z.string().trim().describe(GROUPS.GET_BY_ID.id)
}),
response: {
200: GroupsSchema

View File

@@ -24,6 +24,9 @@ export const GROUPS = {
id: "The id of the group to add the user to.",
username: "The username of the user to add to the group."
},
GET_BY_ID: {
id: "The id of the group to fetch"
},
DELETE_USER: {
id: "The id of the group to remove the user from.",
username: "The username of the user to remove from the group."

View File

@@ -0,0 +1,4 @@
---
title: "Add Group User"
openapi: "POST /api/v1/groups/{id}/users/{username}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Create"
openapi: "POST /api/v1/groups"
---

View File

@@ -0,0 +1,4 @@
---
title: "Delete"
openapi: "DELETE /api/v1/groups/{id}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Get By ID"
openapi: "GET /api/v1/groups/{id}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Get Groups in Organization"
openapi: "GET /api/v1/groups"
---

View File

@@ -0,0 +1,4 @@
---
title: "List Group Users"
openapi: "GET /api/v1/groups/{id}/users"
---

View File

@@ -0,0 +1,4 @@
---
title: "Remove Group User"
openapi: "DELETE /api/v1/groups/{id}/users/{username}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Update"
openapi: "PATCH /api/v1/groups/{id}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Create Project Membership"
openapi: "POST /api/v2/workspace/{projectId}/groups/{groupId}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Delete Project Membership"
openapi: "DELETE /api/v2/workspace/{projectId}/groups/{groupId}"
---

View File

@@ -0,0 +1,4 @@
---
title: "Get Project Membership"
openapi: "GET /api/v2/workspace/{projectId}/groups/{groupId}"
---

View File

@@ -0,0 +1,4 @@
---
title: "List Project Memberships"
openapi: "GET /api/v2/workspace/{projectId}/groups"
---

View File

@@ -0,0 +1,4 @@
---
title: "Update Project Membership"
openapi: "PATCH /api/v2/workspace/{projectId}/groups/{groupId}"
---

View File

@@ -546,6 +546,19 @@
"api-reference/endpoints/oidc-auth/revoke"
]
},
{
"group": "Groups",
"pages": [
"api-reference/endpoints/groups/create",
"api-reference/endpoints/groups/update",
"api-reference/endpoints/groups/delete",
"api-reference/endpoints/groups/get",
"api-reference/endpoints/groups/get-by-id",
"api-reference/endpoints/groups/add-group-user",
"api-reference/endpoints/groups/remove-group-user",
"api-reference/endpoints/groups/list-group-users"
]
},
{
"group": "Organizations",
"pages": [
@@ -577,6 +590,16 @@
"api-reference/endpoints/project-users/update-membership"
]
},
{
"group": "Project Groups",
"pages": [
"api-reference/endpoints/project-groups/create",
"api-reference/endpoints/project-groups/delete",
"api-reference/endpoints/project-groups/get-by-id",
"api-reference/endpoints/project-groups/list",
"api-reference/endpoints/project-groups/update"
]
},
{
"group": "Project Identities",
"pages": [

View File

@@ -189,6 +189,22 @@ export const useGetImportedSecretsAllEnvs = ({
}))
});
const getEnvImportedSecretKeyCount = useCallback(
(env: string) => {
const selectedEnvIndex = environments.indexOf(env);
let totalSecrets = 0;
if (selectedEnvIndex !== -1) {
secretImports?.[selectedEnvIndex]?.data?.forEach((secret) => {
totalSecrets += secret.secrets.length;
});
}
return totalSecrets;
},
[(secretImports || []).map((response) => response.data)]
);
const isImportedSecretPresentInEnv = useCallback(
(envSlug: string, secretName: string) => {
const selectedEnvIndex = environments.indexOf(envSlug);
@@ -226,7 +242,12 @@ export const useGetImportedSecretsAllEnvs = ({
[(secretImports || []).map((response) => response.data)]
);
return { secretImports, isImportedSecretPresentInEnv, getImportedSecretByKey };
return {
secretImports,
isImportedSecretPresentInEnv,
getImportedSecretByKey,
getEnvImportedSecretKeyCount
};
};
export const useGetImportedFoldersByEnv = ({

View File

@@ -1,3 +1,4 @@
import { NoticeBanner } from "@app/components/v2";
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
import { withPermission } from "@app/hoc";
@@ -10,6 +11,14 @@ export const AuditLogsPage = withPermission(
<div className="w-full max-w-7xl px-6">
<div className="bg-bunker-800 py-6">
<p className="text-3xl font-semibold text-gray-200">Audit Logs</p>
{(window.location.origin.includes("https://app.infisical.com") ||
window.location.origin.includes("https://gamma.infisical.com")) && (
<NoticeBanner title="The audit logs page is in maintenance" className="mt-4">
We are currently working on improving the performance of querying audit logs.
However, please note that audit logs are still being published as usual, so theres
no disruption to log generation.
</NoticeBanner>
)}
<div />
</div>
<LogsSection filterClassName="static p-2" showFilters isOrgAuditLogs />

View File

@@ -1,6 +1,6 @@
/* eslint-disable no-nested-ternary */
import { useState } from "react";
import { Control, Controller, UseFormReset, UseFormWatch } from "react-hook-form";
import { useEffect, useState } from "react";
import { Control, Controller, UseFormReset, UseFormSetValue, UseFormWatch } from "react-hook-form";
import {
faCheckCircle,
faChevronDown,
@@ -41,6 +41,7 @@ type Props = {
};
className?: string;
isOrgAuditLogs?: boolean;
setValue: UseFormSetValue<AuditLogFilterFormData>;
control: Control<AuditLogFilterFormData>;
reset: UseFormReset<AuditLogFilterFormData>;
watch: UseFormWatch<AuditLogFilterFormData>;
@@ -51,6 +52,7 @@ export const LogsFilter = ({
isOrgAuditLogs,
className,
control,
setValue,
reset,
watch
}: Props) => {
@@ -60,6 +62,12 @@ export const LogsFilter = ({
const { currentWorkspace, workspaces } = useWorkspace();
const { data, isLoading } = useGetAuditLogActorFilterOpts(currentWorkspace?.id ?? "");
useEffect(() => {
if (workspaces.length) {
setValue("projectId", workspaces[0].id);
}
}, [workspaces]);
const renderActorSelectItem = (actor: Actor) => {
switch (actor.type) {
case ActorType.USER:
@@ -243,20 +251,14 @@ export const LogsFilter = ({
className="w-40"
>
<Select
value={value === undefined ? "all" : value}
value={value}
{...field}
onValueChange={(e) => {
if (e === "all") onChange(undefined);
else onChange(e);
}}
onValueChange={(e) => onChange(e)}
className={twMerge(
"w-full border border-mineshaft-500 bg-mineshaft-700 text-mineshaft-100",
value === undefined && "text-mineshaft-400"
)}
>
<SelectItem value="all" key="all">
All projects
</SelectItem>
{workspaces.map((project) => (
<SelectItem value={String(project.id || "")} key={project.id}>
{project.name}

View File

@@ -44,7 +44,7 @@ export const LogsSection = ({
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["upgradePlan"] as const);
const { control, reset, watch } = useForm<AuditLogFilterFormData>({
const { control, reset, watch, setValue } = useForm<AuditLogFilterFormData>({
resolver: yupResolver(auditLogFilterFormSchema),
defaultValues: {
projectId: undefined,
@@ -79,6 +79,7 @@ export const LogsSection = ({
className={filterClassName}
presets={presets}
control={control}
setValue={setValue}
watch={watch}
reset={reset}
/>

View File

@@ -207,11 +207,12 @@ export const SecretOverviewPage = () => {
setVisibleEnvs(readableEnvs);
}, [userAvailableEnvs, secretPath]);
const { isImportedSecretPresentInEnv, getImportedSecretByKey } = useGetImportedSecretsAllEnvs({
projectId: workspaceId,
path: secretPath,
environments: userAvailableEnvs.map(({ slug }) => slug)
});
const { isImportedSecretPresentInEnv, getImportedSecretByKey, getEnvImportedSecretKeyCount } =
useGetImportedSecretsAllEnvs({
projectId: workspaceId,
path: secretPath,
environments: userAvailableEnvs.map(({ slug }) => slug)
});
const paginationOffset = (page - 1) * perPage;
@@ -784,7 +785,9 @@ export const SecretOverviewPage = () => {
</Th>
{visibleEnvs?.map(({ name, slug }, index) => {
const envSecKeyCount = getEnvSecretKeyCount(slug);
const missingKeyCount = secKeys.length - envSecKeyCount;
const importedSecKeyCount = getEnvImportedSecretKeyCount(slug);
const missingKeyCount = secKeys.length - envSecKeyCount - importedSecKeyCount;
return (
<Th
className="min-table-row min-w-[11rem] border-b-0 p-0 text-center"