diff --git a/backend/src/entities/connection/use-cases/create-connection.use.case.ts b/backend/src/entities/connection/use-cases/create-connection.use.case.ts index 1439aac60..9e14f404a 100644 --- a/backend/src/entities/connection/use-cases/create-connection.use.case.ts +++ b/backend/src/entities/connection/use-cases/create-connection.use.case.ts @@ -1,13 +1,10 @@ import { BadRequestException, Inject, Injectable, InternalServerErrorException, Scope } from '@nestjs/common'; import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; -import * as Sentry from '@sentry/node'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; -import { Encryptor } from '../../../helpers/encryption/encryptor.js'; import { isConnectionTypeAgent, slackPostMessage } from '../../../helpers/index.js'; -import { SharedJobsService } from '../../shared-jobs/shared-jobs.service.js'; import { UserRoleEnum } from '../../user/enums/user-role.enum.js'; import { UserEntity } from '../../user/user.entity.js'; import { CreateConnectionDs } from '../application/data-structures/create-connection.ds.js'; @@ -27,7 +24,6 @@ export class CreateConnectionUseCase constructor( @Inject(BaseType.GLOBAL_DB_CONTEXT) protected _dbContext: IGlobalDatabaseContext, - private readonly sharedJobsService: SharedJobsService, ) { super(); } @@ -51,79 +47,58 @@ export class CreateConnectionUseCase await validateCreateConnectionData(createConnectionData); createConnectionData = await processAWSConnection(createConnectionData); - let isConnectionTestedSuccessfully: boolean = false; if (!isConnectionTypeAgent(createConnectionData.connection_parameters.type)) { const connectionParamsCopy = { ...createConnectionData.connection_parameters, }; const dao = getDataAccessObject(connectionParamsCopy); try { - const testResult = await dao.testConnect(); - isConnectionTestedSuccessfully = testResult.result; + await dao.testConnect(); } catch (e) { const text: string = e.message.toLowerCase(); - isConnectionTestedSuccessfully = false; if (text.includes('ssl required') || text.includes('ssl connection required')) { createConnectionData.connection_parameters.ssl = true; connectionParamsCopy.ssl = true; try { const updatedDao = getDataAccessObject(connectionParamsCopy); - const sslTestResult = await updatedDao.testConnect(); - isConnectionTestedSuccessfully = sslTestResult.result; + await updatedDao.testConnect(); } catch (_e) { - isConnectionTestedSuccessfully = false; createConnectionData.connection_parameters.ssl = false; connectionParamsCopy.ssl = false; } } } } - let connectionCopy: ConnectionEntity = null; - try { - const createdConnection: ConnectionEntity = await buildConnectionEntity(createConnectionData, connectionAuthor); - const savedConnection: ConnectionEntity = - await this._dbContext.connectionRepository.saveNewConnection(createdConnection); + const createdConnection: ConnectionEntity = await buildConnectionEntity(createConnectionData, connectionAuthor); + const savedConnection: ConnectionEntity = + await this._dbContext.connectionRepository.saveNewConnection(createdConnection); - connectionCopy = { ...savedConnection } as ConnectionEntity; - if (savedConnection.masterEncryption && masterPwd && !isConnectionTypeAgent(savedConnection.type)) { - connectionCopy = Encryptor.decryptConnectionCredentials(connectionCopy, masterPwd); - } - - let token: string; - if (isConnectionTypeAgent(savedConnection.type)) { - token = await this._dbContext.agentRepository.createNewAgentForConnectionAndReturnToken(savedConnection); - } - const createdAdminGroup = await this._dbContext.groupRepository.createdAdminGroupInConnection( - savedConnection, - connectionAuthor, - ); - await this._dbContext.permissionRepository.createdDefaultAdminPermissionsInGroup(createdAdminGroup); - delete createdAdminGroup.connection; - await this._dbContext.userRepository.saveUserEntity(connectionAuthor); - createdConnection.groups = [createdAdminGroup]; - const foundUserCompany = await this._dbContext.companyInfoRepository.findOneCompanyInfoByUserIdWithConnections( - connectionAuthor.id, - ); - if (foundUserCompany) { - const connection = await this._dbContext.connectionRepository.findOne({ - where: { id: savedConnection.id }, - }); - connection.company = foundUserCompany; - await this._dbContext.connectionRepository.saveUpdatedConnection(connection); - } - await slackPostMessage( - Messages.USER_CREATED_CONNECTION(connectionAuthor.email, createConnectionData.connection_parameters.type), - ); - const connectionRO = buildCreatedConnectionDs(savedConnection, token, masterPwd); - return connectionRO; - } finally { - if (isConnectionTestedSuccessfully && !isConnectionTypeAgent(connectionCopy.type)) { - // Fire-and-forget: run AI scan in background without blocking response - this.sharedJobsService.scanDatabaseAndCreateSettingsAndWidgetsWithAI(connectionCopy).catch((error) => { - console.error('Background AI scan failed:', error); - Sentry.captureException(error); - }); - } + let token: string; + if (isConnectionTypeAgent(savedConnection.type)) { + token = await this._dbContext.agentRepository.createNewAgentForConnectionAndReturnToken(savedConnection); } + const createdAdminGroup = await this._dbContext.groupRepository.createdAdminGroupInConnection( + savedConnection, + connectionAuthor, + ); + await this._dbContext.permissionRepository.createdDefaultAdminPermissionsInGroup(createdAdminGroup); + delete createdAdminGroup.connection; + await this._dbContext.userRepository.saveUserEntity(connectionAuthor); + createdConnection.groups = [createdAdminGroup]; + const foundUserCompany = await this._dbContext.companyInfoRepository.findOneCompanyInfoByUserIdWithConnections( + connectionAuthor.id, + ); + if (foundUserCompany) { + const connection = await this._dbContext.connectionRepository.findOne({ + where: { id: savedConnection.id }, + }); + connection.company = foundUserCompany; + await this._dbContext.connectionRepository.saveUpdatedConnection(connection); + } + await slackPostMessage( + Messages.USER_CREATED_CONNECTION(connectionAuthor.email, createConnectionData.connection_parameters.type), + ); + const connectionRO = buildCreatedConnectionDs(savedConnection, token, masterPwd); + return connectionRO; } } diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts index e21c149c0..12966d378 100644 --- a/frontend/src/app/app-routing.module.ts +++ b/frontend/src/app/app-routing.module.ts @@ -137,6 +137,13 @@ const routes: Routes = [ canActivate: [AuthGuard], title: 'Upgraded successfully | Rocketadmin', }, + { + path: 'auto-configure/:connection-id', + loadComponent: () => + import('./components/auto-configure/auto-configure.component').then((m) => m.AutoConfigureComponent), + canActivate: [AuthGuard], + title: 'Auto-configure | Rocketadmin', + }, { path: 'edit-db/:connection-id', loadComponent: () => import('./components/connect-db/connect-db.component').then((m) => m.ConnectDBComponent), diff --git a/frontend/src/app/components/auto-configure/auto-configure.component.css b/frontend/src/app/components/auto-configure/auto-configure.component.css new file mode 100644 index 000000000..c4d15122c --- /dev/null +++ b/frontend/src/app/components/auto-configure/auto-configure.component.css @@ -0,0 +1,30 @@ +.auto-configure { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 24px; + height: 100vh; +} + +.auto-configure__title { + color: var(--mat-sidenav-content-text-color); + margin: 0; + font-weight: 500; +} + +.auto-configure__text { + color: var(--mat-sidenav-content-text-color); + opacity: 0.7; + margin: 0; + max-width: 400px; + text-align: center; +} + +.auto-configure__notice { + color: var(--mat-sidenav-content-text-color); + opacity: 0.7; + margin: 0; + text-align: center; + max-width: 400px; +} diff --git a/frontend/src/app/components/auto-configure/auto-configure.component.html b/frontend/src/app/components/auto-configure/auto-configure.component.html new file mode 100644 index 000000000..5b4ea8816 --- /dev/null +++ b/frontend/src/app/components/auto-configure/auto-configure.component.html @@ -0,0 +1,12 @@ +@if (loading()) { +
Please wait while we analyze your database and set up the best configuration. This may take a moment.
+{{ errorMessage() }}
+ Continue to dashboard +