mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 19:28:09 +00:00
feat: public page shows left views or time on shared secret
This commit is contained in:
@@ -8,9 +8,7 @@ export const useGetSharedSecrets = () => {
|
|||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ["sharedSecrets"],
|
queryKey: ["sharedSecrets"],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const { data } = await apiRequest.get<TSharedSecret[]>(
|
const { data } = await apiRequest.get<TSharedSecret[]>("/api/v1/secret-sharing/");
|
||||||
"/api/v1/secret-sharing/"
|
|
||||||
);
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -23,11 +21,11 @@ export const useGetActiveSharedSecretByIdAndHashedHex = (id: string, hashedHex:
|
|||||||
`/api/v1/secret-sharing/public/${id}?hashedHex=${hashedHex}`
|
`/api/v1/secret-sharing/public/${id}?hashedHex=${hashedHex}`
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
name: data.name,
|
|
||||||
encryptedValue: data.encryptedValue,
|
encryptedValue: data.encryptedValue,
|
||||||
iv: data.iv,
|
iv: data.iv,
|
||||||
tag: data.tag,
|
tag: data.tag,
|
||||||
expiresAt: data.expiresAt
|
expiresAt: data.expiresAt,
|
||||||
|
expiresAfterViews: data.expiresAfterViews
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -21,14 +21,18 @@ export const ShareSecretPublicPage = () => {
|
|||||||
}
|
}
|
||||||
}, [id, publicKey]);
|
}, [id, publicKey]);
|
||||||
|
|
||||||
const { isLoading, data } = useGetActiveSharedSecretByIdAndHashedHex(id as string, hashedHex as string );
|
const { isLoading, data } = useGetActiveSharedSecretByIdAndHashedHex(
|
||||||
|
id as string,
|
||||||
|
hashedHex as string
|
||||||
|
);
|
||||||
|
|
||||||
const decryptedSecret = useMemo(() => {
|
const decryptedSecret = useMemo(() => {
|
||||||
if (data && data.encryptedValue && publicKey) {
|
if (data && data.encryptedValue && publicKey) {
|
||||||
const res = decryptSymmetric({
|
const res = decryptSymmetric({
|
||||||
ciphertext: data.encryptedValue,
|
ciphertext: data.encryptedValue,
|
||||||
iv: data.iv,
|
iv: data.iv,
|
||||||
tag: data.tag,
|
tag: data.tag,
|
||||||
key,
|
key
|
||||||
});
|
});
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -37,7 +41,7 @@ export const ShareSecretPublicPage = () => {
|
|||||||
|
|
||||||
const [timeLeft, setTimeLeft] = useState("");
|
const [timeLeft, setTimeLeft] = useState("");
|
||||||
const [isUrlCopied, , setIsUrlCopied] = useTimedReset<boolean>({
|
const [isUrlCopied, , setIsUrlCopied] = useTimedReset<boolean>({
|
||||||
initialState: false,
|
initialState: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const millisecondsPerDay = 1000 * 60 * 60 * 24;
|
const millisecondsPerDay = 1000 * 60 * 60 * 24;
|
||||||
@@ -46,18 +50,26 @@ export const ShareSecretPublicPage = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const updateTimer = () => {
|
const updateTimer = () => {
|
||||||
if (data && data.expiresAt) {
|
if (data) {
|
||||||
const expirationTime = new Date(data.expiresAt).getTime();
|
if (data.expiresAt) {
|
||||||
const currentTime = new Date().getTime();
|
const expirationTime = new Date(data.expiresAt).getTime();
|
||||||
const timeDifference = expirationTime - currentTime;
|
const currentTime = new Date().getTime();
|
||||||
|
const timeDifference = expirationTime - currentTime;
|
||||||
|
|
||||||
if (timeDifference < 0) {
|
if (timeDifference < 0) {
|
||||||
setTimeLeft("Expired");
|
setTimeLeft("Expired");
|
||||||
} else {
|
} else {
|
||||||
const hoursRemaining = Math.floor((timeDifference % millisecondsPerDay) / millisecondsPerHour);
|
const hoursRemaining = Math.floor(
|
||||||
const minutesRemaining = Math.floor((timeDifference % millisecondsPerHour) / millisecondsPerMinute);
|
(timeDifference % millisecondsPerDay) / millisecondsPerHour
|
||||||
const secondsRemaining = Math.floor((timeDifference % millisecondsPerMinute) / 1000);
|
);
|
||||||
setTimeLeft(`${hoursRemaining}h ${minutesRemaining}m ${secondsRemaining}s`);
|
const minutesRemaining = Math.floor(
|
||||||
|
(timeDifference % millisecondsPerHour) / millisecondsPerMinute
|
||||||
|
);
|
||||||
|
const secondsRemaining = Math.floor((timeDifference % millisecondsPerMinute) / 1000);
|
||||||
|
setTimeLeft(`${hoursRemaining}h ${minutesRemaining}m ${secondsRemaining}s`);
|
||||||
|
}
|
||||||
|
} else if (data.expiresAfterViews) {
|
||||||
|
setTimeLeft(`${data.expiresAfterViews - 1} more views`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -72,7 +84,6 @@ export const ShareSecretPublicPage = () => {
|
|||||||
}
|
}
|
||||||
}, [isUrlCopied]);
|
}, [isUrlCopied]);
|
||||||
|
|
||||||
|
|
||||||
const copyUrlToClipboard = () => {
|
const copyUrlToClipboard = () => {
|
||||||
navigator.clipboard.writeText(decryptedSecret);
|
navigator.clipboard.writeText(decryptedSecret);
|
||||||
setIsUrlCopied(true);
|
setIsUrlCopied(true);
|
||||||
|
|||||||
@@ -37,23 +37,17 @@ export const SecretTable = ({
|
|||||||
<Table>
|
<Table>
|
||||||
<THead>
|
<THead>
|
||||||
<Tr>
|
<Tr>
|
||||||
<Th>Name</Th>
|
<Th>Secret</Th>
|
||||||
<Th>Value</Th>
|
|
||||||
<Th>Valid Until</Th>
|
<Th>Valid Until</Th>
|
||||||
</Tr>
|
</Tr>
|
||||||
</THead>
|
</THead>
|
||||||
<TBody>
|
<TBody>
|
||||||
{!isLoading && sharedSecret && decryptedSecret && (
|
{!isLoading && sharedSecret && decryptedSecret && (
|
||||||
<Tr key={sharedSecret.name}>
|
<Tr key={sharedSecret.encryptedValue}>
|
||||||
<Td>{sharedSecret.name}</Td>
|
|
||||||
<Td>
|
<Td>
|
||||||
<div className="flex items-center md:space-x-2">
|
<div className="flex items-center md:space-x-2">
|
||||||
<div className="max-w-[20rem] flex-1 break-words">
|
<div className="max-w-[20rem] flex-1 break-words">
|
||||||
<SecretInput
|
<SecretInput isVisible value={decryptedSecret} readOnly />
|
||||||
isVisible
|
|
||||||
value={decryptedSecret}
|
|
||||||
readOnly
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<IconButton
|
<IconButton
|
||||||
ariaLabel="copy to clipboard"
|
ariaLabel="copy to clipboard"
|
||||||
|
|||||||
Reference in New Issue
Block a user