mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-13 01:29:27 +00:00
review fixes + lint
This commit is contained in:
@@ -5,7 +5,6 @@ import { TPermissionServiceFactory } from "@app/ee/services/permission/permissio
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { groupBy } from "@app/lib/fn";
|
||||
import { TOrgMembershipDALFactory } from "@app/services/org-membership/org-membership-dal";
|
||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||
import { TProjectEnvDALFactory } from "@app/services/project-env/project-env-dal";
|
||||
import { TProjectMembershipDALFactory } from "@app/services/project-membership/project-membership-dal";
|
||||
@@ -45,7 +44,6 @@ type TAccessApprovalPolicyServiceFactoryDep = {
|
||||
accessApprovalRequestDAL: Pick<TAccessApprovalRequestDALFactory, "update" | "find" | "resetReviewByPolicyId">;
|
||||
additionalPrivilegeDAL: Pick<TProjectUserAdditionalPrivilegeDALFactory, "delete">;
|
||||
accessApprovalRequestReviewerDAL: Pick<TAccessApprovalRequestReviewerDALFactory, "update" | "delete">;
|
||||
orgMembershipDAL: Pick<TOrgMembershipDALFactory, "find">;
|
||||
accessApprovalPolicyEnvironmentDAL: TAccessApprovalPolicyEnvironmentDALFactory;
|
||||
};
|
||||
|
||||
@@ -62,7 +60,7 @@ export const accessApprovalPolicyServiceFactory = ({
|
||||
accessApprovalRequestDAL,
|
||||
additionalPrivilegeDAL,
|
||||
accessApprovalRequestReviewerDAL,
|
||||
orgMembershipDAL
|
||||
projectMembershipDAL
|
||||
}: TAccessApprovalPolicyServiceFactoryDep): TAccessApprovalPolicyServiceFactory => {
|
||||
const $policyExists = async ({
|
||||
envId,
|
||||
@@ -85,6 +83,22 @@ export const accessApprovalPolicyServiceFactory = ({
|
||||
return policyId ? policy && policy.id !== policyId : Boolean(policy);
|
||||
};
|
||||
|
||||
const verifyProjectUserMembership = async (userIds: string[], projectId: string) => {
|
||||
if (userIds.length === 0) return;
|
||||
const projectMemberships = await projectMembershipDAL.find({
|
||||
$in: { userId: userIds },
|
||||
projectId
|
||||
});
|
||||
|
||||
if (projectMemberships.length !== userIds.length) {
|
||||
const projectMemberUserIds = new Set(projectMemberships.map((member) => member.userId));
|
||||
const userIdsNotInProject = userIds.filter((id) => !projectMemberUserIds.has(id));
|
||||
throw new BadRequestError({
|
||||
message: `Some users are not members of the project: ${userIdsNotInProject.join(", ")}`
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const createAccessApprovalPolicy: TAccessApprovalPolicyServiceFactory["createAccessApprovalPolicy"] = async ({
|
||||
name,
|
||||
actor,
|
||||
@@ -175,19 +189,10 @@ export const accessApprovalPolicyServiceFactory = ({
|
||||
}
|
||||
|
||||
if (approverUserIds.length > 0) {
|
||||
const allApproverUserIds = approverUserIds.map((au) => au.id);
|
||||
const approverMembers = await orgMembershipDAL.find({
|
||||
$in: { userId: allApproverUserIds },
|
||||
orgId: actorOrgId
|
||||
});
|
||||
|
||||
if (approverMembers.length !== allApproverUserIds.length) {
|
||||
const approverMemberUserIds = new Set(approverMembers.map((member) => member.userId as string));
|
||||
const userIdsNotInOrg = allApproverUserIds.filter((id) => !approverMemberUserIds.has(id));
|
||||
throw new BadRequestError({
|
||||
message: `Some approvers are not in the organization: ${userIdsNotInOrg.join(", ")}`
|
||||
});
|
||||
}
|
||||
await verifyProjectUserMembership(
|
||||
approverUserIds.map((au) => au.id),
|
||||
project.id
|
||||
);
|
||||
}
|
||||
let groupBypassers: string[] = [];
|
||||
let bypasserUserIds: string[] = [];
|
||||
@@ -440,18 +445,7 @@ export const accessApprovalPolicyServiceFactory = ({
|
||||
|
||||
// Validate user bypassers
|
||||
if (bypasserUserIds.length > 0) {
|
||||
const orgMemberships = await orgMembershipDAL.find({
|
||||
$in: { userId: bypasserUserIds },
|
||||
orgId: actorOrgId
|
||||
});
|
||||
|
||||
if (orgMemberships.length !== bypasserUserIds.length) {
|
||||
const foundUserIdsInOrg = new Set(orgMemberships.map((mem) => mem.userId));
|
||||
const missingUserIds = bypasserUserIds.filter((id) => !foundUserIdsInOrg.has(id));
|
||||
throw new BadRequestError({
|
||||
message: `One or more specified bypasser users are not part of the organization or do not exist. Invalid or non-member user IDs: ${missingUserIds.join(", ")}`
|
||||
});
|
||||
}
|
||||
await verifyProjectUserMembership(bypasserUserIds, accessApprovalPolicy.projectId);
|
||||
}
|
||||
|
||||
// Validate group bypassers
|
||||
@@ -517,19 +511,10 @@ export const accessApprovalPolicyServiceFactory = ({
|
||||
}
|
||||
|
||||
if (approverUserIds.length > 0) {
|
||||
const allApproverUserIds = approverUserIds.map((au) => au.id);
|
||||
const approverMembers = await orgMembershipDAL.find({
|
||||
$in: { userId: allApproverUserIds },
|
||||
orgId: actorOrgId
|
||||
});
|
||||
|
||||
if (approverMembers.length !== allApproverUserIds.length) {
|
||||
const approverMemberUserIds = new Set(approverMembers.map((member) => member.userId as string));
|
||||
const userIdsNotInOrg = allApproverUserIds.filter((id) => !approverMemberUserIds.has(id));
|
||||
throw new BadRequestError({
|
||||
message: `Some approvers are not in the organization: ${userIdsNotInOrg.join(", ")}`
|
||||
});
|
||||
}
|
||||
await verifyProjectUserMembership(
|
||||
approverUserIds.map((au) => au.id),
|
||||
accessApprovalPolicy.projectId
|
||||
);
|
||||
}
|
||||
await accessApprovalPolicyApproverDAL.insertMany(
|
||||
approverUserIds.map((el) => ({
|
||||
|
||||
@@ -7,8 +7,8 @@ import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services
|
||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { removeTrailingSlash } from "@app/lib/fn";
|
||||
import { containsGlobPatterns } from "@app/lib/picomatch";
|
||||
import { TOrgMembershipDALFactory } from "@app/services/org-membership/org-membership-dal";
|
||||
import { TProjectEnvDALFactory } from "@app/services/project-env/project-env-dal";
|
||||
import { TProjectMembershipDALFactory } from "@app/services/project-membership/project-membership-dal";
|
||||
import { TUserDALFactory } from "@app/services/user/user-dal";
|
||||
|
||||
import { ApproverType, BypasserType } from "../access-approval-policy/access-approval-policy-types";
|
||||
@@ -40,7 +40,7 @@ type TSecretApprovalPolicyServiceFactoryDep = {
|
||||
secretApprovalPolicyDAL: TSecretApprovalPolicyDALFactory;
|
||||
projectEnvDAL: Pick<TProjectEnvDALFactory, "findOne" | "find">;
|
||||
userDAL: Pick<TUserDALFactory, "find">;
|
||||
orgMembershipDAL: Pick<TOrgMembershipDALFactory, "find">;
|
||||
projectMembershipDAL: Pick<TProjectMembershipDALFactory, "find">;
|
||||
secretApprovalPolicyApproverDAL: TSecretApprovalPolicyApproverDALFactory;
|
||||
secretApprovalPolicyBypasserDAL: TSecretApprovalPolicyBypasserDALFactory;
|
||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||
@@ -58,10 +58,26 @@ export const secretApprovalPolicyServiceFactory = ({
|
||||
secretApprovalPolicyEnvironmentDAL,
|
||||
projectEnvDAL,
|
||||
userDAL,
|
||||
orgMembershipDAL,
|
||||
projectMembershipDAL,
|
||||
licenseService,
|
||||
secretApprovalRequestDAL
|
||||
}: TSecretApprovalPolicyServiceFactoryDep) => {
|
||||
const verifyProjectUserMembership = async (userIds: string[], projectId: string) => {
|
||||
if (userIds.length === 0) return;
|
||||
const projectMemberships = await projectMembershipDAL.find({
|
||||
$in: { userId: userIds },
|
||||
projectId
|
||||
});
|
||||
|
||||
if (projectMemberships.length !== userIds.length) {
|
||||
const projectMemberUserIds = new Set(projectMemberships.map((member) => member.userId));
|
||||
const userIdsNotInProject = userIds.filter((id) => !projectMemberUserIds.has(id));
|
||||
throw new BadRequestError({
|
||||
message: `Some users are not members of the project: ${userIdsNotInProject.join(", ")}`
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const $policyExists = async ({
|
||||
envIds,
|
||||
envId,
|
||||
@@ -205,6 +221,7 @@ export const secretApprovalPolicyServiceFactory = ({
|
||||
},
|
||||
tx
|
||||
);
|
||||
|
||||
await secretApprovalPolicyEnvironmentDAL.insertMany(
|
||||
envs.map((env) => ({
|
||||
envId: env.id,
|
||||
@@ -236,23 +253,7 @@ export const secretApprovalPolicyServiceFactory = ({
|
||||
userApproverIds = userApproverIds.concat(approverUsers.map((user) => user.id));
|
||||
}
|
||||
|
||||
if (userApproverIds.length > 0) {
|
||||
const approverMembers = await orgMembershipDAL.find(
|
||||
{
|
||||
$in: { userId: userApproverIds },
|
||||
orgId: actorOrgId
|
||||
},
|
||||
{ tx }
|
||||
);
|
||||
|
||||
if (approverMembers.length !== userApproverIds.length) {
|
||||
const approverMemberUserIds = new Set(approverMembers.map((member) => member.userId as string));
|
||||
const userIdsNotInOrg = userApproverIds.filter((id) => !approverMemberUserIds.has(id));
|
||||
throw new BadRequestError({
|
||||
message: `Some approvers are not in the organization: ${userIdsNotInOrg.join(", ")}`
|
||||
});
|
||||
}
|
||||
}
|
||||
await verifyProjectUserMembership(userApproverIds, projectId);
|
||||
|
||||
await secretApprovalPolicyApproverDAL.insertMany(
|
||||
userApproverIds.map((approverUserId) => ({
|
||||
@@ -446,23 +447,7 @@ export const secretApprovalPolicyServiceFactory = ({
|
||||
userApproverIds = userApproverIds.concat(approverUsers.map((user) => user.id));
|
||||
}
|
||||
|
||||
if (userApproverIds.length > 0) {
|
||||
const approverMembers = await orgMembershipDAL.find(
|
||||
{
|
||||
$in: { userId: userApproverIds },
|
||||
orgId: actorOrgId
|
||||
},
|
||||
{ tx }
|
||||
);
|
||||
|
||||
if (approverMembers.length !== userApproverIds.length) {
|
||||
const approverMemberUserIds = new Set(approverMembers.map((member) => member.userId as string));
|
||||
const userIdsNotInOrg = userApproverIds.filter((id) => !approverMemberUserIds.has(id));
|
||||
throw new BadRequestError({
|
||||
message: `Some approvers are not in the organization: ${userIdsNotInOrg.join(", ")}`
|
||||
});
|
||||
}
|
||||
}
|
||||
await verifyProjectUserMembership(userApproverIds, secretApprovalPolicy.projectId);
|
||||
|
||||
await secretApprovalPolicyApproverDAL.insertMany(
|
||||
userApproverIds.map((approverUserId) => ({
|
||||
|
||||
@@ -611,7 +611,7 @@ export const registerRoutes = async (
|
||||
secretApprovalPolicyDAL,
|
||||
licenseService,
|
||||
userDAL,
|
||||
orgMembershipDAL,
|
||||
projectMembershipDAL,
|
||||
secretApprovalRequestDAL
|
||||
});
|
||||
const tokenService = tokenServiceFactory({ tokenDAL: authTokenDAL, userDAL, orgMembershipDAL });
|
||||
@@ -1421,8 +1421,7 @@ export const registerRoutes = async (
|
||||
userDAL,
|
||||
accessApprovalRequestDAL,
|
||||
additionalPrivilegeDAL: projectUserAdditionalPrivilegeDAL,
|
||||
accessApprovalRequestReviewerDAL,
|
||||
orgMembershipDAL
|
||||
accessApprovalRequestReviewerDAL
|
||||
});
|
||||
|
||||
const accessApprovalRequestService = accessApprovalRequestServiceFactory({
|
||||
|
||||
@@ -58,8 +58,8 @@ import { registerSecretRequestsRouter } from "./secret-requests-router";
|
||||
import { registerSecretSharingRouter } from "./secret-sharing-router";
|
||||
import { registerSecretTagRouter } from "./secret-tag-router";
|
||||
import { registerSlackRouter } from "./slack-router";
|
||||
import { registerUpgradePathRouter } from "./upgrade-path-router";
|
||||
import { registerSsoRouter } from "./sso-router";
|
||||
import { registerUpgradePathRouter } from "./upgrade-path-router";
|
||||
import { registerUserActionRouter } from "./user-action-router";
|
||||
import { registerUserEngagementRouter } from "./user-engagement-router";
|
||||
import { registerUserRouter } from "./user-router";
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import { CredentialDisplay } from "@app/components/secret-rotations-v2/ViewSecretRotationV2GeneratedCredentials/shared/CredentialDisplay";
|
||||
import { TRedisCredentialsRotationGeneratedCredentialsResponse } from "@app/hooks/api/secretRotationsV2/types/redis-credentials-rotation";
|
||||
|
||||
import { ViewRotationGeneratedCredentialsDisplay } from "./shared";
|
||||
import { TRedisCredentialsRotationGeneratedCredentialsResponse } from "@app/hooks/api/secretRotationsV2/types/redis-credentials-rotation";
|
||||
|
||||
type Props = {
|
||||
generatedCredentialsResponse: TRedisCredentialsRotationGeneratedCredentialsResponse;
|
||||
|
||||
+2
-1
@@ -3,6 +3,7 @@ import { Controller, useFormContext } from "react-hook-form";
|
||||
import { TSecretRotationV2Form } from "@app/components/secret-rotations-v2/forms/schemas";
|
||||
import { FormControl, Input } from "@app/components/v2";
|
||||
import { SecretRotation } from "@app/hooks/api/secretRotationsV2";
|
||||
|
||||
import { DEFAULT_PASSWORD_REQUIREMENTS } from "../schemas/shared";
|
||||
|
||||
export const RedisCredentialsRotationParametersFields = () => {
|
||||
@@ -18,7 +19,7 @@ export const RedisCredentialsRotationParametersFields = () => {
|
||||
<Controller
|
||||
control={control}
|
||||
name="parameters.permissionScope"
|
||||
defaultValue={""}
|
||||
defaultValue=""
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
tooltipClassName="max-w-[40rem] w-full"
|
||||
|
||||
+1
-1
@@ -8,8 +8,8 @@ import { AwsIamUserSecretRotationParametersFields } from "./AwsIamUserSecretRota
|
||||
import { AzureClientSecretRotationParametersFields } from "./AzureClientSecretRotationParametersFields";
|
||||
import { LdapPasswordRotationParametersFields } from "./LdapPasswordRotationParametersFields";
|
||||
import { OktaClientSecretRotationParametersFields } from "./OktaClientSecretRotationParametersFields";
|
||||
import { SqlCredentialsRotationParametersFields } from "./shared";
|
||||
import { RedisCredentialsRotationParametersFields } from "./RedisCredentialsRotationParametersFields";
|
||||
import { SqlCredentialsRotationParametersFields } from "./shared";
|
||||
|
||||
const COMPONENT_MAP: Record<SecretRotation, React.FC> = {
|
||||
[SecretRotation.PostgresCredentials]: SqlCredentialsRotationParametersFields,
|
||||
|
||||
+1
-1
@@ -11,8 +11,8 @@ import { AwsIamUserSecretRotationReviewFields } from "./AwsIamUserSecretRotation
|
||||
import { AzureClientSecretRotationReviewFields } from "./AzureClientSecretRotationReviewFields";
|
||||
import { LdapPasswordRotationReviewFields } from "./LdapPasswordRotationReviewFields";
|
||||
import { OktaClientSecretRotationReviewFields } from "./OktaClientSecretRotationReviewFields";
|
||||
import { SqlCredentialsRotationReviewFields } from "./shared";
|
||||
import { RedisCredentialsRotationReviewFields } from "./RedisCredentialsRotationReviewFields";
|
||||
import { SqlCredentialsRotationReviewFields } from "./shared";
|
||||
|
||||
const COMPONENT_MAP: Record<SecretRotation, React.FC> = {
|
||||
[SecretRotation.PostgresCredentials]: SqlCredentialsRotationReviewFields,
|
||||
|
||||
+1
-1
@@ -8,8 +8,8 @@ import { AwsIamUserSecretRotationSecretsMappingFields } from "./AwsIamUserSecret
|
||||
import { AzureClientSecretRotationSecretsMappingFields } from "./AzureClientSecretRotationSecretsMappingFields";
|
||||
import { LdapPasswordRotationSecretsMappingFields } from "./LdapPasswordRotationSecretsMappingFields";
|
||||
import { OktaClientSecretRotationSecretsMappingFields } from "./OktaClientSecretRotationSecretsMappingFields";
|
||||
import { SqlCredentialsRotationSecretsMappingFields } from "./shared";
|
||||
import { RedisCredentialsRotationSecretsMappingFields } from "./RedisCredentialsRotationSecretsMappingFields";
|
||||
import { SqlCredentialsRotationSecretsMappingFields } from "./shared";
|
||||
|
||||
const COMPONENT_MAP: Record<SecretRotation, React.FC> = {
|
||||
[SecretRotation.PostgresCredentials]: SqlCredentialsRotationSecretsMappingFields,
|
||||
|
||||
+4
-1
@@ -164,7 +164,10 @@ export const PkiSyncRow = ({
|
||||
</div>
|
||||
</Td>
|
||||
{subscriberId ? (
|
||||
<PkiSyncTableCell primaryText={pkiSync.subscriber?.name || subscriberId} secondaryText="PKI Subscriber" />
|
||||
<PkiSyncTableCell
|
||||
primaryText={pkiSync.subscriber?.name || subscriberId}
|
||||
secondaryText="PKI Subscriber"
|
||||
/>
|
||||
) : (
|
||||
<Td>
|
||||
<Tooltip content="The PKI subscriber for this sync has been deleted. Configure a new source or remove this sync.">
|
||||
|
||||
+1
-1
@@ -40,6 +40,7 @@ import { OktaConnectionForm } from "./OktaConnectionForm";
|
||||
import { OracleDBConnectionForm } from "./OracleDBConnectionForm";
|
||||
import { PostgresConnectionForm } from "./PostgresConnectionForm";
|
||||
import { RailwayConnectionForm } from "./RailwayConnectionForm";
|
||||
import { RedisConnectionForm } from "./RedisConnectionForm";
|
||||
import { RenderConnectionForm } from "./RenderConnectionForm";
|
||||
import { SupabaseConnectionForm } from "./SupabaseConnectionForm";
|
||||
import { TeamCityConnectionForm } from "./TeamCityConnectionForm";
|
||||
@@ -47,7 +48,6 @@ import { TerraformCloudConnectionForm } from "./TerraformCloudConnectionForm";
|
||||
import { VercelConnectionForm } from "./VercelConnectionForm";
|
||||
import { WindmillConnectionForm } from "./WindmillConnectionForm";
|
||||
import { ZabbixConnectionForm } from "./ZabbixConnectionForm";
|
||||
import { RedisConnectionForm } from "./RedisConnectionForm";
|
||||
|
||||
type FormProps = {
|
||||
onComplete: (appConnection: TAppConnection) => void;
|
||||
|
||||
+3
-5
@@ -1,9 +1,11 @@
|
||||
import { useState } from "react";
|
||||
import { Controller, FormProvider, useForm } from "react-hook-form";
|
||||
import { faQuestionCircle } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { Tab } from "@headlessui/react";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { z } from "zod";
|
||||
|
||||
import { Tab } from "@headlessui/react";
|
||||
import {
|
||||
Button,
|
||||
FormControl,
|
||||
@@ -24,8 +26,6 @@ import {
|
||||
genericAppConnectionFieldsSchema,
|
||||
GenericAppConnectionsFields
|
||||
} from "./GenericAppConnectionFields";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faQuestionCircle } from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
type Props = {
|
||||
appConnection?: TRedisConnection;
|
||||
@@ -123,7 +123,6 @@ export const RedisConnectionForm = ({ appConnection, onSubmit }: Props) => {
|
||||
)}
|
||||
/>
|
||||
|
||||
<>
|
||||
<Tab.Group selectedIndex={selectedTabIndex} onChange={setSelectedTabIndex}>
|
||||
<Tab.List className="-pb-1 mb-6 w-full border-b-2 border-mineshaft-600">
|
||||
<Tab
|
||||
@@ -291,7 +290,6 @@ export const RedisConnectionForm = ({ appConnection, onSubmit }: Props) => {
|
||||
</Tab.Panel>
|
||||
</Tab.Panels>
|
||||
</Tab.Group>
|
||||
</>
|
||||
|
||||
<div className="mt-6 flex items-center">
|
||||
<Button
|
||||
|
||||
+1
-1
@@ -221,7 +221,7 @@ export const CreateSecretForm = ({ secretPath = "/", onClose }: Props) => {
|
||||
warning={
|
||||
secretKey?.includes(" ") ? (
|
||||
<Tooltip
|
||||
className={"w-full max-w-72"}
|
||||
className="w-full max-w-72"
|
||||
content={
|
||||
<div>
|
||||
Secret key contains whitespaces.
|
||||
|
||||
+1
-1
@@ -158,7 +158,7 @@ function SecretRenameRow({ environments, getSecretByKey, secretKey, secretPath }
|
||||
{currentSecretValue?.trim()?.includes(" ") &&
|
||||
currentSecretValue?.trim() !== secretKey && (
|
||||
<Tooltip
|
||||
className={"w-full max-w-72"}
|
||||
className="w-full max-w-72"
|
||||
content={
|
||||
<div>
|
||||
Secret key contains whitespaces.
|
||||
|
||||
+1
-1
@@ -181,7 +181,7 @@ export const CreateSecretForm = ({
|
||||
warning={
|
||||
secretKey?.includes(" ") ? (
|
||||
<Tooltip
|
||||
className={"w-full max-w-72"}
|
||||
className="w-full max-w-72"
|
||||
content={
|
||||
<div>
|
||||
Secret key contains whitespaces.
|
||||
|
||||
+1
-1
@@ -491,7 +491,7 @@ export const SecretItem = memo(
|
||||
field?.value !== (originalSecret.originalKey || originalSecret.key) &&
|
||||
field.value?.includes(" ") ? (
|
||||
<Tooltip
|
||||
className={"w-full max-w-72"}
|
||||
className="w-full max-w-72"
|
||||
content={
|
||||
<div>
|
||||
Secret key contains whitespaces.
|
||||
|
||||
Reference in New Issue
Block a user