refactor(ui): migrated secret endpoints of e2ee to raw

This commit is contained in:
=
2024-07-30 23:01:12 +05:30
parent 547be80dcf
commit 4caa77e28a
30 changed files with 429 additions and 955 deletions
@@ -1,30 +1,4 @@
import crypto from "crypto";
import { SecretDataProps, Tag } from "public/data/frequentInterfaces";
import { fetchUserWsKey } from "@app/hooks/api/keys/queries";
import { SecretType } from "@app/hooks/api/types";
import { decryptAssymmetric, encryptSymmetric } from "../cryptography/crypto";
interface EncryptedSecretProps {
id: string;
createdAt: string;
environment: string;
secretName: string;
secretCommentCiphertext: string;
secretCommentIV: string;
secretCommentTag: string;
secretKeyCiphertext: string;
secretKeyIV: string;
secretKeyTag: string;
secretValueCiphertext: string;
secretValueIV: string;
secretValueTag: string;
type: SecretType;
tags: Tag[];
}
import { SecretDataProps } from "public/data/frequentInterfaces";
/**
* Encypt secrets before pushing the to the DB
* @param {object} obj
@@ -34,7 +8,6 @@ interface EncryptedSecretProps {
*/
const encryptSecrets = async ({
secretsToEncrypt,
workspaceId,
env
}: {
secretsToEncrypt: SecretDataProps[];
@@ -43,74 +16,14 @@ const encryptSecrets = async ({
}) => {
let secrets;
try {
// const sharedKey = await getLatestFileKey({ workspaceId });
const wsKey = await fetchUserWsKey(workspaceId);
const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY") as string;
let randomBytes: string;
if (wsKey) {
// case: a (shared) key exists for the workspace
randomBytes = decryptAssymmetric({
ciphertext: wsKey.encryptedKey,
nonce: wsKey.nonce,
publicKey: wsKey.sender.publicKey,
privateKey: PRIVATE_KEY
});
} else {
// case: a (shared) key does not exist for the workspace
randomBytes = crypto.randomBytes(16).toString("hex");
}
secrets = secretsToEncrypt.map((secret) => {
// encrypt key
const {
ciphertext: secretKeyCiphertext,
iv: secretKeyIV,
tag: secretKeyTag
} = encryptSymmetric({
plaintext: secret.key,
key: randomBytes
});
// encrypt value
const {
ciphertext: secretValueCiphertext,
iv: secretValueIV,
tag: secretValueTag
} = encryptSymmetric({
plaintext: secret.value ?? "",
key: randomBytes
});
// encrypt comment
const {
ciphertext: secretCommentCiphertext,
iv: secretCommentIV,
tag: secretCommentTag
} = encryptSymmetric({
plaintext: secret.comment ?? "",
key: randomBytes
});
const result: EncryptedSecretProps = {
const result = {
id: secret.id,
createdAt: "",
environment: env,
secretName: secret.key,
secretKeyCiphertext,
secretKeyIV,
secretKeyTag,
secretValueCiphertext,
secretValueIV,
secretValueTag,
secretCommentCiphertext,
secretCommentIV,
secretCommentTag,
type:
secret.valueOverride === undefined || secret?.value !== secret?.valueOverride
? SecretType.Shared
: SecretType.Personal,
secretKey: secret.key,
secretValue: secret.value,
secretComment: secret.comment,
tags: secret.tags
};
@@ -5,7 +5,7 @@ import * as Popover from "@radix-ui/react-popover";
import { useWorkspace } from "@app/context";
import { useDebounce, useToggle } from "@app/hooks";
import { useGetProjectFolders, useGetProjectSecrets, useGetUserWsKey } from "@app/hooks/api";
import { useGetProjectFolders, useGetProjectSecrets } from "@app/hooks/api";
import { SecretInput } from "../SecretInput";
@@ -76,7 +76,6 @@ export const InfisicalSecretInput = forwardRef<HTMLTextAreaElement, Props>(
) => {
const { currentWorkspace } = useWorkspace();
const workspaceId = currentWorkspace?.id || "";
const { data: decryptFileKey } = useGetUserWsKey(workspaceId);
const debouncedValue = useDebounce(value, 500);
@@ -121,7 +120,6 @@ export const InfisicalSecretInput = forwardRef<HTMLTextAreaElement, Props>(
const isPopupOpen = Boolean(suggestionSource.isOpen) && isFocused;
const { data: secrets } = useGetProjectSecrets({
decryptFileKey: decryptFileKey!,
environment: suggestionSource.environment || "",
secretPath: suggestionSource.secretPath || "",
workspaceId,
@@ -193,8 +191,9 @@ export const InfisicalSecretInput = forwardRef<HTMLTextAreaElement, Props>(
);
// mid will be computed value inside the interpolation
const mid = suggestionSource.isDeep
? `${suggestionSource.value.slice(0, -suggestionSource.predicate.length || undefined)}${selectedSuggestion.slug
}`
? `${suggestionSource.value.slice(0, -suggestionSource.predicate.length || undefined)}${
selectedSuggestion.slug
}`
: selectedSuggestion.slug;
// whether we should append . or closing bracket on selecting suggestion
const closingSymbol = getClosingSymbol(
@@ -328,8 +327,9 @@ export const InfisicalSecretInput = forwardRef<HTMLTextAreaElement, Props>(
key={`secret-reference-secret-${i + 1}`}
>
<div
className={`${highlightedIndex === i ? "bg-gray-600" : ""
} text-md relative mb-0.5 flex w-full cursor-pointer select-none items-center justify-between rounded-md px-2 py-2 outline-none transition-all hover:bg-mineshaft-500 data-[highlighted]:bg-mineshaft-500`}
className={`${
highlightedIndex === i ? "bg-gray-600" : ""
} text-md relative mb-0.5 flex w-full cursor-pointer select-none items-center justify-between rounded-md px-2 py-2 outline-none transition-all hover:bg-mineshaft-500 data-[highlighted]:bg-mineshaft-500`}
>
<div className="flex w-full gap-2">
<div className="flex items-center text-yellow-700">