mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-05 03:26:27 +00:00
checkpoint
This commit is contained in:
@@ -0,0 +1,44 @@
|
|||||||
|
import { Schema, Types, model } from "mongoose";
|
||||||
|
|
||||||
|
export interface ISecretApproval {
|
||||||
|
_id: Types.ObjectId;
|
||||||
|
workspace: Types.ObjectId;
|
||||||
|
environment: string;
|
||||||
|
secretPath?: string;
|
||||||
|
approvers: Types.ObjectId[];
|
||||||
|
approvals: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const secretApprovalSchema = new Schema<ISecretApproval>(
|
||||||
|
{
|
||||||
|
workspace: {
|
||||||
|
type: Schema.Types.ObjectId,
|
||||||
|
ref: "Workspace",
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
approvers: [
|
||||||
|
{
|
||||||
|
// user associated with the personal secret
|
||||||
|
type: Schema.Types.ObjectId,
|
||||||
|
ref: "Membership"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
environment: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
secretPath: {
|
||||||
|
type: String,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
approvals: {
|
||||||
|
type: Number,
|
||||||
|
default: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timestamps: true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export const SecretApproval = model<ISecretApproval>("SecretApproval", secretApprovalSchema);
|
||||||
@@ -1,81 +1,65 @@
|
|||||||
import mongoose, { Schema, model } from "mongoose";
|
import { Schema, Types, model } from "mongoose";
|
||||||
import { ISecret, Secret } from "./secret";
|
import { ISecretVersion, SecretVersion } from "../ee/models/secretVersion";
|
||||||
|
|
||||||
interface ISecretApprovalRequest {
|
enum ApprovalStatus {
|
||||||
secret: mongoose.Types.ObjectId;
|
PENDING = "pending",
|
||||||
requestedChanges: ISecret;
|
APPROVED = "approved",
|
||||||
requestedBy: mongoose.Types.ObjectId;
|
REJECTED = "rejected"
|
||||||
approvers: IApprover[];
|
|
||||||
status: ApprovalStatus;
|
|
||||||
timestamp: Date;
|
|
||||||
requestType: RequestType;
|
|
||||||
requestId: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IApprover {
|
enum CommitType {
|
||||||
userId: mongoose.Types.ObjectId;
|
DELETE = "delete",
|
||||||
status: ApprovalStatus;
|
UPDATE = "update",
|
||||||
|
CREATE = "create"
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ApprovalStatus {
|
export interface ISecretApprovalRequest {
|
||||||
PENDING = "pending",
|
_id: Types.ObjectId;
|
||||||
APPROVED = "approved",
|
committer: Types.ObjectId;
|
||||||
REJECTED = "rejected"
|
approvers: {
|
||||||
|
member: Types.ObjectId;
|
||||||
|
status: ApprovalStatus;
|
||||||
|
}[];
|
||||||
|
approvals: number;
|
||||||
|
hasMerged: boolean;
|
||||||
|
status: ApprovalStatus;
|
||||||
|
commits: {
|
||||||
|
secretVersion: Types.ObjectId;
|
||||||
|
newVersion: ISecretVersion;
|
||||||
|
op: CommitType;
|
||||||
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum RequestType {
|
const secretApprovalSchema = new Schema<ISecretApprovalRequest>(
|
||||||
UPDATE = "update",
|
{
|
||||||
DELETE = "delete",
|
approvers: [
|
||||||
CREATE = "create"
|
{
|
||||||
}
|
member: {
|
||||||
|
// user associated with the personal secret
|
||||||
const approverSchema = new mongoose.Schema({
|
type: Schema.Types.ObjectId,
|
||||||
user: {
|
ref: "Membership"
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
},
|
||||||
ref: "User",
|
status: { type: String, enum: ApprovalStatus, default: ApprovalStatus.PENDING }
|
||||||
required: true,
|
}
|
||||||
},
|
],
|
||||||
status: {
|
approvals: {
|
||||||
type: String,
|
type: Number,
|
||||||
enum: [ApprovalStatus],
|
required: true
|
||||||
default: ApprovalStatus.PENDING,
|
},
|
||||||
},
|
hasMerged: { type: Boolean, default: false },
|
||||||
});
|
status: { type: String, enum: ApprovalStatus, default: ApprovalStatus.PENDING },
|
||||||
|
committer: { type: Schema.Types.ObjectId, ref: "Membership" },
|
||||||
const secretApprovalRequestSchema = new Schema<ISecretApprovalRequest>(
|
commits: [
|
||||||
{
|
{
|
||||||
secret: {
|
secretVersion: { type: Types.ObjectId, ref: "SecretVersion" },
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
newVersion: SecretVersion,
|
||||||
ref: "Secret",
|
op: { type: String, enum: [CommitType], required: true }
|
||||||
},
|
}
|
||||||
requestedChanges: Secret,
|
]
|
||||||
requestedBy: {
|
},
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
{
|
||||||
ref: "User",
|
timestamps: true
|
||||||
},
|
}
|
||||||
approvers: [approverSchema],
|
|
||||||
status: {
|
|
||||||
type: String,
|
|
||||||
enum: ApprovalStatus,
|
|
||||||
default: ApprovalStatus.PENDING,
|
|
||||||
},
|
|
||||||
timestamp: {
|
|
||||||
type: Date,
|
|
||||||
default: Date.now,
|
|
||||||
},
|
|
||||||
requestType: {
|
|
||||||
type: String,
|
|
||||||
enum: RequestType,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
requestId: {
|
|
||||||
type: String,
|
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timestamps: true,
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
export const SecretApprovalRequest = model<ISecretApprovalRequest>("SecretApprovalRequest", secretApprovalRequestSchema);
|
export const SecretApproval = model<ISecretApprovalRequest>("SecretApproval", secretApprovalSchema);
|
||||||
|
|||||||
@@ -107,6 +107,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"approval": {
|
||||||
|
"title": "Admin Panel",
|
||||||
|
"og-title": "Manage your secret change management",
|
||||||
|
"og-description": "Infisical a simple end-to-end encrypted platform that enables teams to sync and manage their .env files."
|
||||||
|
},
|
||||||
"integrations": {
|
"integrations": {
|
||||||
"title": "Project Integrations",
|
"title": "Project Integrations",
|
||||||
"description": "Manage your integrations of Infisical with third-party services.",
|
"description": "Manage your integrations of Infisical with third-party services.",
|
||||||
|
|||||||
@@ -475,6 +475,18 @@ export const AppLayout = ({ children }: LayoutProps) => {
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
|
<Link href={`/project/${currentWorkspace?._id}/approval`} passHref>
|
||||||
|
<a>
|
||||||
|
<MenuItem
|
||||||
|
isSelected={
|
||||||
|
router.asPath === `/project/${currentWorkspace?._id}/allowlist`
|
||||||
|
}
|
||||||
|
icon="system-outline-126-verified"
|
||||||
|
>
|
||||||
|
Secret Change Management
|
||||||
|
</MenuItem>
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
<Link href={`/project/${currentWorkspace?._id}/allowlist`} passHref>
|
<Link href={`/project/${currentWorkspace?._id}/allowlist`} passHref>
|
||||||
<a>
|
<a>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import Head from "next/head";
|
||||||
|
|
||||||
|
import { SecretApprovalListPage } from "@app/views/SecretApproval/SecretApprovalListPage";
|
||||||
|
|
||||||
|
const SecretApproval = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Head>
|
||||||
|
<title>{t("common.head-title", { title: t("approval.title") })}</title>
|
||||||
|
<link rel="icon" href="/infisical.ico" />
|
||||||
|
<meta property="og:image" content="/images/message.png" />
|
||||||
|
<meta property="og:title" content={String(t("approval.og-title"))} />
|
||||||
|
<meta name="og:description" content={String(t("approval.og-description"))} />
|
||||||
|
</Head>
|
||||||
|
<div className="h-full">
|
||||||
|
<SecretApprovalListPage />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SecretApproval;
|
||||||
|
|
||||||
|
SecretApproval.requireAuth = true;
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import { faCheck, faCodeBranch, faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
|
||||||
|
import { Button, Table, TableContainer, TBody, Td, Th, THead, Tr } from "@app/components/v2";
|
||||||
|
|
||||||
|
export const SecretApprovalListPage = () => {
|
||||||
|
return (
|
||||||
|
<div className="container mx-auto bg-bunker-800 text-white w-full h-full">
|
||||||
|
<div className="my-6">
|
||||||
|
<p className="text-3xl font-semibold text-gray-200">Admin Panels</p>
|
||||||
|
</div>
|
||||||
|
<div className="rounded-md bg-mineshaft-800 text-gray-300">
|
||||||
|
<div className="p-4 px-8 flex items-center space-x-8">
|
||||||
|
<div>
|
||||||
|
<FontAwesomeIcon icon={faCodeBranch} className="mr-2" />
|
||||||
|
27 Open
|
||||||
|
</div>
|
||||||
|
<div className="text-gray-500">
|
||||||
|
<FontAwesomeIcon icon={faCheck} className="mr-2" />
|
||||||
|
27 Closed
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col border-t border-mineshaft-600">
|
||||||
|
<div className="flex flex-col px-8 py-4">
|
||||||
|
<div className="mb-1">
|
||||||
|
<FontAwesomeIcon icon={faCodeBranch} className="mr-2" />2 secrets added and 1 deleted
|
||||||
|
</div>
|
||||||
|
<span className="text-xs text-gray-500">
|
||||||
|
Opened 2 hours ago by akhilmhdh - Review required
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="my-4 p-4 rounded-md bg-bunker-600 text-gray-300">
|
||||||
|
<div className="mb-4 text-lg">
|
||||||
|
Request for <span className="text-yellow-600">secret change</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<TableContainer>
|
||||||
|
<Table>
|
||||||
|
<THead>
|
||||||
|
<Tr>
|
||||||
|
<Th className="min-table-row">Secret</Th>
|
||||||
|
<Th>Value</Th>
|
||||||
|
<Th className="min-table-row">Comment</Th>
|
||||||
|
<Th className="min-table-row">Tags</Th>
|
||||||
|
</Tr>
|
||||||
|
</THead>
|
||||||
|
<TBody>
|
||||||
|
<Tr>
|
||||||
|
<Td>TWILIO_SECRET_TOKEN</Td>
|
||||||
|
<Td>value</Td>
|
||||||
|
<Td>Some values</Td>
|
||||||
|
<Td>-</Td>
|
||||||
|
</Tr>
|
||||||
|
</TBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center mt-8 space-x-6">
|
||||||
|
<Button leftIcon={<FontAwesomeIcon icon={faCheck} />}>Approve</Button>
|
||||||
|
<Button
|
||||||
|
variant="outline_bg"
|
||||||
|
leftIcon={<FontAwesomeIcon icon={faXmark} />}
|
||||||
|
colorSchema="danger"
|
||||||
|
>
|
||||||
|
Deny
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { SecretApprovalListPage } from "./SecretApprovalListPage";
|
||||||
Reference in New Issue
Block a user