diff --git a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-enums.ts b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-enums.ts
index 661a2399a..470a63849 100644
--- a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-enums.ts
+++ b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-enums.ts
@@ -8,7 +8,8 @@ export enum SecretRotation {
AwsIamUserSecret = "aws-iam-user-secret",
LdapPassword = "ldap-password",
OktaClientSecret = "okta-client-secret",
- RedisCredentials = "redis-credentials"
+ RedisCredentials = "redis-credentials",
+ MongoDBCredentials = "mongodb-credentials"
}
export enum SecretRotationStatus {
diff --git a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-maps.ts b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-maps.ts
index 2087fa195..c2b0714ab 100644
--- a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-maps.ts
+++ b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-maps.ts
@@ -11,7 +11,8 @@ export const SECRET_ROTATION_NAME_MAP: Record = {
[SecretRotation.AwsIamUserSecret]: "AWS IAM User Secret",
[SecretRotation.LdapPassword]: "LDAP Password",
[SecretRotation.OktaClientSecret]: "Okta Client Secret",
- [SecretRotation.RedisCredentials]: "Redis Credentials"
+ [SecretRotation.RedisCredentials]: "Redis Credentials",
+ [SecretRotation.MongoDBCredentials]: "MongoDB Credentials"
};
export const SECRET_ROTATION_CONNECTION_MAP: Record = {
@@ -24,5 +25,6 @@ export const SECRET_ROTATION_CONNECTION_MAP: Record;
diff --git a/frontend/src/hooks/api/appConnections/types/mongodb-connection.ts b/frontend/src/hooks/api/appConnections/types/mongodb-connection.ts
new file mode 100644
index 000000000..151c676a5
--- /dev/null
+++ b/frontend/src/hooks/api/appConnections/types/mongodb-connection.ts
@@ -0,0 +1,22 @@
+import { AppConnection } from "@app/hooks/api/appConnections/enums";
+import { TRootAppConnection } from "@app/hooks/api/appConnections/types/root-connection";
+
+export enum MongoDBConnectionMethod {
+ UsernameAndPassword = "username-and-password"
+}
+
+export type TMongoDBConnectionCredentials = {
+ host: string;
+ port: number;
+ username: string;
+ password: string;
+ database: string;
+ sslEnabled: boolean;
+ sslRejectUnauthorized: boolean;
+ sslCertificate?: string;
+};
+
+export type TMongoDBConnection = TRootAppConnection & { app: AppConnection.MongoDB } & {
+ method: MongoDBConnectionMethod.UsernameAndPassword;
+ credentials: TMongoDBConnectionCredentials;
+};
diff --git a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/AppConnectionForm.tsx b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/AppConnectionForm.tsx
index aca33ffa2..3b1710fdb 100644
--- a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/AppConnectionForm.tsx
+++ b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/AppConnectionForm.tsx
@@ -34,6 +34,7 @@ import { HerokuConnectionForm } from "./HerokuAppConnectionForm";
import { HumanitecConnectionForm } from "./HumanitecConnectionForm";
import { LaravelForgeConnectionForm } from "./LaravelForgeConnectionForm";
import { LdapConnectionForm } from "./LdapConnectionForm";
+import { MongoDBConnectionForm } from "./MongoDBConnectionForm";
import { MsSqlConnectionForm } from "./MsSqlConnectionForm";
import { MySqlConnectionForm } from "./MySqlConnectionForm";
import { NetlifyConnectionForm } from "./NetlifyConnectionForm";
@@ -170,6 +171,8 @@ const CreateForm = ({ app, onComplete, projectId }: CreateFormProps) => {
return ;
case AppConnection.Redis:
return ;
+ case AppConnection.MongoDB:
+ return ;
default:
throw new Error(`Unhandled App ${app}`);
}
@@ -326,6 +329,8 @@ const UpdateForm = ({ appConnection, onComplete }: UpdateFormProps) => {
return ;
case AppConnection.Redis:
return ;
+ case AppConnection.MongoDB:
+ return ;
default:
throw new Error(`Unhandled App ${(appConnection as TAppConnection).app}`);
}
diff --git a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/MongoDBConnectionForm.tsx b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/MongoDBConnectionForm.tsx
new file mode 100644
index 000000000..c9b3421ce
--- /dev/null
+++ b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/MongoDBConnectionForm.tsx
@@ -0,0 +1,334 @@
+import { useEffect, useState } from "react";
+import { Controller, FormProvider, useForm } from "react-hook-form";
+import { faQuestionCircle } from "@fortawesome/free-solid-svg-icons";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { Tab } from "@headlessui/react";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { z } from "zod";
+
+import {
+ Button,
+ FormControl,
+ Input,
+ ModalClose,
+ SecretInput,
+ Select,
+ SelectItem,
+ Switch,
+ TextArea,
+ Tooltip
+} from "@app/components/v2";
+import { APP_CONNECTION_MAP, getAppConnectionMethodDetails } from "@app/helpers/appConnections";
+import { MongoDBConnectionMethod, TMongoDBConnection } from "@app/hooks/api/appConnections";
+import { AppConnection } from "@app/hooks/api/appConnections/enums";
+
+import {
+ genericAppConnectionFieldsSchema,
+ GenericAppConnectionsFields
+} from "./GenericAppConnectionFields";
+
+type Props = {
+ appConnection?: TMongoDBConnection;
+ onSubmit: (formData: FormData) => Promise;
+};
+
+const rootSchema = genericAppConnectionFieldsSchema.extend({
+ app: z.literal(AppConnection.MongoDB)
+});
+
+const formSchema = z.discriminatedUnion("method", [
+ rootSchema.extend({
+ method: z.literal(MongoDBConnectionMethod.UsernameAndPassword),
+ credentials: z.object({
+ host: z.string().trim().min(1, "Host required"),
+ port: z.coerce.number().default(27017),
+ username: z.string().trim().min(1, "Username required"),
+ password: z.string().trim().min(1, "Password required"),
+ database: z.string().trim().min(1, "Database required"),
+ sslEnabled: z.boolean().default(false),
+ sslRejectUnauthorized: z.boolean().default(true),
+ sslCertificate: z
+ .string()
+ .trim()
+ .transform((value) => value || undefined)
+ .optional()
+ })
+ })
+]);
+
+type FormData = z.infer;
+
+export const MongoDBConnectionForm = ({ appConnection, onSubmit }: Props) => {
+ const isUpdate = Boolean(appConnection);
+ const [selectedTabIndex, setSelectedTabIndex] = useState(0);
+
+ const form = useForm({
+ resolver: zodResolver(formSchema),
+ defaultValues: appConnection ?? {
+ app: AppConnection.MongoDB,
+ method: MongoDBConnectionMethod.UsernameAndPassword,
+ credentials: {
+ host: "",
+ port: 27017,
+ username: "",
+ password: "",
+ database: "",
+ sslEnabled: false,
+ sslRejectUnauthorized: true,
+ sslCertificate: undefined
+ }
+ }
+ });
+
+ const {
+ handleSubmit,
+ watch,
+ control,
+ setValue,
+ formState: { isSubmitting, isDirty }
+ } = form;
+
+ const host = watch("credentials.host");
+ const sslEnabled = watch("credentials.sslEnabled");
+
+ useEffect(() => {
+ if (host && host.includes("+srv") && !sslEnabled) {
+ setValue("credentials.sslEnabled", true, { shouldDirty: true });
+ }
+ }, [host, sslEnabled, setValue]);
+
+ return (
+
+
+
+
+ )}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};