chore: refactor

This commit is contained in:
Meet
2024-10-01 01:34:24 +05:30
parent b0e536e576
commit 22b6e0afcd
9 changed files with 58 additions and 76 deletions
+2 -1
View File
@@ -37,7 +37,6 @@
"@slack/oauth": "^3.0.1", "@slack/oauth": "^3.0.1",
"@slack/web-api": "^7.3.4", "@slack/web-api": "^7.3.4",
"@team-plain/typescript-sdk": "^4.6.1", "@team-plain/typescript-sdk": "^4.6.1",
"@types/sjcl": "^1.0.34",
"@ucast/mongo2js": "^1.3.4", "@ucast/mongo2js": "^1.3.4",
"ajv": "^8.12.0", "ajv": "^8.12.0",
"argon2": "^0.31.2", "argon2": "^0.31.2",
@@ -119,6 +118,7 @@
"@types/prompt-sync": "^4.2.3", "@types/prompt-sync": "^4.2.3",
"@types/resolve": "^1.20.6", "@types/resolve": "^1.20.6",
"@types/safe-regex": "^1.1.6", "@types/safe-regex": "^1.1.6",
"@types/sjcl": "^1.0.34",
"@types/uuid": "^9.0.7", "@types/uuid": "^9.0.7",
"@typescript-eslint/eslint-plugin": "^6.20.0", "@typescript-eslint/eslint-plugin": "^6.20.0",
"@typescript-eslint/parser": "^6.20.0", "@typescript-eslint/parser": "^6.20.0",
@@ -7302,6 +7302,7 @@
"version": "1.0.34", "version": "1.0.34",
"resolved": "https://registry.npmjs.org/@types/sjcl/-/sjcl-1.0.34.tgz", "resolved": "https://registry.npmjs.org/@types/sjcl/-/sjcl-1.0.34.tgz",
"integrity": "sha512-bQHEeK5DTQRunIfQeUMgtpPsNNCcZyQ9MJuAfW1I7iN0LDunTc78Fu17STbLMd7KiEY/g2zHVApippa70h6HoQ==", "integrity": "sha512-bQHEeK5DTQRunIfQeUMgtpPsNNCcZyQ9MJuAfW1I7iN0LDunTc78Fu17STbLMd7KiEY/g2zHVApippa70h6HoQ==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/uuid": { "node_modules/@types/uuid": {
+1 -1
View File
@@ -80,6 +80,7 @@
"@types/prompt-sync": "^4.2.3", "@types/prompt-sync": "^4.2.3",
"@types/resolve": "^1.20.6", "@types/resolve": "^1.20.6",
"@types/safe-regex": "^1.1.6", "@types/safe-regex": "^1.1.6",
"@types/sjcl": "^1.0.34",
"@types/uuid": "^9.0.7", "@types/uuid": "^9.0.7",
"@typescript-eslint/eslint-plugin": "^6.20.0", "@typescript-eslint/eslint-plugin": "^6.20.0",
"@typescript-eslint/parser": "^6.20.0", "@typescript-eslint/parser": "^6.20.0",
@@ -134,7 +135,6 @@
"@slack/oauth": "^3.0.1", "@slack/oauth": "^3.0.1",
"@slack/web-api": "^7.3.4", "@slack/web-api": "^7.3.4",
"@team-plain/typescript-sdk": "^4.6.1", "@team-plain/typescript-sdk": "^4.6.1",
"@types/sjcl": "^1.0.34",
"@ucast/mongo2js": "^1.3.4", "@ucast/mongo2js": "^1.3.4",
"ajv": "^8.12.0", "ajv": "^8.12.0",
"argon2": "^0.31.2", "argon2": "^0.31.2",
@@ -7,7 +7,7 @@ import { AuthMode } from "@app/services/auth/auth-type";
export const registerExternalMigrationRouter = async (server: FastifyZodProvider) => { export const registerExternalMigrationRouter = async (server: FastifyZodProvider) => {
server.route({ server.route({
method: "POST", method: "POST",
url: "/envkey", url: "/env-key",
config: { config: {
rateLimit: readLimit rateLimit: readLimit
}, },
@@ -20,15 +20,12 @@ export const registerExternalMigrationRouter = async (server: FastifyZodProvider
}) })
}), }),
response: { response: {
200: z.object({ 200: z.object({})
success: z.boolean(),
error: z.string().optional()
})
} }
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => { handler: async (req) => {
const result = await server.services.migration.importEnvnKeyData({ await server.services.migration.importEnvnKeyData({
decryptionKey: req.body.decryptionKey, decryptionKey: req.body.decryptionKey,
encryptedJson: req.body.encryptedJson, encryptedJson: req.body.encryptedJson,
actorId: req.permission.id, actorId: req.permission.id,
@@ -36,7 +33,6 @@ export const registerExternalMigrationRouter = async (server: FastifyZodProvider
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod actorAuthMethod: req.permission.authMethod
}); });
return result;
} }
}); });
}; };
@@ -3,6 +3,8 @@ import sjcl from "sjcl";
import tweetnacl from "tweetnacl"; import tweetnacl from "tweetnacl";
import tweetnaclUtil from "tweetnacl-util"; import tweetnaclUtil from "tweetnacl-util";
import { BadRequestError } from "@app/lib/errors";
import { InfisicalImportData, TEnvKeyExportJSON } from "./external-migration-types"; import { InfisicalImportData, TEnvKeyExportJSON } from "./external-migration-types";
const { codec, hash } = sjcl; const { codec, hash } = sjcl;
@@ -16,7 +18,7 @@ export const decryptEnvKeyData = async (decryptionKey: string, encryptedJson: {
const decrypted = secretbox.open(encryptedData, nonce, key); const decrypted = secretbox.open(encryptedData, nonce, key);
if (!decrypted) { if (!decrypted) {
throw new Error("Decryption failed, please check the entered encryption key"); throw new BadRequestError({ message: "Decryption failed, please check the entered encryption key" });
} }
const decryptedJson = tweetnaclUtil.encodeUTF8(decrypted); const decryptedJson = tweetnaclUtil.encodeUTF8(decrypted);
@@ -33,7 +35,7 @@ export const parseEnvKeyData = async (decryptedJson: string): Promise<InfisicalI
}; };
parsedJson.apps.forEach((app: { name: string; id: string }) => { parsedJson.apps.forEach((app: { name: string; id: string }) => {
infisicalImportData.projects?.set(app.id, { name: app.name, id: app.id }); infisicalImportData.projects.set(app.id, { name: app.name, id: app.id });
}); });
// string to string map for env templates // string to string map for env templates
@@ -36,11 +36,7 @@ export const externalMigrationServiceFactory = ({
}: TImportInfisicalDataCreate) => { }: TImportInfisicalDataCreate) => {
// Import data to infisical // Import data to infisical
if (!data || !data.projects) { if (!data || !data.projects) {
logger.error("No projects found in data"); throw new BadRequestError({ message: "No projects found in data" });
return {
success: false,
message: "No projects found in data"
};
} }
const orginalToNewProjectId = new Map<string, string>(); const orginalToNewProjectId = new Map<string, string>();
@@ -55,13 +51,12 @@ export const externalMigrationServiceFactory = ({
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod, actorAuthMethod,
workspaceName: project?.name, workspaceName: project.name,
createDefaultEnvs: false createDefaultEnvs: false
}) })
.then((projectResponse) => { .then((projectResponse) => {
if (!projectResponse) { if (!projectResponse) {
logger.error(`Failed to import project: [name:${project.name}] [id:${id}]`); throw new BadRequestError({ message: `Failed to import to project [name:${project.name}] [id:${id}]` });
throw new Error(`Failed to import project: [name:${project.name}] [id:${id}]`);
} }
orginalToNewProjectId.set(project.id, projectResponse.id); orginalToNewProjectId.set(project.id, projectResponse.id);
}); });
@@ -86,19 +81,14 @@ export const externalMigrationServiceFactory = ({
}) })
}); });
if (!response) { if (!response) {
logger.error(`Failed to invite user to projects: [userId:${actorId}]`); throw new BadRequestError({ message: `Failed to invite user to projects: [userId:${actorId}]` });
return {
success: false,
message: `Failed to invite user to project: [userId:${actorId}]`
};
} }
// Import environments // Import environments
if (data.environments) { if (data.environments) {
for (const [id, environment] of data.environments) { for await (const [id, environment] of data.environments) {
try { try {
// TODO: we can create envs parallely once the position constraint is handled differently // TODO: we can create envs parallely once the position constraint is handled differently
// eslint-disable-next-line
const newEnvironment = await projectEnvService.createEnvironment({ const newEnvironment = await projectEnvService.createEnvironment({
actor, actor,
actorId, actorId,
@@ -126,7 +116,7 @@ export const externalMigrationServiceFactory = ({
// Import secrets // Import secrets
if (data.secrets) { if (data.secrets) {
for (const [id, secret] of data.secrets) { for await (const [id, secret] of data.secrets) {
const dataProjectId = data.environments?.get(secret.environmentId)?.projectId; const dataProjectId = data.environments?.get(secret.environmentId)?.projectId;
if (!dataProjectId) { if (!dataProjectId) {
logger.error(`Failed to import secret: [name:${secret.name}] [id:${id}], project not found`); logger.error(`Failed to import secret: [name:${secret.name}] [id:${id}], project not found`);
@@ -137,7 +127,6 @@ export const externalMigrationServiceFactory = ({
} }
const projectId = orginalToNewProjectId.get(dataProjectId); const projectId = orginalToNewProjectId.get(dataProjectId);
// TODO: we can create secrets parallely once the KMS ID bug on create is fixed // TODO: we can create secrets parallely once the KMS ID bug on create is fixed
// eslint-disable-next-line
const newSecret = await secretService.createSecretRaw({ const newSecret = await secretService.createSecretRaw({
actorId, actorId,
actor, actor,
@@ -151,18 +140,12 @@ export const externalMigrationServiceFactory = ({
secretValue: secret.value secretValue: secret.value
}); });
if (!newSecret) { if (!newSecret) {
logger.error(`Failed to import secret: [name:${secret.name}] [id:${id}]`); throw new BadRequestError({ message: `Failed to import secret: [name:${secret.name}] [id:${id}]` });
return {
success: false,
message: `Failed to import secret: [name:${secret.name}] [id:${id}]`
};
} }
} }
} }
return { return true;
success: true
};
}; };
const importEnvnKeyData = async ({ const importEnvnKeyData = async ({
@@ -1,7 +1,7 @@
import { ActorAuthMethod, ActorType } from "../auth/auth-type"; import { ActorAuthMethod, ActorType } from "../auth/auth-type";
export type InfisicalImportData = { export type InfisicalImportData = {
projects?: Map<string, { name: string; id: string }>; projects: Map<string, { name: string; id: string }>;
environments?: Map< environments?: Map<
string, string,
@@ -208,7 +208,15 @@ export const projectServiceFactory = ({
); );
// set default environments and root folder for provided environments // set default environments and root folder for provided environments
let envs; let envs: {
id: string;
createdAt: Date;
updatedAt: Date;
projectId: string;
name: string;
slug: string;
position: number;
}[] = [];
if (createDefaultEnvs) { if (createDefaultEnvs) {
envs = await projectEnvDAL.insertMany( envs = await projectEnvDAL.insertMany(
DEFAULT_PROJECT_ENVS.map((el, i) => ({ ...el, projectId: project.id, position: i + 1 })), DEFAULT_PROJECT_ENVS.map((el, i) => ({ ...el, projectId: project.id, position: i + 1 })),
@@ -364,7 +372,7 @@ export const projectServiceFactory = ({
return { return {
...project, ...project,
environments: envs || [], environments: envs,
_id: project.id _id: project.id
}; };
}); });
+19 -23
View File
@@ -1,31 +1,27 @@
import { useMutation } from "@tanstack/react-query"; import { useMutation, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
import { apiRequest } from "@app/config/request"; import { apiRequest } from "@app/config/request";
import { workspaceKeys } from "../workspace";
export const useImportEnvKey = () => { export const useImportEnvKey = () => {
const queryClient = useQueryClient();
return useMutation({ return useMutation({
mutationFn: async ({ encryptedJson, decryptionKey }: { encryptedJson: { mutationFn: async ({ encryptedJson, decryptionKey }: {
nonce: string, encryptedJson: {
data: string nonce: string,
}, decryptionKey: string }) : Promise<{ success: boolean, message:string }>=> { data: string
try{ }, decryptionKey: string
const { data } = await apiRequest.post<{ }): Promise<{ success: boolean, message: string }> => {
success: boolean, const { data } = await apiRequest.post("/api/v3/migrate/env-key/", {
message: string encryptedJson,
}>("/api/v3/migrate/envkey/", { decryptionKey
encryptedJson, });
decryptionKey return data;
}); },
return data; onSuccess: () => {
} catch (err) { queryClient.invalidateQueries(workspaceKeys.getAllUserWorkspace);
if ((err as AxiosError<{
message: string
}>).response) {
return { success: false, message: (err as AxiosError<{message: string}>).response?.data?.message as string};
}
}
return { success: false, message: "Something went wrong" };
} }
}); });
}; };
@@ -11,7 +11,7 @@ import { Button, FormControl, IconButton } from "@app/components/v2";
import { useImportEnvKey } from "@app/hooks/api/migration/mutations"; import { useImportEnvKey } from "@app/hooks/api/migration/mutations";
const formSchema = z.object({ const formSchema = z.object({
decryptionKey: z.string().min(1), encryptionKey: z.string().min(1),
file: z.unknown(), file: z.unknown(),
encryptedJson: z.object({ encryptedJson: z.object({
nonce: z.string().min(1), nonce: z.string().min(1),
@@ -39,7 +39,7 @@ export const ImportTab = () => {
} = useForm<TForm>({ } = useForm<TForm>({
resolver: zodResolver(formSchema), resolver: zodResolver(formSchema),
values: { values: {
decryptionKey: "", encryptionKey: "",
encryptedJson: { encryptedJson: {
nonce: "", nonce: "",
data: "" data: ""
@@ -49,7 +49,6 @@ export const ImportTab = () => {
}); });
const parseJson = (src: ArrayBuffer) => { const parseJson = (src: ArrayBuffer) => {
console.log("here")
const file = src.toString(); const file = src.toString();
const formatedData: Record<string, string> = JSON.parse(file); const formatedData: Record<string, string> = JSON.parse(file);
if (Object.keys(formatedData).includes("nonce") && Object.keys(formatedData).includes("data")) { if (Object.keys(formatedData).includes("nonce") && Object.keys(formatedData).includes("data")) {
@@ -59,7 +58,6 @@ export const ImportTab = () => {
}; };
setValue("encryptedJson", data); setValue("encryptedJson", data);
trigger("encryptedJson"); trigger("encryptedJson");
console.log(data);
} else { } else {
setValue("encryptedJson", { setValue("encryptedJson", {
nonce: "", nonce: "",
@@ -101,8 +99,8 @@ export const ImportTab = () => {
return; return;
} }
const res = await importEnvKey({ encryptedJson: data.encryptedJson, decryptionKey: data.decryptionKey }); try{
if (res.success) { await importEnvKey({ encryptedJson: data.encryptedJson, decryptionKey: data.encryptionKey });
createNotification({ createNotification({
text: "Data imported successfully.", text: "Data imported successfully.",
type: "success" type: "success"
@@ -111,12 +109,10 @@ export const ImportTab = () => {
if (fileUploadRef.current) { if (fileUploadRef.current) {
fileUploadRef.current.value = ""; fileUploadRef.current.value = "";
} }
} else { } catch (error) {
createNotification({ reset();
text: res.message,
type: "error"
});
} }
} }
const watchEncryptedJsonFile: any = watch("file"); const watchEncryptedJsonFile: any = watch("file");
@@ -152,17 +148,17 @@ export const ImportTab = () => {
<form onSubmit={handleSubmit(submitExport)}> <form onSubmit={handleSubmit(submitExport)}>
<Controller <Controller
render={({ field: { onChange, ...field }, fieldState: { error } }) => ( render={({ field: { onChange, ...field }, fieldState: { error } }) => (
<FormControl errorText={error?.message} isError={Boolean(error)} label="Decryption Key"> <FormControl errorText={error?.message} isError={Boolean(error)} label="Encryption Key">
<input <input
{...field} {...field}
onChange={onChange} onChange={onChange}
type="password" type="password"
className="w-full bg-mineshaft-800 text-white rounded-lg py-2 px-4" className="w-full bg-mineshaft-800 text-white rounded-lg py-2 px-4"
placeholder="Enter decryption key" placeholder="Enter encryption key"
/> />
</FormControl> </FormControl>
)} )}
name="decryptionKey" name="encryptionKey"
control={control} control={control}
/> />
<div className="flex justify-left"> <div className="flex justify-left">