mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-04 07:26:11 +00:00
requested changes
This commit is contained in:
@@ -44,7 +44,6 @@ export const registerSecretRequestsRouter = async (server: FastifyZodProvider) =
|
|||||||
const secretRequest = await req.server.services.secretSharing.getSecretRequestById({
|
const secretRequest = await req.server.services.secretSharing.getSecretRequestById({
|
||||||
id: req.params.id,
|
id: req.params.id,
|
||||||
actorOrgId: req.permission?.orgId,
|
actorOrgId: req.permission?.orgId,
|
||||||
orgId: req.permission?.orgId,
|
|
||||||
actor: req.permission?.type,
|
actor: req.permission?.type,
|
||||||
actorId: req.permission?.id,
|
actorId: req.permission?.id,
|
||||||
actorAuthMethod: req.permission?.authMethod
|
actorAuthMethod: req.permission?.authMethod
|
||||||
@@ -82,7 +81,6 @@ export const registerSecretRequestsRouter = async (server: FastifyZodProvider) =
|
|||||||
const secretRequest = await req.server.services.secretSharing.setSecretRequestValue({
|
const secretRequest = await req.server.services.secretSharing.setSecretRequestValue({
|
||||||
id: req.params.id,
|
id: req.params.id,
|
||||||
actorOrgId: req.permission?.orgId,
|
actorOrgId: req.permission?.orgId,
|
||||||
orgId: req.permission?.orgId,
|
|
||||||
actor: req.permission?.type,
|
actor: req.permission?.type,
|
||||||
actorId: req.permission?.id,
|
actorId: req.permission?.id,
|
||||||
actorAuthMethod: req.permission?.authMethod,
|
actorAuthMethod: req.permission?.authMethod,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Knex } from "knex";
|
|||||||
|
|
||||||
import { TDbClient } from "@app/db";
|
import { TDbClient } from "@app/db";
|
||||||
import { TableName, TSecretSharing } from "@app/db/schemas";
|
import { TableName, TSecretSharing } from "@app/db/schemas";
|
||||||
import { DatabaseError } from "@app/lib/errors";
|
import { DatabaseError, NotFoundError } from "@app/lib/errors";
|
||||||
import { ormify, selectAllTableCols } from "@app/lib/knex";
|
import { ormify, selectAllTableCols } from "@app/lib/knex";
|
||||||
import { logger } from "@app/lib/logger";
|
import { logger } from "@app/lib/logger";
|
||||||
import { QueueName } from "@app/queue";
|
import { QueueName } from "@app/queue";
|
||||||
@@ -32,10 +32,8 @@ export const secretSharingDALFactory = (db: TDbClient) => {
|
|||||||
.first();
|
.first();
|
||||||
|
|
||||||
if (!secretRequest) {
|
if (!secretRequest) {
|
||||||
throw new DatabaseError({
|
throw new NotFoundError({
|
||||||
error: new Error("Get Secret Request By Id, Not found"),
|
message: `Secret request with ID '${id}' not found`
|
||||||
message: "Get Secret Request By Id, Not found",
|
|
||||||
name: "GetSecretRequestById"
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -176,7 +176,6 @@ export const secretSharingServiceFactory = ({
|
|||||||
id,
|
id,
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
orgId,
|
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId
|
actorOrgId
|
||||||
}: TGetSecretRequestByIdDTO) => {
|
}: TGetSecretRequestByIdDTO) => {
|
||||||
@@ -187,22 +186,22 @@ export const secretSharingServiceFactory = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (secretRequest.accessType === SecretSharingAccessType.Organization) {
|
if (secretRequest.accessType === SecretSharingAccessType.Organization) {
|
||||||
if (orgId === undefined) {
|
if (!secretRequest.orgId) {
|
||||||
|
throw new BadRequestError({ message: "No organization ID present on secret request" });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!actorOrgId) {
|
||||||
throw new UnauthorizedError();
|
throw new UnauthorizedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission(
|
const { permission } = await permissionService.getOrgPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
orgId,
|
secretRequest.orgId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId
|
actorOrgId
|
||||||
);
|
);
|
||||||
if (!permission) throw new ForbiddenRequestError({ name: "User is not a part of the specified organization" });
|
if (!permission) throw new ForbiddenRequestError({ name: "User is not a part of the specified organization" });
|
||||||
|
|
||||||
if (secretRequest.orgId !== orgId) {
|
|
||||||
throw new ForbiddenRequestError({ name: "User does not have permission to access this secret request" });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (secretRequest.expiresAt && secretRequest.expiresAt < new Date()) {
|
if (secretRequest.expiresAt && secretRequest.expiresAt < new Date()) {
|
||||||
@@ -221,7 +220,6 @@ export const secretSharingServiceFactory = ({
|
|||||||
id,
|
id,
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
orgId,
|
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId,
|
||||||
secretValue
|
secretValue
|
||||||
@@ -237,23 +235,23 @@ export const secretSharingServiceFactory = ({
|
|||||||
let respondentUsername: string | undefined;
|
let respondentUsername: string | undefined;
|
||||||
|
|
||||||
if (secretRequest.accessType === SecretSharingAccessType.Organization) {
|
if (secretRequest.accessType === SecretSharingAccessType.Organization) {
|
||||||
|
if (!secretRequest.orgId) {
|
||||||
|
throw new BadRequestError({ message: "No organization ID present on secret request" });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!actorOrgId) {
|
||||||
|
throw new UnauthorizedError();
|
||||||
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission(
|
const { permission } = await permissionService.getOrgPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
orgId,
|
secretRequest.orgId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId
|
actorOrgId
|
||||||
);
|
);
|
||||||
if (!permission) throw new ForbiddenRequestError({ name: "User is not a part of the specified organization" });
|
if (!permission) throw new ForbiddenRequestError({ name: "User is not a part of the specified organization" });
|
||||||
|
|
||||||
if (!orgId) {
|
|
||||||
throw new UnauthorizedError();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (secretRequest.orgId !== orgId) {
|
|
||||||
throw new ForbiddenRequestError({ name: "User does not have permission to access this secret request" });
|
|
||||||
}
|
|
||||||
|
|
||||||
const user = await userDAL.findById(actorId);
|
const user = await userDAL.findById(actorId);
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
@@ -478,8 +476,14 @@ export const secretSharingServiceFactory = ({
|
|||||||
? await secretSharingDAL.findOne({ id: sharedSecretId, type: deleteSharedSecretInput.type })
|
? await secretSharingDAL.findOne({ id: sharedSecretId, type: deleteSharedSecretInput.type })
|
||||||
: await secretSharingDAL.findOne({ identifier: sharedSecretId, type: deleteSharedSecretInput.type });
|
: await secretSharingDAL.findOne({ identifier: sharedSecretId, type: deleteSharedSecretInput.type });
|
||||||
|
|
||||||
if (sharedSecret.orgId && sharedSecret.orgId !== orgId)
|
if (sharedSecret.userId !== actorId) {
|
||||||
|
throw new ForbiddenRequestError({
|
||||||
|
message: "User does not have permission to delete shared secret"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (sharedSecret.orgId && sharedSecret.orgId !== orgId) {
|
||||||
throw new ForbiddenRequestError({ message: "User does not have permission to delete shared secret" });
|
throw new ForbiddenRequestError({ message: "User does not have permission to delete shared secret" });
|
||||||
|
}
|
||||||
|
|
||||||
const deletedSharedSecret = await secretSharingDAL.deleteById(sharedSecretId);
|
const deletedSharedSecret = await secretSharingDAL.deleteById(sharedSecretId);
|
||||||
|
|
||||||
|
|||||||
@@ -57,12 +57,12 @@ export type TRevealSecretRequestValueDTO = {
|
|||||||
|
|
||||||
export type TGetSecretRequestByIdDTO = {
|
export type TGetSecretRequestByIdDTO = {
|
||||||
id: string;
|
id: string;
|
||||||
} & TOrgPermission;
|
} & Omit<TOrgPermission, "orgId">;
|
||||||
|
|
||||||
export type TSetSecretRequestValueDTO = {
|
export type TSetSecretRequestValueDTO = {
|
||||||
id: string;
|
id: string;
|
||||||
secretValue: string;
|
secretValue: string;
|
||||||
} & TOrgPermission;
|
} & Omit<TOrgPermission, "orgId">;
|
||||||
|
|
||||||
export type TDeleteSharedSecretDTO = {
|
export type TDeleteSharedSecretDTO = {
|
||||||
sharedSecretId: string;
|
sharedSecretId: string;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { apiRequest } from "@app/config/request";
|
|||||||
import { secretSharingKeys } from "./queries";
|
import { secretSharingKeys } from "./queries";
|
||||||
import {
|
import {
|
||||||
TCreatedSharedSecret,
|
TCreatedSharedSecret,
|
||||||
TCreateSecretRequestRequest,
|
TCreateSecretRequestRequestDTO,
|
||||||
TCreateSharedSecretRequest,
|
TCreateSharedSecretRequest,
|
||||||
TDeleteSecretRequestDTO,
|
TDeleteSecretRequestDTO,
|
||||||
TDeleteSharedSecretRequestDTO,
|
TDeleteSharedSecretRequestDTO,
|
||||||
@@ -48,7 +48,7 @@ export const useCreatePublicSharedSecret = () => {
|
|||||||
export const useCreateSecretRequest = () => {
|
export const useCreateSecretRequest = () => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async (inputData: TCreateSecretRequestRequest) => {
|
mutationFn: async (inputData: TCreateSecretRequestRequestDTO) => {
|
||||||
const { data } = await apiRequest.post<TCreatedSharedSecret>(
|
const { data } = await apiRequest.post<TCreatedSharedSecret>(
|
||||||
"/api/v1/secret-sharing/requests",
|
"/api/v1/secret-sharing/requests",
|
||||||
inputData
|
inputData
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export type TSharedSecret = {
|
|||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
name: string | null;
|
name: string | null;
|
||||||
lastViewedAt?: Date;
|
lastViewedAt?: Date;
|
||||||
|
accessType: SecretSharingAccessType;
|
||||||
expiresAt: Date;
|
expiresAt: Date;
|
||||||
expiresAfterViews: number | null;
|
expiresAfterViews: number | null;
|
||||||
encryptedValue: string;
|
encryptedValue: string;
|
||||||
@@ -33,7 +34,7 @@ export type TCreateSharedSecretRequest = {
|
|||||||
accessType?: SecretSharingAccessType;
|
accessType?: SecretSharingAccessType;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TCreateSecretRequestRequest = {
|
export type TCreateSecretRequestRequestDTO = {
|
||||||
name?: string;
|
name?: string;
|
||||||
accessType?: SecretSharingAccessType;
|
accessType?: SecretSharingAccessType;
|
||||||
expiresAt: Date;
|
expiresAt: Date;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { useNavigate, useSearch } from "@tanstack/react-router";
|
|||||||
|
|
||||||
import { Badge, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
|
import { Badge, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
|
||||||
import { ROUTE_PATHS } from "@app/const/routes";
|
import { ROUTE_PATHS } from "@app/const/routes";
|
||||||
import { usePopUp } from "@app/hooks";
|
|
||||||
|
|
||||||
import { RequestSecretTab } from "./components/RequestSecret/RequestSecretTab";
|
import { RequestSecretTab } from "./components/RequestSecret/RequestSecretTab";
|
||||||
import { ShareSecretTab } from "./components/ShareSecret/ShareSecretTab";
|
import { ShareSecretTab } from "./components/ShareSecret/ShareSecretTab";
|
||||||
@@ -14,14 +13,6 @@ enum SecretSharingPageTabs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const ShareSecretSection = () => {
|
export const ShareSecretSection = () => {
|
||||||
const { popUp, handlePopUpToggle, handlePopUpClose, handlePopUpOpen } = usePopUp([
|
|
||||||
"createSharedSecret",
|
|
||||||
"deleteSharedSecretConfirmation",
|
|
||||||
"createSecretRequest",
|
|
||||||
"deleteSecretRequestConfirmation",
|
|
||||||
"revealSecretRequestValue"
|
|
||||||
] as const);
|
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const { selectedTab } = useSearch({
|
const { selectedTab } = useSearch({
|
||||||
@@ -54,20 +45,10 @@ export const ShareSecretSection = () => {
|
|||||||
</Tab>
|
</Tab>
|
||||||
</TabList>
|
</TabList>
|
||||||
<TabPanel value={SecretSharingPageTabs.ShareSecret}>
|
<TabPanel value={SecretSharingPageTabs.ShareSecret}>
|
||||||
<ShareSecretTab
|
<ShareSecretTab />
|
||||||
handlePopUpOpen={handlePopUpOpen}
|
|
||||||
popUp={popUp}
|
|
||||||
handlePopUpToggle={handlePopUpToggle}
|
|
||||||
handlePopUpClose={handlePopUpClose}
|
|
||||||
/>
|
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel value={SecretSharingPageTabs.RequestSecret}>
|
<TabPanel value={SecretSharingPageTabs.RequestSecret}>
|
||||||
<RequestSecretTab
|
<RequestSecretTab />
|
||||||
handlePopUpOpen={handlePopUpOpen}
|
|
||||||
popUp={popUp}
|
|
||||||
handlePopUpToggle={handlePopUpToggle}
|
|
||||||
handlePopUpClose={handlePopUpClose}
|
|
||||||
/>
|
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+6
-1
@@ -98,7 +98,12 @@ export const RequestSecretForm = () => {
|
|||||||
name="expiresIn"
|
name="expiresIn"
|
||||||
defaultValue="3600000"
|
defaultValue="3600000"
|
||||||
render={({ field: { onChange, ...field }, fieldState: { error } }) => (
|
render={({ field: { onChange, ...field }, fieldState: { error } }) => (
|
||||||
<FormControl label="Expires In" errorText={error?.message} isError={Boolean(error)}>
|
<FormControl
|
||||||
|
label="Expires In"
|
||||||
|
errorText={error?.message}
|
||||||
|
tooltipText="Select for how long someone is able to input the secret. If a secret is shared with you in time, it will remain available to you, even after the expiration."
|
||||||
|
isError={Boolean(error)}
|
||||||
|
>
|
||||||
<Select
|
<Select
|
||||||
defaultValue={field.value}
|
defaultValue={field.value}
|
||||||
{...field}
|
{...field}
|
||||||
|
|||||||
+8
-28
@@ -4,41 +4,21 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
import { Button, DeleteActionModal } from "@app/components/v2";
|
import { Button, DeleteActionModal } from "@app/components/v2";
|
||||||
import { useDeleteSecretRequest } from "@app/hooks/api";
|
import { useDeleteSecretRequest } from "@app/hooks/api";
|
||||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
import { usePopUp } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
import { AddSecretRequestModal } from "./AddSecretRequestModal";
|
import { AddSecretRequestModal } from "./AddSecretRequestModal";
|
||||||
import { RequestedSecretsTable } from "./RequestedSecretsTable";
|
import { RequestedSecretsTable } from "./RequestedSecretsTable";
|
||||||
import { RevealSecretValueModal } from "./RevealSecretValueModal";
|
import { RevealSecretValueModal } from "./RevealSecretValueModal";
|
||||||
|
|
||||||
type Props = {
|
|
||||||
handlePopUpOpen: (
|
|
||||||
popUpName: keyof UsePopUpState<
|
|
||||||
["createSecretRequest", "deleteSecretRequestConfirmation", "revealSecretRequestValue"]
|
|
||||||
>,
|
|
||||||
data?: any
|
|
||||||
) => void;
|
|
||||||
popUp: UsePopUpState<
|
|
||||||
["createSecretRequest", "deleteSecretRequestConfirmation", "revealSecretRequestValue"]
|
|
||||||
>;
|
|
||||||
handlePopUpToggle: (
|
|
||||||
popUpName: keyof UsePopUpState<
|
|
||||||
["createSecretRequest", "deleteSecretRequestConfirmation", "revealSecretRequestValue"]
|
|
||||||
>,
|
|
||||||
state?: boolean
|
|
||||||
) => void;
|
|
||||||
handlePopUpClose: (
|
|
||||||
popUpName: keyof UsePopUpState<["deleteSecretRequestConfirmation", "revealSecretRequestValue"]>
|
|
||||||
) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
type DeleteModalData = { name: string; id: string };
|
type DeleteModalData = { name: string; id: string };
|
||||||
|
|
||||||
export const RequestSecretTab = ({
|
export const RequestSecretTab = () => {
|
||||||
handlePopUpOpen,
|
const { popUp, handlePopUpToggle, handlePopUpClose, handlePopUpOpen } = usePopUp([
|
||||||
popUp,
|
"createSecretRequest",
|
||||||
handlePopUpToggle,
|
"deleteSecretRequestConfirmation",
|
||||||
handlePopUpClose
|
"revealSecretRequestValue"
|
||||||
}: Props) => {
|
] as const);
|
||||||
|
|
||||||
const { mutateAsync: deleteSecretRequest } = useDeleteSecretRequest();
|
const { mutateAsync: deleteSecretRequest } = useDeleteSecretRequest();
|
||||||
|
|
||||||
const onDeleteApproved = async () => {
|
const onDeleteApproved = async () => {
|
||||||
|
|||||||
+44
-21
@@ -4,7 +4,11 @@ import { format } from "date-fns";
|
|||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
import { Badge, IconButton, Td, Tooltip, Tr } from "@app/components/v2";
|
import { Badge, IconButton, Td, Tooltip, Tr } from "@app/components/v2";
|
||||||
import { TSharedSecret, useRevealSecretRequestValue } from "@app/hooks/api/secretSharing";
|
import {
|
||||||
|
SecretSharingAccessType,
|
||||||
|
TSharedSecret,
|
||||||
|
useRevealSecretRequestValue
|
||||||
|
} from "@app/hooks/api/secretSharing";
|
||||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
export const RequestedSecretsRow = ({
|
export const RequestedSecretsRow = ({
|
||||||
@@ -36,6 +40,23 @@ export const RequestedSecretsRow = ({
|
|||||||
</Badge>
|
</Badge>
|
||||||
)}
|
)}
|
||||||
</Td>
|
</Td>
|
||||||
|
<Td>
|
||||||
|
<Badge variant="primary">
|
||||||
|
<Tooltip
|
||||||
|
content={
|
||||||
|
row.accessType === SecretSharingAccessType.Anyone
|
||||||
|
? "Anyone can input the secret."
|
||||||
|
: "Only members of the organization can input the secret."
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
{row.accessType === SecretSharingAccessType.Anyone
|
||||||
|
? "Anyone"
|
||||||
|
: "Organization Members"}
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
</Badge>
|
||||||
|
</Td>
|
||||||
<Td>{`${format(new Date(row.createdAt), "yyyy-MM-dd - HH:mm a")}`}</Td>
|
<Td>{`${format(new Date(row.createdAt), "yyyy-MM-dd - HH:mm a")}`}</Td>
|
||||||
<Td>{row.expiresAt ? format(new Date(row.expiresAt), "yyyy-MM-dd - HH:mm a") : "-"}</Td>
|
<Td>{row.expiresAt ? format(new Date(row.expiresAt), "yyyy-MM-dd - HH:mm a") : "-"}</Td>
|
||||||
<Td>
|
<Td>
|
||||||
@@ -43,7 +64,7 @@ export const RequestedSecretsRow = ({
|
|||||||
<Tooltip
|
<Tooltip
|
||||||
content={
|
content={
|
||||||
row.encryptedSecret
|
row.encryptedSecret
|
||||||
? "Reveal shared secret"
|
? "Reveal secret"
|
||||||
: "Secret value must be provided before it can be viewed."
|
: "Secret value must be provided before it can be viewed."
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -72,28 +93,30 @@ export const RequestedSecretsRow = ({
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<IconButton
|
<Tooltip content="Copy link">
|
||||||
isDisabled={Boolean(row.encryptedSecret) || isExpired}
|
<IconButton
|
||||||
className={Boolean(row.encryptedSecret) || isExpired ? "opacity-50" : ""}
|
isDisabled={Boolean(row.encryptedSecret) || isExpired}
|
||||||
onClick={async (e) => {
|
className={Boolean(row.encryptedSecret) || isExpired ? "opacity-50" : ""}
|
||||||
e.stopPropagation();
|
onClick={async (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
navigator.clipboard.writeText(
|
navigator.clipboard.writeText(
|
||||||
`${window.location.origin}/secret-request/secret/${row.id}`
|
`${window.location.origin}/secret-request/secret/${row.id}`
|
||||||
);
|
);
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: "Shared secret link copied to clipboard.",
|
text: "Shared secret link copied to clipboard.",
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
variant="plain"
|
variant="plain"
|
||||||
ariaLabel="copy link"
|
ariaLabel="copy link"
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faCopy} />
|
<FontAwesomeIcon icon={faCopy} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
<Tooltip content="Delete Secret Request">
|
<Tooltip content="Delete">
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|||||||
+2
-1
@@ -38,6 +38,7 @@ export const RequestedSecretsTable = ({ handlePopUpOpen }: Props) => {
|
|||||||
<Tr>
|
<Tr>
|
||||||
<Th>Name</Th>
|
<Th>Name</Th>
|
||||||
<Th>Status</Th>
|
<Th>Status</Th>
|
||||||
|
<Th>Access Type</Th>
|
||||||
<Th>Created At</Th>
|
<Th>Created At</Th>
|
||||||
<Th>Valid Until</Th>
|
<Th>Valid Until</Th>
|
||||||
<Th aria-label="button" className="w-5" />
|
<Th aria-label="button" className="w-5" />
|
||||||
@@ -64,7 +65,7 @@ export const RequestedSecretsTable = ({ handlePopUpOpen }: Props) => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{!isPending && !data?.secrets?.length && (
|
{!isPending && !data?.secrets?.length && (
|
||||||
<EmptyState title="No secrets shared yet" icon={faKey} />
|
<EmptyState title="No secrets requested yet" icon={faKey} />
|
||||||
)}
|
)}
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
+2
-2
@@ -27,7 +27,7 @@ const Content = ({ secretValue, secretRequestName }: ContentProps) => {
|
|||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="mb-8 flex items-center justify-between rounded-md bg-white/[0.07] p-2 text-base text-gray-400">
|
<div className="mb-8 flex items-center justify-between rounded-md bg-mineshaft-700 p-2 text-base text-gray-400">
|
||||||
<p className="mr-4 break-all">{secretValue}</p>
|
<p className="mr-4 break-all">{secretValue}</p>
|
||||||
<Tooltip content="Click to copy">
|
<Tooltip content="Click to copy">
|
||||||
<IconButton
|
<IconButton
|
||||||
@@ -46,7 +46,7 @@ const Content = ({ secretValue, secretRequestName }: ContentProps) => {
|
|||||||
|
|
||||||
<div className="mt-8 flex w-full items-center justify-between gap-2">
|
<div className="mt-8 flex w-full items-center justify-between gap-2">
|
||||||
<ModalClose asChild>
|
<ModalClose asChild>
|
||||||
<Button colorSchema="primary">Close</Button>
|
<Button colorSchema="secondary">Close</Button>
|
||||||
</ModalClose>
|
</ModalClose>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
+7
-20
@@ -4,32 +4,19 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
import { Button, DeleteActionModal } from "@app/components/v2";
|
import { Button, DeleteActionModal } from "@app/components/v2";
|
||||||
import { useDeleteSharedSecret } from "@app/hooks/api";
|
import { useDeleteSharedSecret } from "@app/hooks/api";
|
||||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
import { usePopUp } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
import { AddShareSecretModal } from "./AddShareSecretModal";
|
import { AddShareSecretModal } from "./AddShareSecretModal";
|
||||||
import { ShareSecretsTable } from "./ShareSecretsTable";
|
import { ShareSecretsTable } from "./ShareSecretsTable";
|
||||||
|
|
||||||
type Props = {
|
|
||||||
handlePopUpOpen: (
|
|
||||||
popUpName: keyof UsePopUpState<["createSharedSecret", "deleteSharedSecretConfirmation"]>,
|
|
||||||
data?: any
|
|
||||||
) => void;
|
|
||||||
popUp: UsePopUpState<["createSharedSecret", "deleteSharedSecretConfirmation"]>;
|
|
||||||
handlePopUpToggle: (
|
|
||||||
popUpName: keyof UsePopUpState<["createSharedSecret", "deleteSharedSecretConfirmation"]>,
|
|
||||||
state?: boolean
|
|
||||||
) => void;
|
|
||||||
handlePopUpClose: (popUpName: keyof UsePopUpState<["deleteSharedSecretConfirmation"]>) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
type DeleteModalData = { name: string; id: string };
|
type DeleteModalData = { name: string; id: string };
|
||||||
|
|
||||||
export const ShareSecretTab = ({
|
export const ShareSecretTab = () => {
|
||||||
handlePopUpOpen,
|
const { popUp, handlePopUpToggle, handlePopUpClose, handlePopUpOpen } = usePopUp([
|
||||||
popUp,
|
"createSharedSecret",
|
||||||
handlePopUpToggle,
|
"deleteSharedSecretConfirmation"
|
||||||
handlePopUpClose
|
] as const);
|
||||||
}: Props) => {
|
|
||||||
const deleteSecretShare = useDeleteSharedSecret();
|
const deleteSecretShare = useDeleteSharedSecret();
|
||||||
|
|
||||||
const onDeleteApproved = async () => {
|
const onDeleteApproved = async () => {
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ export const SecretRequestErrorContainer = () => {
|
|||||||
<div className="rounded-lg border border-mineshaft-600 bg-mineshaft-800 p-8">
|
<div className="rounded-lg border border-mineshaft-600 bg-mineshaft-800 p-8">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<FontAwesomeIcon icon={faKey} size="2x" />
|
<FontAwesomeIcon icon={faKey} size="2x" />
|
||||||
<p className="mt-4">The secret request you are looking is missing or has expired.</p>
|
<p className="mt-4">The secret request you are looking for is missing or has expired.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user