mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 15:41:27 +00:00
Merge pull request #3153 from Infisical/daniel/secret-requests
feat(secret-sharing): secret requests
This commit is contained in:
@@ -5,8 +5,13 @@ import { apiRequest } from "@app/config/request";
|
||||
import { secretSharingKeys } from "./queries";
|
||||
import {
|
||||
TCreatedSharedSecret,
|
||||
TCreateSecretRequestRequestDTO,
|
||||
TCreateSharedSecretRequest,
|
||||
TDeleteSharedSecretRequest,
|
||||
TDeleteSecretRequestDTO,
|
||||
TDeleteSharedSecretRequestDTO,
|
||||
TRevealedSecretRequest,
|
||||
TRevealSecretRequestValueRequest,
|
||||
TSetSecretRequestValueRequest,
|
||||
TSharedSecret
|
||||
} from "./types";
|
||||
|
||||
@@ -15,7 +20,7 @@ export const useCreateSharedSecret = () => {
|
||||
return useMutation({
|
||||
mutationFn: async (inputData: TCreateSharedSecretRequest) => {
|
||||
const { data } = await apiRequest.post<TCreatedSharedSecret>(
|
||||
"/api/v1/secret-sharing",
|
||||
"/api/v1/secret-sharing/shared",
|
||||
inputData
|
||||
);
|
||||
return data;
|
||||
@@ -30,7 +35,7 @@ export const useCreatePublicSharedSecret = () => {
|
||||
return useMutation({
|
||||
mutationFn: async (inputData: TCreateSharedSecretRequest) => {
|
||||
const { data } = await apiRequest.post<TCreatedSharedSecret>(
|
||||
"/api/v1/secret-sharing/public",
|
||||
"/api/v1/secret-sharing/shared/public",
|
||||
inputData
|
||||
);
|
||||
return data;
|
||||
@@ -40,12 +45,50 @@ export const useCreatePublicSharedSecret = () => {
|
||||
});
|
||||
};
|
||||
|
||||
export const useCreateSecretRequest = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: async (inputData: TCreateSecretRequestRequestDTO) => {
|
||||
const { data } = await apiRequest.post<TCreatedSharedSecret>(
|
||||
"/api/v1/secret-sharing/requests",
|
||||
inputData
|
||||
);
|
||||
return data;
|
||||
},
|
||||
onSuccess: () =>
|
||||
queryClient.invalidateQueries({ queryKey: secretSharingKeys.allSecretRequests() })
|
||||
});
|
||||
};
|
||||
|
||||
export const useSetSecretRequestValue = () => {
|
||||
return useMutation({
|
||||
mutationFn: async (inputData: TSetSecretRequestValueRequest) => {
|
||||
const { data } = await apiRequest.post<TSharedSecret>(
|
||||
`/api/v1/secret-sharing/requests/${inputData.id}/set-value`,
|
||||
inputData
|
||||
);
|
||||
return data;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useRevealSecretRequestValue = () => {
|
||||
return useMutation({
|
||||
mutationFn: async (inputData: TRevealSecretRequestValueRequest) => {
|
||||
const { data } = await apiRequest.post<TRevealedSecretRequest>(
|
||||
`/api/v1/secret-sharing/requests/${inputData.id}/reveal-value`,
|
||||
inputData
|
||||
);
|
||||
return data.secretRequest;
|
||||
}
|
||||
});
|
||||
};
|
||||
export const useDeleteSharedSecret = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation<TSharedSecret, { message: string }, { sharedSecretId: string }>({
|
||||
mutationFn: async ({ sharedSecretId }: TDeleteSharedSecretRequest) => {
|
||||
mutationFn: async ({ sharedSecretId }: TDeleteSharedSecretRequestDTO) => {
|
||||
const { data } = await apiRequest.delete<TSharedSecret>(
|
||||
`/api/v1/secret-sharing/${sharedSecretId}`
|
||||
`/api/v1/secret-sharing/shared/${sharedSecretId}`
|
||||
);
|
||||
return data;
|
||||
},
|
||||
@@ -53,3 +96,19 @@ export const useDeleteSharedSecret = () => {
|
||||
queryClient.invalidateQueries({ queryKey: secretSharingKeys.allSharedSecrets() })
|
||||
});
|
||||
};
|
||||
|
||||
export const useDeleteSecretRequest = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation<TSharedSecret, unknown, TDeleteSecretRequestDTO>({
|
||||
mutationFn: async ({ secretRequestId }: TDeleteSecretRequestDTO) => {
|
||||
const { data } = await apiRequest.delete<TSharedSecret>(
|
||||
`/api/v1/secret-sharing/requests/${secretRequestId}`
|
||||
);
|
||||
|
||||
return data;
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: secretSharingKeys.allSecretRequests() });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -2,16 +2,20 @@ import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
import { apiRequest } from "@app/config/request";
|
||||
|
||||
import { TSharedSecret, TViewSharedSecretResponse } from "./types";
|
||||
import { TGetSecretRequestByIdResponse, TSharedSecret, TViewSharedSecretResponse } from "./types";
|
||||
|
||||
export const secretSharingKeys = {
|
||||
allSharedSecrets: () => ["sharedSecrets"] as const,
|
||||
specificSharedSecrets: ({ offset, limit }: { offset: number; limit: number }) =>
|
||||
[...secretSharingKeys.allSharedSecrets(), { offset, limit }] as const,
|
||||
allSecretRequests: () => ["secretRequests"] as const,
|
||||
specificSecretRequests: ({ offset, limit }: { offset: number; limit: number }) =>
|
||||
[...secretSharingKeys.allSecretRequests(), { offset, limit }] as const,
|
||||
getSecretById: (arg: { id: string; hashedHex: string | null; password?: string }) => [
|
||||
"shared-secret",
|
||||
arg
|
||||
]
|
||||
],
|
||||
getSecretRequestById: (arg: { id: string }) => ["secret-request", arg] as const
|
||||
};
|
||||
|
||||
export const useGetSharedSecrets = ({
|
||||
@@ -30,7 +34,7 @@ export const useGetSharedSecrets = ({
|
||||
});
|
||||
|
||||
const { data } = await apiRequest.get<{ secrets: TSharedSecret[]; totalCount: number }>(
|
||||
"/api/v1/secret-sharing/",
|
||||
"/api/v1/secret-sharing/shared",
|
||||
{
|
||||
params
|
||||
}
|
||||
@@ -40,6 +44,29 @@ export const useGetSharedSecrets = ({
|
||||
});
|
||||
};
|
||||
|
||||
export const useGetSecretRequests = ({
|
||||
offset = 0,
|
||||
limit = 25
|
||||
}: {
|
||||
offset: number;
|
||||
limit: number;
|
||||
}) => {
|
||||
return useQuery({
|
||||
queryKey: secretSharingKeys.specificSecretRequests({ offset, limit }),
|
||||
queryFn: async () => {
|
||||
const { data } = await apiRequest.get<{ secrets: TSharedSecret[]; totalCount: number }>(
|
||||
"/api/v1/secret-sharing/requests",
|
||||
{
|
||||
params: {
|
||||
offset: String(offset),
|
||||
limit: String(limit)
|
||||
}
|
||||
}
|
||||
);
|
||||
return data;
|
||||
}
|
||||
});
|
||||
};
|
||||
export const useGetActiveSharedSecretById = ({
|
||||
sharedSecretId,
|
||||
hashedHex,
|
||||
@@ -53,7 +80,7 @@ export const useGetActiveSharedSecretById = ({
|
||||
queryKey: secretSharingKeys.getSecretById({ id: sharedSecretId, hashedHex, password }),
|
||||
queryFn: async () => {
|
||||
const { data } = await apiRequest.post<TViewSharedSecretResponse>(
|
||||
`/api/v1/secret-sharing/public/${sharedSecretId}`,
|
||||
`/api/v1/secret-sharing/shared/public/${sharedSecretId}`,
|
||||
{
|
||||
...(hashedHex && { hashedHex }),
|
||||
password
|
||||
@@ -65,3 +92,16 @@ export const useGetActiveSharedSecretById = ({
|
||||
enabled: Boolean(sharedSecretId)
|
||||
});
|
||||
};
|
||||
|
||||
export const useGetSecretRequestById = ({ secretRequestId }: { secretRequestId: string }) => {
|
||||
return useQuery({
|
||||
queryKey: secretSharingKeys.getSecretRequestById({ id: secretRequestId }),
|
||||
queryFn: async () => {
|
||||
const { data } = await apiRequest.get<TGetSecretRequestByIdResponse>(
|
||||
`/api/v1/secret-sharing/requests/${secretRequestId}`
|
||||
);
|
||||
|
||||
return data.secretRequest;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -6,13 +6,21 @@ export type TSharedSecret = {
|
||||
updatedAt: Date;
|
||||
name: string | null;
|
||||
lastViewedAt?: Date;
|
||||
accessType: SecretSharingAccessType;
|
||||
expiresAt: Date;
|
||||
expiresAfterViews: number | null;
|
||||
encryptedValue: string;
|
||||
encryptedSecret: string;
|
||||
iv: string;
|
||||
tag: string;
|
||||
};
|
||||
|
||||
export type TRevealedSecretRequest = {
|
||||
secretRequest: {
|
||||
secretValue: string;
|
||||
} & TSharedSecret;
|
||||
};
|
||||
|
||||
export type TCreatedSharedSecret = {
|
||||
id: string;
|
||||
};
|
||||
@@ -26,6 +34,21 @@ export type TCreateSharedSecretRequest = {
|
||||
accessType?: SecretSharingAccessType;
|
||||
};
|
||||
|
||||
export type TCreateSecretRequestRequestDTO = {
|
||||
name?: string;
|
||||
accessType?: SecretSharingAccessType;
|
||||
expiresAt: Date;
|
||||
};
|
||||
|
||||
export type TSetSecretRequestValueRequest = {
|
||||
secretValue: string;
|
||||
id: string;
|
||||
};
|
||||
|
||||
export type TRevealSecretRequestValueRequest = {
|
||||
id: string;
|
||||
};
|
||||
|
||||
export type TViewSharedSecretResponse = {
|
||||
isPasswordProtected: boolean;
|
||||
secret: {
|
||||
@@ -38,10 +61,27 @@ export type TViewSharedSecretResponse = {
|
||||
};
|
||||
};
|
||||
|
||||
export type TDeleteSharedSecretRequest = {
|
||||
export type TGetSecretRequestByIdResponse = {
|
||||
secretRequest: {
|
||||
isSecretValueSet: boolean;
|
||||
accessType: SecretSharingAccessType;
|
||||
requester: {
|
||||
organizationName: string;
|
||||
username: string;
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
export type TDeleteSharedSecretRequestDTO = {
|
||||
sharedSecretId: string;
|
||||
};
|
||||
|
||||
export type TDeleteSecretRequestDTO = {
|
||||
secretRequestId: string;
|
||||
};
|
||||
|
||||
export enum SecretSharingAccessType {
|
||||
Anyone = "anyone",
|
||||
Organization = "organization"
|
||||
|
||||
Reference in New Issue
Block a user