mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 16:27:46 +00:00
feat(secret-approval): updated names to secret policy and fixed approval number bug
This commit is contained in:
@@ -16,7 +16,7 @@ import * as workspaceController from "./workspaceController";
|
|||||||
import * as secretScanningController from "./secretScanningController";
|
import * as secretScanningController from "./secretScanningController";
|
||||||
import * as webhookController from "./webhookController";
|
import * as webhookController from "./webhookController";
|
||||||
import * as secretImpsController from "./secretImpsController";
|
import * as secretImpsController from "./secretImpsController";
|
||||||
import * as secretApprovalController from "./secretApprovalController";
|
import * as secretApprovalPolicyController from "./secretApprovalPolicyController";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
authController,
|
authController,
|
||||||
@@ -37,5 +37,5 @@ export {
|
|||||||
secretScanningController,
|
secretScanningController,
|
||||||
webhookController,
|
webhookController,
|
||||||
secretImpsController,
|
secretImpsController,
|
||||||
secretApprovalController
|
secretApprovalPolicyController
|
||||||
};
|
};
|
||||||
|
|||||||
+12
-12
@@ -6,13 +6,13 @@ import {
|
|||||||
getUserProjectPermissions
|
getUserProjectPermissions
|
||||||
} from "../../ee/services/ProjectRoleService";
|
} from "../../ee/services/ProjectRoleService";
|
||||||
import { validateRequest } from "../../helpers/validation";
|
import { validateRequest } from "../../helpers/validation";
|
||||||
import { SecretApproval } from "../../models/secretApproval";
|
import { SecretApprovalPolicy } from "../../models/secretApprovalPolicy";
|
||||||
import { BadRequestError } from "../../utils/errors";
|
import { BadRequestError } from "../../utils/errors";
|
||||||
import * as reqValidator from "../../validation/secretApproval";
|
import * as reqValidator from "../../validation/secretApproval";
|
||||||
|
|
||||||
const ERR_SECRET_APPROVAL_NOT_FOUND = BadRequestError({ message: "secret approval not found" });
|
const ERR_SECRET_APPROVAL_NOT_FOUND = BadRequestError({ message: "secret approval not found" });
|
||||||
|
|
||||||
export const createSecretApprovalRule = async (req: Request, res: Response) => {
|
export const createSecretApprovalPolicy = async (req: Request, res: Response) => {
|
||||||
const {
|
const {
|
||||||
body: { approvals, secretPath, approvers, environment, workspaceId }
|
body: { approvals, secretPath, approvers, environment, workspaceId }
|
||||||
} = await validateRequest(reqValidator.CreateSecretApprovalRule, req);
|
} = await validateRequest(reqValidator.CreateSecretApprovalRule, req);
|
||||||
@@ -23,7 +23,7 @@ export const createSecretApprovalRule = async (req: Request, res: Response) => {
|
|||||||
ProjectPermissionSub.SecretApproval
|
ProjectPermissionSub.SecretApproval
|
||||||
);
|
);
|
||||||
|
|
||||||
const secretApproval = new SecretApproval({
|
const secretApproval = new SecretApprovalPolicy({
|
||||||
workspace: workspaceId,
|
workspace: workspaceId,
|
||||||
secretPath,
|
secretPath,
|
||||||
environment,
|
environment,
|
||||||
@@ -37,13 +37,13 @@ export const createSecretApprovalRule = async (req: Request, res: Response) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateSecretApprovalRule = async (req: Request, res: Response) => {
|
export const updateSecretApprovalPolicy = async (req: Request, res: Response) => {
|
||||||
const {
|
const {
|
||||||
body: { approvals, approvers, secretPath },
|
body: { approvals, approvers, secretPath },
|
||||||
params: { id }
|
params: { id }
|
||||||
} = await validateRequest(reqValidator.UpdateSecretApprovalRule, req);
|
} = await validateRequest(reqValidator.UpdateSecretApprovalRule, req);
|
||||||
|
|
||||||
const secretApproval = await SecretApproval.findById(id);
|
const secretApproval = await SecretApprovalPolicy.findById(id);
|
||||||
if (!secretApproval) throw ERR_SECRET_APPROVAL_NOT_FOUND;
|
if (!secretApproval) throw ERR_SECRET_APPROVAL_NOT_FOUND;
|
||||||
|
|
||||||
const { permission } = await getUserProjectPermissions(
|
const { permission } = await getUserProjectPermissions(
|
||||||
@@ -55,10 +55,10 @@ export const updateSecretApprovalRule = async (req: Request, res: Response) => {
|
|||||||
ProjectPermissionSub.SecretApproval
|
ProjectPermissionSub.SecretApproval
|
||||||
);
|
);
|
||||||
|
|
||||||
const updatedDoc = await SecretApproval.findByIdAndUpdate(id, {
|
const updatedDoc = await SecretApprovalPolicy.findByIdAndUpdate(id, {
|
||||||
approvals,
|
approvals,
|
||||||
approvers,
|
approvers,
|
||||||
$set: secretPath === "-" ? undefined : { secretPath }
|
...(secretPath === null ? { $unset: { secretPath: 1 } } : { secretPath })
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.send({
|
return res.send({
|
||||||
@@ -66,12 +66,12 @@ export const updateSecretApprovalRule = async (req: Request, res: Response) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const deleteSecretApprovalRule = async (req: Request, res: Response) => {
|
export const deleteSecretApprovalPolicy = async (req: Request, res: Response) => {
|
||||||
const {
|
const {
|
||||||
params: { id }
|
params: { id }
|
||||||
} = await validateRequest(reqValidator.DeleteSecretApprovalRule, req);
|
} = await validateRequest(reqValidator.DeleteSecretApprovalRule, req);
|
||||||
|
|
||||||
const secretApproval = await SecretApproval.findById(id);
|
const secretApproval = await SecretApprovalPolicy.findById(id);
|
||||||
if (!secretApproval) throw ERR_SECRET_APPROVAL_NOT_FOUND;
|
if (!secretApproval) throw ERR_SECRET_APPROVAL_NOT_FOUND;
|
||||||
|
|
||||||
const { permission } = await getUserProjectPermissions(
|
const { permission } = await getUserProjectPermissions(
|
||||||
@@ -83,14 +83,14 @@ export const deleteSecretApprovalRule = async (req: Request, res: Response) => {
|
|||||||
ProjectPermissionSub.SecretApproval
|
ProjectPermissionSub.SecretApproval
|
||||||
);
|
);
|
||||||
|
|
||||||
const deletedDoc = await SecretApproval.findByIdAndDelete(id);
|
const deletedDoc = await SecretApprovalPolicy.findByIdAndDelete(id);
|
||||||
|
|
||||||
return res.send({
|
return res.send({
|
||||||
approval: deletedDoc
|
approval: deletedDoc
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSecretApprovalRules = async (req: Request, res: Response) => {
|
export const getSecretApprovalPolicy = async (req: Request, res: Response) => {
|
||||||
const {
|
const {
|
||||||
query: { workspaceId }
|
query: { workspaceId }
|
||||||
} = await validateRequest(reqValidator.GetSecretApprovalRuleList, req);
|
} = await validateRequest(reqValidator.GetSecretApprovalRuleList, req);
|
||||||
@@ -101,7 +101,7 @@ export const getSecretApprovalRules = async (req: Request, res: Response) => {
|
|||||||
ProjectPermissionSub.SecretApproval
|
ProjectPermissionSub.SecretApproval
|
||||||
);
|
);
|
||||||
|
|
||||||
const doc = await SecretApproval.find({ workspace: workspaceId });
|
const doc = await SecretApprovalPolicy.find({ workspace: workspaceId });
|
||||||
|
|
||||||
return res.send({
|
return res.send({
|
||||||
approvals: doc
|
approvals: doc
|
||||||
@@ -38,7 +38,7 @@ import {
|
|||||||
membership as v1MembershipRouter,
|
membership as v1MembershipRouter,
|
||||||
organization as v1OrganizationRouter,
|
organization as v1OrganizationRouter,
|
||||||
password as v1PasswordRouter,
|
password as v1PasswordRouter,
|
||||||
secretApproval as v1SecretApproval,
|
secretApprovalPolicy as v1SecretApprovalPolicy,
|
||||||
secretImps as v1SecretImpsRouter,
|
secretImps as v1SecretImpsRouter,
|
||||||
secret as v1SecretRouter,
|
secret as v1SecretRouter,
|
||||||
secretsFolder as v1SecretsFolder,
|
secretsFolder as v1SecretsFolder,
|
||||||
@@ -177,7 +177,7 @@ const main = async () => {
|
|||||||
app.use("/api/v1/webhooks", v1WebhooksRouter);
|
app.use("/api/v1/webhooks", v1WebhooksRouter);
|
||||||
app.use("/api/v1/secret-imports", v1SecretImpsRouter);
|
app.use("/api/v1/secret-imports", v1SecretImpsRouter);
|
||||||
app.use("/api/v1/roles", v1RoleRouter);
|
app.use("/api/v1/roles", v1RoleRouter);
|
||||||
app.use("/api/v1/secret-approvals", v1SecretApproval);
|
app.use("/api/v1/secret-approvals", v1SecretApprovalPolicy);
|
||||||
|
|
||||||
// v2 routes (improvements)
|
// v2 routes (improvements)
|
||||||
app.use("/api/v2/signup", v2SignupRouter);
|
app.use("/api/v2/signup", v2SignupRouter);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Schema, Types, model } from "mongoose";
|
import { Schema, Types, model } from "mongoose";
|
||||||
|
|
||||||
export interface ISecretApproval {
|
export interface ISecretApprovalPolicy {
|
||||||
_id: Types.ObjectId;
|
_id: Types.ObjectId;
|
||||||
workspace: Types.ObjectId;
|
workspace: Types.ObjectId;
|
||||||
environment: string;
|
environment: string;
|
||||||
@@ -9,7 +9,7 @@ export interface ISecretApproval {
|
|||||||
approvals: number;
|
approvals: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const secretApprovalSchema = new Schema<ISecretApproval>(
|
const secretApprovalPolicySchema = new Schema<ISecretApprovalPolicy>(
|
||||||
{
|
{
|
||||||
workspace: {
|
workspace: {
|
||||||
type: Schema.Types.ObjectId,
|
type: Schema.Types.ObjectId,
|
||||||
@@ -41,4 +41,7 @@ const secretApprovalSchema = new Schema<ISecretApproval>(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const SecretApproval = model<ISecretApproval>("SecretApproval", secretApprovalSchema);
|
export const SecretApprovalPolicy = model<ISecretApprovalPolicy>(
|
||||||
|
"SecretApprovalPolicy",
|
||||||
|
secretApprovalPolicySchema
|
||||||
|
);
|
||||||
@@ -30,7 +30,7 @@ export interface ISecretApprovalRequest {
|
|||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const secretApprovalSchema = new Schema<ISecretApprovalRequest>(
|
const secretApprovalRequestSchema = new Schema<ISecretApprovalRequest>(
|
||||||
{
|
{
|
||||||
approvers: [
|
approvers: [
|
||||||
{
|
{
|
||||||
@@ -62,4 +62,7 @@ const secretApprovalSchema = new Schema<ISecretApprovalRequest>(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const SecretApproval = model<ISecretApprovalRequest>("SecretApproval", secretApprovalSchema);
|
export const SecretApprovalRequest = model<ISecretApprovalRequest>(
|
||||||
|
"SecretApprovalRequest",
|
||||||
|
secretApprovalRequestSchema
|
||||||
|
);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import integrationAuth from "./integrationAuth";
|
|||||||
import secretsFolder from "./secretsFolder";
|
import secretsFolder from "./secretsFolder";
|
||||||
import webhooks from "./webhook";
|
import webhooks from "./webhook";
|
||||||
import secretImps from "./secretImps";
|
import secretImps from "./secretImps";
|
||||||
import secretApproval from "./secretApproval";
|
import secretApprovalPolicy from "./secretApprovalPolicy";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
signup,
|
signup,
|
||||||
@@ -39,5 +39,5 @@ export {
|
|||||||
secretsFolder,
|
secretsFolder,
|
||||||
webhooks,
|
webhooks,
|
||||||
secretImps,
|
secretImps,
|
||||||
secretApproval
|
secretApprovalPolicy
|
||||||
};
|
};
|
||||||
|
|||||||
+5
-5
@@ -1,7 +1,7 @@
|
|||||||
import express from "express";
|
import express from "express";
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
import { requireAuth } from "../../middleware";
|
import { requireAuth } from "../../middleware";
|
||||||
import { secretApprovalController } from "../../controllers/v1";
|
import { secretApprovalPolicyController } from "../../controllers/v1";
|
||||||
import { AuthMode } from "../../variables";
|
import { AuthMode } from "../../variables";
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
@@ -9,7 +9,7 @@ router.get(
|
|||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT]
|
acceptedAuthModes: [AuthMode.JWT]
|
||||||
}),
|
}),
|
||||||
secretApprovalController.getSecretApprovalRules
|
secretApprovalPolicyController.getSecretApprovalPolicy
|
||||||
);
|
);
|
||||||
|
|
||||||
router.post(
|
router.post(
|
||||||
@@ -17,7 +17,7 @@ router.post(
|
|||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT]
|
acceptedAuthModes: [AuthMode.JWT]
|
||||||
}),
|
}),
|
||||||
secretApprovalController.createSecretApprovalRule
|
secretApprovalPolicyController.createSecretApprovalPolicy
|
||||||
);
|
);
|
||||||
|
|
||||||
router.patch(
|
router.patch(
|
||||||
@@ -25,7 +25,7 @@ router.patch(
|
|||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT]
|
acceptedAuthModes: [AuthMode.JWT]
|
||||||
}),
|
}),
|
||||||
secretApprovalController.updateSecretApprovalRule
|
secretApprovalPolicyController.updateSecretApprovalPolicy
|
||||||
);
|
);
|
||||||
|
|
||||||
router.delete(
|
router.delete(
|
||||||
@@ -33,7 +33,7 @@ router.delete(
|
|||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT]
|
acceptedAuthModes: [AuthMode.JWT]
|
||||||
}),
|
}),
|
||||||
secretApprovalController.deleteSecretApprovalRule
|
secretApprovalPolicyController.deleteSecretApprovalPolicy
|
||||||
);
|
);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
@@ -10,7 +10,7 @@ export const CreateSecretApprovalRule = z.object({
|
|||||||
body: z.object({
|
body: z.object({
|
||||||
workspaceId: z.string(),
|
workspaceId: z.string(),
|
||||||
environment: z.string(),
|
environment: z.string(),
|
||||||
secretPath: z.string().optional(),
|
secretPath: z.string().optional().nullable(),
|
||||||
approvers: z.string().array().optional(),
|
approvers: z.string().array().optional(),
|
||||||
approvals: z.number().min(1).default(1)
|
approvals: z.number().min(1).default(1)
|
||||||
})
|
})
|
||||||
@@ -23,7 +23,7 @@ export const UpdateSecretApprovalRule = z.object({
|
|||||||
body: z.object({
|
body: z.object({
|
||||||
approvers: z.string().array().optional(),
|
approvers: z.string().array().optional(),
|
||||||
approvals: z.number().min(1).optional(),
|
approvals: z.number().min(1).optional(),
|
||||||
secretPath: z.string().optional()
|
secretPath: z.string().optional().nullable()
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export type TSecretApprovalPolicy = {
|
|||||||
export type TCreateSecretPolicyDTO = {
|
export type TCreateSecretPolicyDTO = {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
secretPath?: string;
|
secretPath?: string | null;
|
||||||
approvers?: string[];
|
approvers?: string[];
|
||||||
approvals?: number;
|
approvals?: number;
|
||||||
};
|
};
|
||||||
@@ -18,7 +18,7 @@ export type TCreateSecretPolicyDTO = {
|
|||||||
export type TUpdateSecretPolicyDTO = {
|
export type TUpdateSecretPolicyDTO = {
|
||||||
id: string;
|
id: string;
|
||||||
approvers?: string[];
|
approvers?: string[];
|
||||||
secretPath?: string;
|
secretPath?: string | null;
|
||||||
approvals?: number;
|
approvals?: number;
|
||||||
// for invalidating list
|
// for invalidating list
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
|
|||||||
+8
-1
@@ -1,14 +1,16 @@
|
|||||||
import { faPlus } from "@fortawesome/free-solid-svg-icons";
|
import { faFileShield, faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
|
||||||
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
|
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
DeleteActionModal,
|
DeleteActionModal,
|
||||||
|
EmptyState,
|
||||||
Table,
|
Table,
|
||||||
TableContainer,
|
TableContainer,
|
||||||
TableSkeleton,
|
TableSkeleton,
|
||||||
TBody,
|
TBody,
|
||||||
|
Td,
|
||||||
Th,
|
Th,
|
||||||
THead,
|
THead,
|
||||||
Tr
|
Tr
|
||||||
@@ -96,6 +98,11 @@ export const SecretApprovalPolicyList = ({ workspaceId }: Props) => {
|
|||||||
{isPoliciesLoading && (
|
{isPoliciesLoading && (
|
||||||
<TableSkeleton columns={4} innerKey="secret-policies" className="bg-mineshaft-700" />
|
<TableSkeleton columns={4} innerKey="secret-policies" className="bg-mineshaft-700" />
|
||||||
)}
|
)}
|
||||||
|
{!isPoliciesLoading && !policies?.length && (
|
||||||
|
<Td colSpan={5}>
|
||||||
|
<EmptyState title="No policies found" icon={faFileShield} />
|
||||||
|
</Td>
|
||||||
|
)}
|
||||||
{policies?.map((policy) => (
|
{policies?.map((policy) => (
|
||||||
<SecretApprovalPolicyRow
|
<SecretApprovalPolicyRow
|
||||||
workspaceId={workspaceId}
|
workspaceId={workspaceId}
|
||||||
|
|||||||
+8
-4
@@ -35,7 +35,7 @@ type Props = {
|
|||||||
|
|
||||||
const formSchema = z.object({
|
const formSchema = z.object({
|
||||||
environment: z.string(),
|
environment: z.string(),
|
||||||
secretPath: z.string().optional(),
|
secretPath: z.string().optional().nullable(),
|
||||||
approvals: z.number().min(1),
|
approvals: z.number().min(1),
|
||||||
approvers: z.string().array().optional()
|
approvers: z.string().array().optional()
|
||||||
});
|
});
|
||||||
@@ -97,7 +97,7 @@ export const SecretPolicyForm = ({
|
|||||||
await updateSecretApprovalPolicy({
|
await updateSecretApprovalPolicy({
|
||||||
id: editValues?._id,
|
id: editValues?._id,
|
||||||
...data,
|
...data,
|
||||||
secretPath: data.secretPath ?? "-",
|
secretPath: data.secretPath || null,
|
||||||
workspaceId
|
workspaceId
|
||||||
});
|
});
|
||||||
createNotification({
|
createNotification({
|
||||||
@@ -159,7 +159,7 @@ export const SecretPolicyForm = ({
|
|||||||
name="secretPath"
|
name="secretPath"
|
||||||
render={({ field, fieldState: { error } }) => (
|
render={({ field, fieldState: { error } }) => (
|
||||||
<FormControl label="Secret Path" isError={Boolean(error)} errorText={error?.message}>
|
<FormControl label="Secret Path" isError={Boolean(error)} errorText={error?.message}>
|
||||||
<Input {...field} />
|
<Input {...field} value={field.value || ""} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
@@ -220,7 +220,11 @@ export const SecretPolicyForm = ({
|
|||||||
isError={Boolean(error)}
|
isError={Boolean(error)}
|
||||||
errorText={error?.message}
|
errorText={error?.message}
|
||||||
>
|
>
|
||||||
<Input {...field} type="number" />
|
<Input
|
||||||
|
{...field}
|
||||||
|
type="number"
|
||||||
|
onChange={(el) => field.onChange(parseInt(el.target.value, 10))}
|
||||||
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user