diff --git a/backend/internal/features/backups/backups/controller_test.go b/backend/internal/features/backups/backups/controller_test.go index 9c316f8..6c6b20a 100644 --- a/backend/internal/features/backups/backups/controller_test.go +++ b/backend/internal/features/backups/backups/controller_test.go @@ -1366,11 +1366,24 @@ func createTestBackup( panic(err) } - storages, err := storages.GetStorageService().GetStorages(user, *database.WorkspaceID) - if err != nil || len(storages) == 0 { + loadedStorages, err := storages.GetStorageService().GetStorages(user, *database.WorkspaceID) + if err != nil || len(loadedStorages) == 0 { panic("No storage found for workspace") } + // Filter out system storages + var nonSystemStorages []*storages.Storage + for _, storage := range loadedStorages { + if !storage.IsSystem { + nonSystemStorages = append(nonSystemStorages, storage) + } + } + if len(nonSystemStorages) == 0 { + panic("No non-system storage found for workspace") + } + + storages := nonSystemStorages + backup := &backups_core.Backup{ ID: uuid.New(), DatabaseID: database.ID, diff --git a/backend/internal/features/databases/controller_test.go b/backend/internal/features/databases/controller_test.go index 394686e..b17dd1d 100644 --- a/backend/internal/features/databases/controller_test.go +++ b/backend/internal/features/databases/controller_test.go @@ -1164,12 +1164,13 @@ func getTestMongodbConfig() *mongodb.MongodbDatabase { return &mongodb.MongodbDatabase{ Version: tools.MongodbVersion7, Host: config.GetEnv().TestLocalhost, - Port: port, + Port: &port, Username: "root", Password: "rootpassword", Database: "testdb", AuthDatabase: "admin", IsHttps: false, + IsSrv: false, CpuCount: 1, } } diff --git a/backend/internal/features/databases/databases/mongodb/model.go b/backend/internal/features/databases/databases/mongodb/model.go index 3c925e1..ca0b98b 100644 --- a/backend/internal/features/databases/databases/mongodb/model.go +++ b/backend/internal/features/databases/databases/mongodb/model.go @@ -26,12 +26,13 @@ type MongodbDatabase struct { Version tools.MongodbVersion `json:"version" gorm:"type:text;not null"` Host string `json:"host" gorm:"type:text;not null"` - Port int `json:"port" gorm:"type:int;not null"` + Port *int `json:"port" gorm:"type:int"` Username string `json:"username" gorm:"type:text;not null"` Password string `json:"password" gorm:"type:text;not null"` Database string `json:"database" gorm:"type:text;not null"` AuthDatabase string `json:"authDatabase" gorm:"type:text;not null;default:'admin'"` IsHttps bool `json:"isHttps" gorm:"type:boolean;default:false"` + IsSrv bool `json:"isSrv" gorm:"column:is_srv;type:boolean;not null;default:false"` CpuCount int `json:"cpuCount" gorm:"column:cpu_count;type:int;not null;default:1"` } @@ -43,9 +44,13 @@ func (m *MongodbDatabase) Validate() error { if m.Host == "" { return errors.New("host is required") } - if m.Port == 0 { - return errors.New("port is required") + + if !m.IsSrv { + if m.Port == nil || *m.Port == 0 { + return errors.New("port is required for standard connections") + } } + if m.Username == "" { return errors.New("username is required") } @@ -58,6 +63,7 @@ func (m *MongodbDatabase) Validate() error { if m.CpuCount <= 0 { return errors.New("cpu count must be greater than 0") } + return nil } @@ -125,6 +131,7 @@ func (m *MongodbDatabase) Update(incoming *MongodbDatabase) { m.Database = incoming.Database m.AuthDatabase = incoming.AuthDatabase m.IsHttps = incoming.IsHttps + m.IsSrv = incoming.IsSrv m.CpuCount = incoming.CpuCount if incoming.Password != "" { @@ -455,12 +462,29 @@ func (m *MongodbDatabase) buildConnectionURI(password string) string { tlsParams = "&tls=true&tlsInsecure=true" } + if m.IsSrv { + return fmt.Sprintf( + "mongodb+srv://%s:%s@%s/%s?authSource=%s&connectTimeoutMS=15000%s", + url.QueryEscape(m.Username), + url.QueryEscape(password), + m.Host, + m.Database, + authDB, + tlsParams, + ) + } + + port := 27017 + if m.Port != nil { + port = *m.Port + } + return fmt.Sprintf( "mongodb://%s:%s@%s:%d/%s?authSource=%s&connectTimeoutMS=15000%s", url.QueryEscape(m.Username), url.QueryEscape(password), m.Host, - m.Port, + port, m.Database, authDB, tlsParams, @@ -479,12 +503,28 @@ func (m *MongodbDatabase) BuildMongodumpURI(password string) string { tlsParams = "&tls=true&tlsInsecure=true" } + if m.IsSrv { + return fmt.Sprintf( + "mongodb+srv://%s:%s@%s/?authSource=%s&connectTimeoutMS=15000%s", + url.QueryEscape(m.Username), + url.QueryEscape(password), + m.Host, + authDB, + tlsParams, + ) + } + + port := 27017 + if m.Port != nil { + port = *m.Port + } + return fmt.Sprintf( "mongodb://%s:%s@%s:%d/?authSource=%s&connectTimeoutMS=15000%s", url.QueryEscape(m.Username), url.QueryEscape(password), m.Host, - m.Port, + port, authDB, tlsParams, ) diff --git a/backend/internal/features/databases/databases/mongodb/model_test.go b/backend/internal/features/databases/databases/mongodb/model_test.go index 4e4c3f8..cf48ba8 100644 --- a/backend/internal/features/databases/databases/mongodb/model_test.go +++ b/backend/internal/features/databases/databases/mongodb/model_test.go @@ -64,15 +64,17 @@ func Test_TestConnection_InsufficientPermissions_ReturnsError(t *testing.T) { defer dropUserSafe(container.Client, limitedUsername, container.AuthDatabase) + port := container.Port mongodbModel := &MongodbDatabase{ Version: tc.version, Host: container.Host, - Port: container.Port, + Port: &port, Username: limitedUsername, Password: limitedPassword, Database: container.Database, AuthDatabase: container.AuthDatabase, IsHttps: false, + IsSrv: false, CpuCount: 1, } @@ -133,15 +135,17 @@ func Test_TestConnection_SufficientPermissions_Success(t *testing.T) { defer dropUserSafe(container.Client, backupUsername, container.AuthDatabase) + port := container.Port mongodbModel := &MongodbDatabase{ Version: tc.version, Host: container.Host, - Port: container.Port, + Port: &port, Username: backupUsername, Password: backupPassword, Database: container.Database, AuthDatabase: container.AuthDatabase, IsHttps: false, + IsSrv: false, CpuCount: 1, } @@ -442,15 +446,17 @@ func connectToMongodbContainer( } func createMongodbModel(container *MongodbContainer) *MongodbDatabase { + port := container.Port return &MongodbDatabase{ Version: container.Version, Host: container.Host, - Port: container.Port, + Port: &port, Username: container.Username, Password: container.Password, Database: container.Database, AuthDatabase: container.AuthDatabase, IsHttps: false, + IsSrv: false, CpuCount: 1, } } @@ -489,3 +495,157 @@ func assertWriteDenied(t *testing.T, err error) { strings.Contains(errStr, "permission denied"), "Expected authorization error, got: %v", err) } + +func Test_BuildConnectionURI_WithSrvFormat_ReturnsCorrectUri(t *testing.T) { + port := 27017 + model := &MongodbDatabase{ + Host: "cluster0.example.mongodb.net", + Port: &port, + Username: "testuser", + Password: "testpass123", + Database: "mydb", + AuthDatabase: "admin", + IsHttps: false, + IsSrv: true, + } + + uri := model.buildConnectionURI("testpass123") + + assert.Contains(t, uri, "mongodb+srv://") + assert.Contains(t, uri, "testuser") + assert.Contains(t, uri, "testpass123") + assert.Contains(t, uri, "cluster0.example.mongodb.net") + assert.Contains(t, uri, "/mydb") + assert.Contains(t, uri, "authSource=admin") + assert.Contains(t, uri, "connectTimeoutMS=15000") + assert.NotContains(t, uri, ":27017") +} + +func Test_BuildConnectionURI_WithStandardFormat_ReturnsCorrectUri(t *testing.T) { + port := 27017 + model := &MongodbDatabase{ + Host: "localhost", + Port: &port, + Username: "testuser", + Password: "testpass123", + Database: "mydb", + AuthDatabase: "admin", + IsHttps: false, + IsSrv: false, + } + + uri := model.buildConnectionURI("testpass123") + + assert.Contains(t, uri, "mongodb://") + assert.Contains(t, uri, "testuser") + assert.Contains(t, uri, "testpass123") + assert.Contains(t, uri, "localhost:27017") + assert.Contains(t, uri, "/mydb") + assert.Contains(t, uri, "authSource=admin") + assert.Contains(t, uri, "connectTimeoutMS=15000") + assert.NotContains(t, uri, "mongodb+srv://") +} + +func Test_BuildConnectionURI_WithNullPort_UsesDefault(t *testing.T) { + model := &MongodbDatabase{ + Host: "localhost", + Port: nil, + Username: "testuser", + Password: "testpass123", + Database: "mydb", + AuthDatabase: "admin", + IsHttps: false, + IsSrv: false, + } + + uri := model.buildConnectionURI("testpass123") + + assert.Contains(t, uri, "localhost:27017") +} + +func Test_BuildMongodumpURI_WithSrvFormat_ReturnsCorrectUri(t *testing.T) { + port := 27017 + model := &MongodbDatabase{ + Host: "cluster0.example.mongodb.net", + Port: &port, + Username: "testuser", + Password: "testpass123", + Database: "mydb", + AuthDatabase: "admin", + IsHttps: false, + IsSrv: true, + } + + uri := model.BuildMongodumpURI("testpass123") + + assert.Contains(t, uri, "mongodb+srv://") + assert.Contains(t, uri, "testuser") + assert.Contains(t, uri, "testpass123") + assert.Contains(t, uri, "cluster0.example.mongodb.net") + assert.Contains(t, uri, "/?authSource=admin") + assert.Contains(t, uri, "connectTimeoutMS=15000") + assert.NotContains(t, uri, ":27017") + assert.NotContains(t, uri, "/mydb") +} + +func Test_BuildMongodumpURI_WithStandardFormat_ReturnsCorrectUri(t *testing.T) { + port := 27017 + model := &MongodbDatabase{ + Host: "localhost", + Port: &port, + Username: "testuser", + Password: "testpass123", + Database: "mydb", + AuthDatabase: "admin", + IsHttps: false, + IsSrv: false, + } + + uri := model.BuildMongodumpURI("testpass123") + + assert.Contains(t, uri, "mongodb://") + assert.Contains(t, uri, "testuser") + assert.Contains(t, uri, "testpass123") + assert.Contains(t, uri, "localhost:27017") + assert.Contains(t, uri, "/?authSource=admin") + assert.Contains(t, uri, "connectTimeoutMS=15000") + assert.NotContains(t, uri, "mongodb+srv://") + assert.NotContains(t, uri, "/mydb") +} + +func Test_Validate_SrvConnection_AllowsNullPort(t *testing.T) { + model := &MongodbDatabase{ + Host: "cluster0.example.mongodb.net", + Port: nil, + Username: "testuser", + Password: "testpass123", + Database: "mydb", + AuthDatabase: "admin", + IsHttps: false, + IsSrv: true, + CpuCount: 1, + } + + err := model.Validate() + + assert.NoError(t, err) +} + +func Test_Validate_StandardConnection_RequiresPort(t *testing.T) { + model := &MongodbDatabase{ + Host: "localhost", + Port: nil, + Username: "testuser", + Password: "testpass123", + Database: "mydb", + AuthDatabase: "admin", + IsHttps: false, + IsSrv: false, + CpuCount: 1, + } + + err := model.Validate() + + assert.Error(t, err) + assert.Contains(t, err.Error(), "port is required for standard connections") +} diff --git a/backend/internal/features/databases/testing.go b/backend/internal/features/databases/testing.go index b360480..3a0699c 100644 --- a/backend/internal/features/databases/testing.go +++ b/backend/internal/features/databases/testing.go @@ -71,12 +71,13 @@ func GetTestMongodbConfig() *mongodb.MongodbDatabase { return &mongodb.MongodbDatabase{ Version: tools.MongodbVersion7, Host: config.GetEnv().TestLocalhost, - Port: port, + Port: &port, Username: "root", Password: "rootpassword", Database: "testdb", AuthDatabase: "admin", IsHttps: false, + IsSrv: false, CpuCount: 1, } } diff --git a/backend/internal/features/tests/mongodb_backup_restore_test.go b/backend/internal/features/tests/mongodb_backup_restore_test.go index fffa140..ef21647 100644 --- a/backend/internal/features/tests/mongodb_backup_restore_test.go +++ b/backend/internal/features/tests/mongodb_backup_restore_test.go @@ -385,13 +385,14 @@ func createMongodbDatabaseViaAPI( Type: databases.DatabaseTypeMongodb, Mongodb: &mongodbtypes.MongodbDatabase{ Host: host, - Port: port, + Port: &port, Username: username, Password: password, Database: database, AuthDatabase: authDatabase, Version: version, IsHttps: false, + IsSrv: false, CpuCount: 1, }, } @@ -432,13 +433,14 @@ func createMongodbRestoreViaAPI( request := restores_core.RestoreBackupRequest{ MongodbDatabase: &mongodbtypes.MongodbDatabase{ Host: host, - Port: port, + Port: &port, Username: username, Password: password, Database: database, AuthDatabase: authDatabase, Version: version, IsHttps: false, + IsSrv: false, CpuCount: 1, }, } diff --git a/backend/migrations/20260209125258_add_mongodb_srv_support.sql b/backend/migrations/20260209125258_add_mongodb_srv_support.sql new file mode 100644 index 0000000..c33f82f --- /dev/null +++ b/backend/migrations/20260209125258_add_mongodb_srv_support.sql @@ -0,0 +1,17 @@ +-- +goose Up +-- +goose StatementBegin +ALTER TABLE mongodb_databases ALTER COLUMN port DROP NOT NULL; +-- +goose StatementEnd + +-- +goose StatementBegin +ALTER TABLE mongodb_databases ADD COLUMN is_srv BOOLEAN NOT NULL DEFAULT FALSE; +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +ALTER TABLE mongodb_databases DROP COLUMN is_srv; +-- +goose StatementEnd + +-- +goose StatementBegin +ALTER TABLE mongodb_databases ALTER COLUMN port SET NOT NULL; +-- +goose StatementEnd diff --git a/frontend/src/entity/databases/model/mongodb/MongodbConnectionStringParser.test.ts b/frontend/src/entity/databases/model/mongodb/MongodbConnectionStringParser.test.ts index 5e2e490..cd00168 100644 --- a/frontend/src/entity/databases/model/mongodb/MongodbConnectionStringParser.test.ts +++ b/frontend/src/entity/databases/model/mongodb/MongodbConnectionStringParser.test.ts @@ -32,6 +32,7 @@ describe('MongodbConnectionStringParser', () => { expect(result.database).toBe('mydb'); expect(result.authDatabase).toBe('admin'); expect(result.useTls).toBe(false); + expect(result.isSrv).toBe(false); }); it('should parse connection string without database', () => { @@ -46,6 +47,7 @@ describe('MongodbConnectionStringParser', () => { expect(result.database).toBe(''); expect(result.authDatabase).toBe('admin'); expect(result.useTls).toBe(false); + expect(result.isSrv).toBe(false); }); it('should default port to 27017 when not specified', () => { @@ -107,6 +109,7 @@ describe('MongodbConnectionStringParser', () => { expect(result.password).toBe('atlaspass'); expect(result.database).toBe('mydb'); expect(result.useTls).toBe(true); // SRV connections use TLS by default + expect(result.isSrv).toBe(true); }); it('should parse mongodb+srv:// without database', () => { @@ -119,6 +122,7 @@ describe('MongodbConnectionStringParser', () => { expect(result.host).toBe('cluster0.abc123.mongodb.net'); expect(result.database).toBe(''); expect(result.useTls).toBe(true); + expect(result.isSrv).toBe(true); }); }); @@ -314,13 +318,15 @@ describe('MongodbConnectionStringParser', () => { expect(result.format).toBe('key-value'); }); - it('should return error for key-value format missing password', () => { - const result = expectError( + it('should allow missing password in key-value format (returns empty password)', () => { + const result = expectSuccess( MongodbConnectionStringParser.parse('host=localhost database=mydb user=admin'), ); - expect(result.error).toContain('Password'); - expect(result.format).toBe('key-value'); + expect(result.host).toBe('localhost'); + expect(result.username).toBe('admin'); + expect(result.password).toBe(''); + expect(result.database).toBe('mydb'); }); }); @@ -351,12 +357,15 @@ describe('MongodbConnectionStringParser', () => { expect(result.error).toContain('Username'); }); - it('should return error for missing password in URI', () => { - const result = expectError( + it('should allow missing password in URI (returns empty password)', () => { + const result = expectSuccess( MongodbConnectionStringParser.parse('mongodb://user@host:27017/db'), ); - expect(result.error).toContain('Password'); + expect(result.username).toBe('user'); + expect(result.password).toBe(''); + expect(result.host).toBe('host'); + expect(result.database).toBe('db'); }); it('should return error for mysql:// format (wrong database type)', () => { @@ -446,4 +455,67 @@ describe('MongodbConnectionStringParser', () => { expect(result.database).toBe(''); }); }); + + describe('Password Placeholder Handling', () => { + it('should treat placeholder as empty password in URI format', () => { + const result = expectSuccess( + MongodbConnectionStringParser.parse('mongodb://user:@host:27017/db'), + ); + + expect(result.username).toBe('user'); + expect(result.password).toBe(''); + expect(result.host).toBe('host'); + expect(result.database).toBe('db'); + }); + + it('should treat placeholder as empty password in URI format', () => { + const result = expectSuccess( + MongodbConnectionStringParser.parse('mongodb://user:@host:27017/db'), + ); + + expect(result.username).toBe('user'); + expect(result.password).toBe(''); + expect(result.host).toBe('host'); + expect(result.database).toBe('db'); + }); + + it('should treat placeholder as empty password in SRV format', () => { + const result = expectSuccess( + MongodbConnectionStringParser.parse( + 'mongodb+srv://user:@cluster0.mongodb.net/db', + ), + ); + + expect(result.username).toBe('user'); + expect(result.password).toBe(''); + expect(result.host).toBe('cluster0.mongodb.net'); + expect(result.isSrv).toBe(true); + }); + + it('should treat placeholder as empty password in key-value format', () => { + const result = expectSuccess( + MongodbConnectionStringParser.parse( + 'host=localhost database=mydb user=admin password=', + ), + ); + + expect(result.host).toBe('localhost'); + expect(result.username).toBe('admin'); + expect(result.password).toBe(''); + expect(result.database).toBe('mydb'); + }); + + it('should treat placeholder as empty password in key-value format', () => { + const result = expectSuccess( + MongodbConnectionStringParser.parse( + 'host=localhost database=mydb user=admin password=', + ), + ); + + expect(result.host).toBe('localhost'); + expect(result.username).toBe('admin'); + expect(result.password).toBe(''); + expect(result.database).toBe('mydb'); + }); + }); }); diff --git a/frontend/src/entity/databases/model/mongodb/MongodbConnectionStringParser.ts b/frontend/src/entity/databases/model/mongodb/MongodbConnectionStringParser.ts index 8b29b6f..91eacf3 100644 --- a/frontend/src/entity/databases/model/mongodb/MongodbConnectionStringParser.ts +++ b/frontend/src/entity/databases/model/mongodb/MongodbConnectionStringParser.ts @@ -6,6 +6,7 @@ export type ParseResult = { database: string; authDatabase: string; useTls: boolean; + isSrv: boolean; }; export type ParseError = { @@ -63,7 +64,8 @@ export class MongodbConnectionStringParser { const host = url.hostname; const port = url.port ? parseInt(url.port, 10) : isSrv ? 27017 : 27017; const username = decodeURIComponent(url.username); - const password = decodeURIComponent(url.password); + const rawPassword = decodeURIComponent(url.password); + const password = this.isPasswordPlaceholder(rawPassword) ? '' : rawPassword; const database = decodeURIComponent(url.pathname.slice(1)); const authDatabase = this.getAuthSource(url.search) || 'admin'; const useTls = isSrv ? true : this.checkTlsMode(url.search); @@ -76,10 +78,6 @@ export class MongodbConnectionStringParser { return { error: 'Username is missing from connection string' }; } - if (!password) { - return { error: 'Password is missing from connection string' }; - } - return { host, port, @@ -88,6 +86,7 @@ export class MongodbConnectionStringParser { database: database || '', authDatabase, useTls, + isSrv, }; } catch (e) { return { @@ -114,7 +113,8 @@ export class MongodbConnectionStringParser { const port = params['port']; const database = params['database'] || params['dbname'] || params['db']; const username = params['user'] || params['username']; - const password = params['password']; + const rawPassword = params['password']; + const password = this.isPasswordPlaceholder(rawPassword) ? '' : rawPassword || ''; const authDatabase = params['authSource'] || params['authDatabase'] || 'admin'; const tls = params['tls'] || params['ssl']; @@ -132,13 +132,6 @@ export class MongodbConnectionStringParser { }; } - if (!password) { - return { - error: 'Password is missing from connection string. Use password=yourpassword', - format: 'key-value', - }; - } - const useTls = this.isTlsEnabled(tls); return { @@ -149,6 +142,7 @@ export class MongodbConnectionStringParser { database: database || '', authDatabase, useTls, + isSrv: false, }; } catch (e) { return { @@ -191,4 +185,11 @@ export class MongodbConnectionStringParser { const enabledValues = ['true', 'yes', '1']; return enabledValues.includes(lowercased); } + + private static isPasswordPlaceholder(password: string | null | undefined): boolean { + if (!password) return false; + + const trimmed = password.trim(); + return trimmed === '' || trimmed === ''; + } } diff --git a/frontend/src/entity/databases/model/mongodb/MongodbDatabase.ts b/frontend/src/entity/databases/model/mongodb/MongodbDatabase.ts index 6981fd2..36fdbe9 100644 --- a/frontend/src/entity/databases/model/mongodb/MongodbDatabase.ts +++ b/frontend/src/entity/databases/model/mongodb/MongodbDatabase.ts @@ -10,5 +10,6 @@ export interface MongodbDatabase { database: string; authDatabase: string; isHttps: boolean; + isSrv: boolean; cpuCount: number; } diff --git a/frontend/src/features/databases/ui/edit/EditMongoDbSpecificDataComponent.tsx b/frontend/src/features/databases/ui/edit/EditMongoDbSpecificDataComponent.tsx index 5d3c7e9..be9f94f 100644 --- a/frontend/src/features/databases/ui/edit/EditMongoDbSpecificDataComponent.tsx +++ b/frontend/src/features/databases/ui/edit/EditMongoDbSpecificDataComponent.tsx @@ -46,7 +46,7 @@ export const EditMongoDbSpecificDataComponent = ({ const [isTestingConnection, setIsTestingConnection] = useState(false); const [isConnectionFailed, setIsConnectionFailed] = useState(false); - const hasAdvancedValues = !!database.mongodb?.authDatabase; + const hasAdvancedValues = !!database.mongodb?.authDatabase || !!database.mongodb?.isSrv; const [isShowAdvanced, setShowAdvanced] = useState(hasAdvancedValues); const parseFromClipboard = async () => { @@ -75,17 +75,29 @@ export const EditMongoDbSpecificDataComponent = ({ host: result.host, port: result.port, username: result.username, - password: result.password, + password: result.password || '', database: result.database, authDatabase: result.authDatabase, isHttps: result.useTls, + isSrv: result.isSrv, cpuCount: 1, }, }; + if (result.isSrv) { + setShowAdvanced(true); + } + setEditingDatabase(updatedDatabase); setIsConnectionTested(false); - message.success('Connection string parsed successfully'); + + if (!result.password) { + message.warning( + 'Connection string parsed successfully. Please enter the password manually.', + ); + } else { + message.success('Connection string parsed successfully'); + } } catch { message.error('Failed to read clipboard. Please check browser permissions.'); } @@ -156,9 +168,11 @@ export const EditMongoDbSpecificDataComponent = ({ if (!editingDatabase) return null; + const isSrvConnection = editingDatabase.mongodb?.isSrv || false; + let isAllFieldsFilled = true; if (!editingDatabase.mongodb?.host) isAllFieldsFilled = false; - if (!editingDatabase.mongodb?.port) isAllFieldsFilled = false; + if (!isSrvConnection && !editingDatabase.mongodb?.port) isAllFieldsFilled = false; if (!editingDatabase.mongodb?.username) isAllFieldsFilled = false; if (!editingDatabase.id && !editingDatabase.mongodb?.password) isAllFieldsFilled = false; if (!editingDatabase.mongodb?.database) isAllFieldsFilled = false; @@ -220,25 +234,27 @@ export const EditMongoDbSpecificDataComponent = ({ )} -
-
Port
- { - if (!editingDatabase.mongodb || e === null) return; + {!isSrvConnection && ( +
+
Port
+ { + if (!editingDatabase.mongodb || e === null) return; - setEditingDatabase({ - ...editingDatabase, - mongodb: { ...editingDatabase.mongodb, port: e }, - }); - setIsConnectionTested(false); - }} - size="small" - className="max-w-[200px] grow" - placeholder="27017" - /> -
+ setEditingDatabase({ + ...editingDatabase, + mongodb: { ...editingDatabase.mongodb, port: e }, + }); + setIsConnectionTested(false); + }} + size="small" + className="max-w-[200px] grow" + placeholder="27017" + /> +
+ )}
Username
@@ -366,6 +382,31 @@ export const EditMongoDbSpecificDataComponent = ({ {isShowAdvanced && ( <> +
+
Use SRV connection
+
+ { + if (!editingDatabase.mongodb) return; + + setEditingDatabase({ + ...editingDatabase, + mongodb: { ...editingDatabase.mongodb, isSrv: checked }, + }); + setIsConnectionTested(false); + }} + size="small" + /> + + + +
+
+
Auth database