From 174eead2c15fc6faa3ee14f4157c690e8b68727f Mon Sep 17 00:00:00 2001 From: Artem Niehrieiev Date: Mon, 23 Mar 2026 15:15:26 +0000 Subject: [PATCH 1/6] refactor: update return types to include null for connection-related methods and improve error handling --- .../connection/connection.controller.ts | 2 +- .../connection.repository.interface.ts | 14 +++++++------- .../custom-connection-repository-extension.ts | 12 ++++++------ .../use-cases/create-connection.use.case.ts | 8 ++++---- .../use-cases/test-connection.use.case.ts | 18 +++++++++--------- .../utils/validate-create-connection-data.ts | 6 +++--- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/backend/src/entities/connection/connection.controller.ts b/backend/src/entities/connection/connection.controller.ts index c34502312..0771287a0 100644 --- a/backend/src/entities/connection/connection.controller.ts +++ b/backend/src/entities/connection/connection.controller.ts @@ -291,7 +291,7 @@ export class ConnectionController { @UserId() userId: string, @MasterPassword() masterPwd: string, ): Promise { - const errors = []; + const errors: string[] = []; if (updateConnectionDto.masterEncryption && !masterPwd) { errors.push(Messages.MASTER_PASSWORD_REQUIRED); } diff --git a/backend/src/entities/connection/repository/connection.repository.interface.ts b/backend/src/entities/connection/repository/connection.repository.interface.ts index 1e239c4b5..69b161a7c 100644 --- a/backend/src/entities/connection/repository/connection.repository.interface.ts +++ b/backend/src/entities/connection/repository/connection.repository.interface.ts @@ -8,27 +8,27 @@ export interface IConnectionRepository { findAllUserNonTestsConnections(userId: string): Promise>; - findAllUsersInConnection(connectionId): Promise>; + findAllUsersInConnection(connectionId: string): Promise>; - findOneConnection(connectionId: string): Promise; + findOneConnection(connectionId: string): Promise; - findAndDecryptConnection(connectionId: string, masterPwd: string): Promise; + findAndDecryptConnection(connectionId: string, masterPwd: string): Promise; removeConnection(connection: ConnectionEntity): Promise; - findConnectionWithGroups(connectionId: string): Promise; + findConnectionWithGroups(connectionId: string): Promise; getWorkedConnectionsInTwoWeeks(): Promise>; - getConnectionByGroupIdWithCompanyAndUsersInCompany(groupId: string): Promise; + getConnectionByGroupIdWithCompanyAndUsersInCompany(groupId: string): Promise; - findOneById(connectionId: string): Promise; + findOneById(connectionId: string): Promise; isTestConnectionById(connectionId: string): Promise; saveUpdatedConnection(connection: ConnectionEntity): Promise; - findOneAgentConnectionByToken(connectionToken: string): Promise; + findOneAgentConnectionByToken(connectionToken: string): Promise; decryptConnectionField(field: string): string; diff --git a/backend/src/entities/connection/repository/custom-connection-repository-extension.ts b/backend/src/entities/connection/repository/custom-connection-repository-extension.ts index d9a29d05e..b56ca0848 100644 --- a/backend/src/entities/connection/repository/custom-connection-repository-extension.ts +++ b/backend/src/entities/connection/repository/custom-connection-repository-extension.ts @@ -65,7 +65,7 @@ export const customConnectionRepositoryExtension: IConnectionRepository = { return await usersQb.getMany(); }, - async findOneConnection(connectionId: string): Promise { + async findOneConnection(connectionId: string): Promise { const connectionQb = this.createQueryBuilder('connection') .leftJoinAndSelect('connection.connection_properties', 'connection_properties') .where('connection.id = :connectionId', { @@ -82,7 +82,7 @@ export const customConnectionRepositoryExtension: IConnectionRepository = { return connection; }, - async findAndDecryptConnection(connectionId: string, masterPwd: string): Promise { + async findAndDecryptConnection(connectionId: string, masterPwd: string): Promise { const qb = this.createQueryBuilder('connection') .leftJoinAndSelect('connection.agent', 'agent') .andWhere('connection.id = :connectionId', { connectionId: connectionId }); @@ -115,7 +115,7 @@ export const customConnectionRepositoryExtension: IConnectionRepository = { return await this.remove(connection); }, - async findConnectionWithGroups(connectionId: string): Promise { + async findConnectionWithGroups(connectionId: string): Promise { const qb = this.createQueryBuilder('connection') .leftJoinAndSelect('connection.groups', 'group') .andWhere('connection.id = :connectionId', { connectionId: connectionId }); @@ -134,7 +134,7 @@ export const customConnectionRepositoryExtension: IConnectionRepository = { return freshNonTestConnectionsWithLogs; }, - async getConnectionByGroupIdWithCompanyAndUsersInCompany(groupId: string): Promise { + async getConnectionByGroupIdWithCompanyAndUsersInCompany(groupId: string): Promise { const qb = this.createQueryBuilder('connection') .leftJoinAndSelect('connection.groups', 'group') .leftJoinAndSelect('connection.company', 'company') @@ -143,11 +143,11 @@ export const customConnectionRepositoryExtension: IConnectionRepository = { return await qb.getOne(); }, - async findOneById(connectionId: string): Promise { + async findOneById(connectionId: string): Promise { return await this.findOne({ where: { id: connectionId } }); }, - async findOneAgentConnectionByToken(connectionToken: string): Promise { + async findOneAgentConnectionByToken(connectionToken: string): Promise { const qb = this.createQueryBuilder('connection').leftJoinAndSelect('connection.agent', 'agent'); qb.andWhere('agent.token = :agentToken', { agentToken: connectionToken }); return await qb.getOne(); 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 95f352e7e..efaeda560 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 @@ -62,8 +62,8 @@ export class CreateConnectionUseCase try { const testResult = await dao.testConnect(); isConnectionTestedSuccessfully = testResult.result; - } catch (e) { - const text: string = e.message.toLowerCase(); + } catch (e: unknown) { + const text: string = (e instanceof Error ? e.message : String(e)).toLowerCase(); isConnectionTestedSuccessfully = false; if (text.includes('ssl required') || text.includes('ssl connection required')) { createConnectionData.connection_parameters.ssl = true; @@ -80,7 +80,7 @@ export class CreateConnectionUseCase } } } - let connectionCopy: ConnectionEntity = null; + let connectionCopy: ConnectionEntity | null = null; try { const createdConnection: ConnectionEntity = await buildConnectionEntity(createConnectionData, connectionAuthor); const savedConnection: ConnectionEntity = @@ -128,7 +128,7 @@ export class CreateConnectionUseCase const connectionRO = buildCreatedConnectionDs(savedConnection, token, masterPwd); return connectionRO; } finally { - if (isConnectionTestedSuccessfully && !isConnectionTypeAgent(connectionCopy.type)) { + if (connectionCopy && 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); diff --git a/backend/src/entities/connection/use-cases/test-connection.use.case.ts b/backend/src/entities/connection/use-cases/test-connection.use.case.ts index 434150131..289b6c77f 100644 --- a/backend/src/entities/connection/use-cases/test-connection.use.case.ts +++ b/backend/src/entities/connection/use-cases/test-connection.use.case.ts @@ -111,7 +111,7 @@ export class TestConnectionUseCase const updated = Object.assign(toUpdate, connectionData); const dataForProcessing: CreateConnectionDs = { connection_parameters: updated, - creation_info: null, + creation_info: null as unknown as CreateConnectionDs['creation_info'], }; const processed = (await processAWSConnection(dataForProcessing)).connection_parameters; Object.assign(updated, processed); @@ -123,10 +123,10 @@ export class TestConnectionUseCase inputData.update_info.authorId, inputData.connection_parameters.type, ); - } catch (e) { + } catch (e: unknown) { return { result: false, - message: `${Messages.CONNECTION_TEST_FAILED}${e ? e : ''}`, + message: `${Messages.CONNECTION_TEST_FAILED}${e instanceof Error ? e.message : String(e)}`, }; } } else { @@ -143,10 +143,10 @@ export class TestConnectionUseCase const dataForProcessing: CreateConnectionDs = { connection_parameters: connectionData, - creation_info: null, + creation_info: null as unknown as CreateConnectionDs['creation_info'], }; connectionData = (await processAWSConnection(dataForProcessing)).connection_parameters; - const dao = getDataAccessObject(connectionData as ConnectionEntity); + const dao = getDataAccessObject(connectionData); return await this.testConnection( dao, @@ -167,8 +167,8 @@ export class TestConnectionUseCase try { testResult = await dao.testConnect(); return testResult; - } catch (e) { - let text: string = e.message.toLowerCase(); + } catch (e: unknown) { + let text: string = (e instanceof Error ? e.message : String(e)).toLowerCase(); if (text.includes('ssl required') || text.includes('ssl connection required')) { connectionData.ssl = true; @@ -176,8 +176,8 @@ export class TestConnectionUseCase try { testResult = await dao.testConnect(); return testResult; - } catch (e) { - text = e.message; + } catch (e: unknown) { + text = e instanceof Error ? e.message : String(e); } } diff --git a/backend/src/entities/connection/utils/validate-create-connection-data.ts b/backend/src/entities/connection/utils/validate-create-connection-data.ts index 232fd5874..b32164371 100644 --- a/backend/src/entities/connection/utils/validate-create-connection-data.ts +++ b/backend/src/entities/connection/utils/validate-create-connection-data.ts @@ -90,9 +90,9 @@ export async function validateCreateConnectionData( } } -function validateConnectionType(type: string): string { +function validateConnectionType(type: string): boolean { if (process.env.NODE_ENV === 'test') { - return Object.keys(ConnectionTypeTestEnum).find((key) => key === type); + return !!Object.keys(ConnectionTypeTestEnum).find((key) => key === type); } - return Object.keys(ConnectionTypesEnum).find((key) => key === type); + return !!Object.keys(ConnectionTypesEnum).find((key) => key === type); } From da4790898cb785f767124472c072ee4f874ac369 Mon Sep 17 00:00:00 2001 From: Artem Niehrieiev Date: Mon, 23 Mar 2026 15:33:01 +0000 Subject: [PATCH 2/6] refactor: consolidate connection parameters into a new interface and update related data structures --- .../connection-parameters.ds.ts | 24 ++++++++++++++++++ .../data-structures/create-connection.ds.ts | 25 ++----------------- .../data-structures/found-connections.ds.ts | 13 +++++----- .../data-structures/update-connection.ds.ts | 25 ++----------------- .../application/dto/created-connection.dto.ts | 2 +- .../utils/build-created-connection.ds.ts | 3 ++- .../utils/build-found-connection.ds.ts | 3 ++- ...pdate-connection-entity-for-restoration.ts | 4 +-- 8 files changed, 41 insertions(+), 58 deletions(-) create mode 100644 backend/src/entities/connection/application/data-structures/connection-parameters.ds.ts diff --git a/backend/src/entities/connection/application/data-structures/connection-parameters.ds.ts b/backend/src/entities/connection/application/data-structures/connection-parameters.ds.ts new file mode 100644 index 000000000..10f7075c8 --- /dev/null +++ b/backend/src/entities/connection/application/data-structures/connection-parameters.ds.ts @@ -0,0 +1,24 @@ +import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; + +export interface ConnectionParametersDs { + title?: string; + masterEncryption?: boolean; + type: ConnectionTypesEnum; + host?: string; + port?: number; + username?: string; + password?: string; + database?: string; + schema?: string; + sid?: string; + ssh?: boolean; + privateSSHKey?: string; + sshHost?: string; + sshPort?: number; + sshUsername?: string; + ssl?: boolean; + cert?: string; + azure_encryption?: boolean; + authSource?: string; + dataCenter?: string; +} diff --git a/backend/src/entities/connection/application/data-structures/create-connection.ds.ts b/backend/src/entities/connection/application/data-structures/create-connection.ds.ts index dbfb12ede..3abfdc15d 100644 --- a/backend/src/entities/connection/application/data-structures/create-connection.ds.ts +++ b/backend/src/entities/connection/application/data-structures/create-connection.ds.ts @@ -1,28 +1,7 @@ -import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; +import { ConnectionParametersDs } from './connection-parameters.ds.js'; export class CreateConnectionDs { - connection_parameters: { - title: string; - masterEncryption: boolean; - type: ConnectionTypesEnum; - host: string; - port: number; - username: string; - password: string; - database: string; - schema: string; - sid: string; - ssh: boolean; - privateSSHKey: string; - sshHost: string; - sshPort: number; - sshUsername: string; - ssl: boolean; - cert: string; - azure_encryption: boolean; - authSource: string; - dataCenter: string; - }; + connection_parameters: ConnectionParametersDs; creation_info: { authorId: string; masterPwd: string; diff --git a/backend/src/entities/connection/application/data-structures/found-connections.ds.ts b/backend/src/entities/connection/application/data-structures/found-connections.ds.ts index d8462df66..eef0936b9 100644 --- a/backend/src/entities/connection/application/data-structures/found-connections.ds.ts +++ b/backend/src/entities/connection/application/data-structures/found-connections.ds.ts @@ -4,7 +4,6 @@ import { AccessLevelEnum } from '../../../../enums/index.js'; import { ConnectionPropertiesEntity } from '../../../connection-properties/connection-properties.entity.js'; import { FoundGroupDataWithUsersDs } from '../../../group/application/data-sctructures/found-user-groups.ds.js'; import { SimpleFoundUserInfoDs } from '../../../user/dto/found-user.dto.js'; -import { UserEntity } from '../../../user/user.entity.js'; export class FoundDirectConnectionsDs { @ApiProperty() @@ -17,7 +16,7 @@ export class FoundDirectConnectionsDs { masterEncryption: boolean; @ApiProperty({ enum: ConnectionTypesEnum }) - type?: ConnectionTypesEnum | string; + type?: ConnectionTypesEnum; @ApiProperty() host?: string; @@ -59,7 +58,7 @@ export class FoundDirectConnectionsDs { cert?: string; @ApiProperty({ required: false }) - author?: UserEntity | string; + author?: string; @ApiProperty({ required: false }) token?: string; @@ -94,7 +93,7 @@ export class FoundDirectConnectionsNonePermissionDs { title?: string; @ApiProperty() - type?: ConnectionTypesEnum | string; + type?: ConnectionTypesEnum; @ApiProperty() database: string; @@ -117,10 +116,10 @@ export class FoundAgentConnectionsDs { title?: string; @ApiProperty({ enum: ConnectionTypesEnum }) - type?: ConnectionTypesEnum | string; + type?: ConnectionTypesEnum; @ApiProperty({ required: false }) - author: UserEntity | string; + author?: string; @ApiProperty() token: string; @@ -143,7 +142,7 @@ export class FoundSipleConnectionInfoDS { title?: string; @ApiProperty({ enum: ConnectionTypesEnum }) - type?: ConnectionTypesEnum | string; + type?: ConnectionTypesEnum; @ApiProperty() isTestConnection: boolean; diff --git a/backend/src/entities/connection/application/data-structures/update-connection.ds.ts b/backend/src/entities/connection/application/data-structures/update-connection.ds.ts index 8fbed81b2..fd002455a 100644 --- a/backend/src/entities/connection/application/data-structures/update-connection.ds.ts +++ b/backend/src/entities/connection/application/data-structures/update-connection.ds.ts @@ -1,28 +1,7 @@ -import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; +import { ConnectionParametersDs } from './connection-parameters.ds.js'; export class UpdateConnectionDs { - connection_parameters: { - title: string; - masterEncryption: boolean; - type: ConnectionTypesEnum; - host: string; - port: number; - username: string; - password: string; - database: string; - schema: string; - sid: string; - ssh: boolean; - privateSSHKey: string; - sshHost: string; - sshPort: number; - sshUsername: string; - ssl: boolean; - cert: string; - azure_encryption: boolean; - authSource: string; - dataCenter: string; - }; + connection_parameters: ConnectionParametersDs; update_info: { authorId: string; connectionId: string; diff --git a/backend/src/entities/connection/application/dto/created-connection.dto.ts b/backend/src/entities/connection/application/dto/created-connection.dto.ts index 1a7566066..1679fc82f 100644 --- a/backend/src/entities/connection/application/dto/created-connection.dto.ts +++ b/backend/src/entities/connection/application/dto/created-connection.dto.ts @@ -27,7 +27,7 @@ export class CreatedConnectionDTO { masterEncryption: boolean; @ApiProperty({ enum: ConnectionTypesEnum }) - type: ConnectionTypesEnum | string; + type: ConnectionTypesEnum; @ApiProperty() host: string; diff --git a/backend/src/entities/connection/utils/build-created-connection.ds.ts b/backend/src/entities/connection/utils/build-created-connection.ds.ts index 68c2e4691..2942f16b6 100644 --- a/backend/src/entities/connection/utils/build-created-connection.ds.ts +++ b/backend/src/entities/connection/utils/build-created-connection.ds.ts @@ -1,3 +1,4 @@ +import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; import { Encryptor } from '../../../helpers/encryption/encryptor.js'; import { CreatedConnectionDTO } from '../application/dto/created-connection.dto.js'; import { ConnectionEntity } from '../connection.entity.js'; @@ -30,7 +31,7 @@ export function buildCreatedConnectionDs( ssl: connection.ssl, title: connection.title, token: token ? token : null, - type: connection.type, + type: connection.type as ConnectionTypesEnum, updatedAt: connection.updatedAt, username: connection.username, authSource: connection.authSource, diff --git a/backend/src/entities/connection/utils/build-found-connection.ds.ts b/backend/src/entities/connection/utils/build-found-connection.ds.ts index 0fffb24f8..baed750e4 100644 --- a/backend/src/entities/connection/utils/build-found-connection.ds.ts +++ b/backend/src/entities/connection/utils/build-found-connection.ds.ts @@ -1,3 +1,4 @@ +import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; import { FoundAgentConnectionsDs, FoundDirectConnectionsDs, @@ -27,7 +28,7 @@ export function buildFoundConnectionDs( ssl: connection.ssl, title: connection.title, token: connection.agent?.token, - type: connection.type, + type: connection.type as ConnectionTypesEnum, updatedAt: connection.updatedAt, username: connection.username, signing_key: connection.signing_key, diff --git a/backend/src/entities/connection/utils/update-connection-entity-for-restoration.ts b/backend/src/entities/connection/utils/update-connection-entity-for-restoration.ts index 47c548b30..d899d4790 100644 --- a/backend/src/entities/connection/utils/update-connection-entity-for-restoration.ts +++ b/backend/src/entities/connection/utils/update-connection-entity-for-restoration.ts @@ -1,5 +1,5 @@ import { Encryptor } from '../../../helpers/encryption/encryptor.js'; -import { isConnectionEntityAgent } from '../../../helpers/index.js'; +import { isConnectionTypeAgent } from '../../../helpers/index.js'; import { UpdateConnectionDs } from '../application/data-structures/update-connection.ds.js'; import { ConnectionEntity } from '../connection.entity.js'; @@ -17,7 +17,7 @@ export async function updateConnectionEntityForRestoration( toUpdate.ssh = connection_parameters.ssh; toUpdate.ssl = connection_parameters.ssl; toUpdate.isTestConnection = isTestConnection; - if (!isConnectionEntityAgent(connection_parameters)) { + if (!isConnectionTypeAgent(connection_parameters.type)) { toUpdate.masterEncryption = connection_parameters.masterEncryption; toUpdate.host = connection_parameters.host; toUpdate.port = connection_parameters.port; From b8ba30c1a4c2b75de62b67a6064950e3882958ac Mon Sep 17 00:00:00 2001 From: Artem Niehrieiev Date: Mon, 23 Mar 2026 15:53:16 +0000 Subject: [PATCH 3/6] refactor: update connection-related types and streamline use cases for improved type safety --- backend/src/entities/connection/connection.controller.ts | 5 ++--- backend/src/entities/connection/connection.entity.ts | 3 ++- .../connection/use-cases/find-all-connections.use.case.ts | 5 ++--- .../entities/connection/use-cases/use-cases.interfaces.ts | 4 ++-- .../connection/utils/build-created-connection.ds.ts | 7 +++---- .../entities/connection/utils/build-found-connection.ds.ts | 3 +-- 6 files changed, 12 insertions(+), 15 deletions(-) diff --git a/backend/src/entities/connection/connection.controller.ts b/backend/src/entities/connection/connection.controller.ts index 0771287a0..a7d972c7c 100644 --- a/backend/src/entities/connection/connection.controller.ts +++ b/backend/src/entities/connection/connection.controller.ts @@ -27,7 +27,6 @@ import { SentryInterceptor } from '../../interceptors/index.js'; import { SuccessResponse } from '../../microservices/saas-microservice/data-structures/common-responce.ds.js'; import { AmplitudeService } from '../amplitude/amplitude.service.js'; import { FoundGroupResponseDto } from '../group/dto/found-group-response.dto.js'; -import { IComplexPermission } from '../permission/permission.interface.js'; import { FindUserDs } from '../user/application/data-structures/find-user.ds.js'; import { FoundUserDto } from '../user/dto/found-user.dto.js'; import { CreateConnectionDs } from './application/data-structures/create-connection.ds.js'; @@ -457,7 +456,7 @@ export class ConnectionController { @QueryUuid('groupId') groupId: string, @UserId() userId: string, @MasterPassword() masterPwd: string, - ): Promise { + ): Promise { if (!connectionId || !groupId) { throw new BadRequestException(Messages.PARAMETER_MISSING); } @@ -481,7 +480,7 @@ export class ConnectionController { @QueryUuid('groupId') groupId: string, @UserId() userId: string, @MasterPassword() masterPwd: string, - ): Promise { + ): Promise { if (!connectionId || !groupId) { throw new BadRequestException(Messages.PARAMETER_MISSING); } diff --git a/backend/src/entities/connection/connection.entity.ts b/backend/src/entities/connection/connection.entity.ts index fe228177e..0bd346899 100644 --- a/backend/src/entities/connection/connection.entity.ts +++ b/backend/src/entities/connection/connection.entity.ts @@ -13,6 +13,7 @@ import { PrimaryColumn, Relation, } from 'typeorm'; +import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; import { Constants } from '../../helpers/constants/constants.js'; import { Encryptor } from '../../helpers/encryption/encryptor.js'; import { isConnectionTypeAgent } from '../../helpers/index.js'; @@ -43,7 +44,7 @@ export class ConnectionEntity { masterEncryption: boolean; @Column({ default: null }) - type?: string | null; + type?: ConnectionTypesEnum | null; @Column({ default: null }) host?: string | null; diff --git a/backend/src/entities/connection/use-cases/find-all-connections.use.case.ts b/backend/src/entities/connection/use-cases/find-all-connections.use.case.ts index 98933df6c..7e22c3b5e 100644 --- a/backend/src/entities/connection/use-cases/find-all-connections.use.case.ts +++ b/backend/src/entities/connection/use-cases/find-all-connections.use.case.ts @@ -10,7 +10,6 @@ import { AmplitudeService } from '../../amplitude/amplitude.service.js'; import { CedarPermissionsService } from '../../cedar-authorization/cedar-permissions.service.js'; import { generateCedarPolicyForGroup } from '../../cedar-authorization/cedar-policy-generator.js'; import { GroupEntity } from '../../group/group.entity.js'; -import { CreateUserDs } from '../../user/application/data-structures/create-user.ds.js'; import { FindUserDs } from '../../user/application/data-structures/find-user.ds.js'; import { UserRoleEnum } from '../../user/enums/user-role.enum.js'; import { buildConnectionEntitiesFromTestDtos } from '../../user/utils/build-connection-entities-from-test-dtos.js'; @@ -26,7 +25,7 @@ export type FilteredConnection = RequiredConnectionKeys & OptionalConnectionKeys @Injectable() export class FindAllConnectionsUseCase - extends AbstractUseCase + extends AbstractUseCase implements IFindConnections { constructor( @@ -38,7 +37,7 @@ export class FindAllConnectionsUseCase super(); } - protected async implementation(userData: CreateUserDs | FindUserDs): Promise { + protected async implementation(userData: FindUserDs): Promise { const user = await this._dbContext.userRepository.findOneUserByIdWithCompany(userData.id); if (!user) { throw new InternalServerErrorException(Messages.USER_NOT_FOUND); diff --git a/backend/src/entities/connection/use-cases/use-cases.interfaces.ts b/backend/src/entities/connection/use-cases/use-cases.interfaces.ts index 2d3df269f..0088bec6f 100644 --- a/backend/src/entities/connection/use-cases/use-cases.interfaces.ts +++ b/backend/src/entities/connection/use-cases/use-cases.interfaces.ts @@ -1,7 +1,7 @@ import { InTransactionEnum } from '../../../enums/index.js'; import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; import { FoundGroupResponseDto } from '../../group/dto/found-group-response.dto.js'; -import { CreateUserDs } from '../../user/application/data-structures/create-user.ds.js'; +import { FindUserDs } from '../../user/application/data-structures/find-user.ds.js'; import { FoundUserDto } from '../../user/dto/found-user.dto.js'; import { CreateConnectionDs } from '../application/data-structures/create-connection.ds.js'; import { CreateGroupInConnectionDs } from '../application/data-structures/create-group-in-connection.ds.js'; @@ -26,7 +26,7 @@ import { ValidationResultRo } from '../application/dto/validation-result.ro.js'; import { TokenValidationResult } from './validate-connection-token.use.case.js'; export interface IFindConnections { - execute(user: CreateUserDs, inTransaction: InTransactionEnum): Promise; + execute(user: FindUserDs, inTransaction: InTransactionEnum): Promise; } export interface IFindUsersInConnection { diff --git a/backend/src/entities/connection/utils/build-created-connection.ds.ts b/backend/src/entities/connection/utils/build-created-connection.ds.ts index 2942f16b6..6ad986e90 100644 --- a/backend/src/entities/connection/utils/build-created-connection.ds.ts +++ b/backend/src/entities/connection/utils/build-created-connection.ds.ts @@ -1,12 +1,11 @@ -import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; import { Encryptor } from '../../../helpers/encryption/encryptor.js'; import { CreatedConnectionDTO } from '../application/dto/created-connection.dto.js'; import { ConnectionEntity } from '../connection.entity.js'; export function buildCreatedConnectionDs( connection: ConnectionEntity, - token: string, - masterPwd: string, + token: string | null | undefined, + masterPwd: string | null | undefined, ): CreatedConnectionDTO { if (connection.masterEncryption && masterPwd) { connection = Encryptor.decryptConnectionCredentials(connection, masterPwd); @@ -31,7 +30,7 @@ export function buildCreatedConnectionDs( ssl: connection.ssl, title: connection.title, token: token ? token : null, - type: connection.type as ConnectionTypesEnum, + type: connection.type, updatedAt: connection.updatedAt, username: connection.username, authSource: connection.authSource, diff --git a/backend/src/entities/connection/utils/build-found-connection.ds.ts b/backend/src/entities/connection/utils/build-found-connection.ds.ts index baed750e4..0fffb24f8 100644 --- a/backend/src/entities/connection/utils/build-found-connection.ds.ts +++ b/backend/src/entities/connection/utils/build-found-connection.ds.ts @@ -1,4 +1,3 @@ -import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; import { FoundAgentConnectionsDs, FoundDirectConnectionsDs, @@ -28,7 +27,7 @@ export function buildFoundConnectionDs( ssl: connection.ssl, title: connection.title, token: connection.agent?.token, - type: connection.type as ConnectionTypesEnum, + type: connection.type, updatedAt: connection.updatedAt, username: connection.username, signing_key: connection.signing_key, From e91d394fc4120fdf286dfb9921425d3735be2198 Mon Sep 17 00:00:00 2001 From: Artem Niehrieiev Date: Mon, 23 Mar 2026 16:01:11 +0000 Subject: [PATCH 4/6] refactor: correct typos in connection-related class names and update DTO properties for optional fields --- .../application/data-structures/found-company-info.ds.ts | 4 ++-- .../company-info/utils/build-found-company-info-ds.ts | 4 ++-- .../application/data-structures/found-connections.ds.ts | 2 +- .../connection/application/dto/delete-connection.dto.ts | 8 ++++---- backend/src/entities/connection/connection.entity.ts | 2 +- backend/src/entities/connection/connection.module.ts | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/backend/src/entities/company-info/application/data-structures/found-company-info.ds.ts b/backend/src/entities/company-info/application/data-structures/found-company-info.ds.ts index be9d1d55b..c396799ec 100644 --- a/backend/src/entities/company-info/application/data-structures/found-company-info.ds.ts +++ b/backend/src/entities/company-info/application/data-structures/found-company-info.ds.ts @@ -1,5 +1,5 @@ import { ApiProperty } from '@nestjs/swagger'; -import { FoundSipleConnectionInfoDS } from '../../../connection/application/data-structures/found-connections.ds.js'; +import { FoundSimpleConnectionInfoDS } from '../../../connection/application/data-structures/found-connections.ds.js'; import { FoundCompanyImageInfo } from '../dto/found-company-logo.ro.js'; import { FoundInvitationInCompanyDs } from './found-invitation-in-company.ds.js'; @@ -49,7 +49,7 @@ export class FoundUserCompanyInfoDs { export class FoundUserFullCompanyInfoDs extends FoundUserCompanyInfoDs { @ApiProperty({ isArray: true }) - connections: Array; + connections: Array; @ApiProperty({ isArray: true, type: FoundInvitationInCompanyDs }) invitations: Array; diff --git a/backend/src/entities/company-info/utils/build-found-company-info-ds.ts b/backend/src/entities/company-info/utils/build-found-company-info-ds.ts index a0d5da821..e399ef3b9 100644 --- a/backend/src/entities/company-info/utils/build-found-company-info-ds.ts +++ b/backend/src/entities/company-info/utils/build-found-company-info-ds.ts @@ -1,5 +1,5 @@ import { FoundSassCompanyInfoDS } from '../../../microservices/gateways/saas-gateway.ts/data-structures/found-saas-company-info.ds.js'; -import { FoundSipleConnectionInfoDS } from '../../connection/application/data-structures/found-connections.ds.js'; +import { FoundSimpleConnectionInfoDS } from '../../connection/application/data-structures/found-connections.ds.js'; import { UserRoleEnum } from '../../user/enums/user-role.enum.js'; import { buildSimpleUserInfoDs } from '../../user/utils/build-created-user.ds.js'; import { @@ -26,7 +26,7 @@ export function buildFoundCompanyFullInfoDs( companyCustomDomain, userRole, ) as any; - const connectionsRO: Array = companyInfoFromCore.connections.map((connection) => { + const connectionsRO: Array = companyInfoFromCore.connections.map((connection) => { return { id: connection.id, createdAt: connection.createdAt, diff --git a/backend/src/entities/connection/application/data-structures/found-connections.ds.ts b/backend/src/entities/connection/application/data-structures/found-connections.ds.ts index eef0936b9..f5440c426 100644 --- a/backend/src/entities/connection/application/data-structures/found-connections.ds.ts +++ b/backend/src/entities/connection/application/data-structures/found-connections.ds.ts @@ -134,7 +134,7 @@ export class FoundAgentConnectionsDs { connection_properties: ConnectionPropertiesEntity; } -export class FoundSipleConnectionInfoDS { +export class FoundSimpleConnectionInfoDS { @ApiProperty() id: string; diff --git a/backend/src/entities/connection/application/dto/delete-connection.dto.ts b/backend/src/entities/connection/application/dto/delete-connection.dto.ts index eb8161128..354d8bff9 100644 --- a/backend/src/entities/connection/application/dto/delete-connection.dto.ts +++ b/backend/src/entities/connection/application/dto/delete-connection.dto.ts @@ -4,11 +4,11 @@ import { IsOptional, IsString } from 'class-validator'; export class DeleteConnectionReasonDto { @IsOptional() @IsString() - @ApiProperty() - reason: string; + @ApiProperty({ required: false }) + reason?: string; @IsOptional() @IsString() - @ApiProperty() - message: string; + @ApiProperty({ required: false }) + message?: string; } diff --git a/backend/src/entities/connection/connection.entity.ts b/backend/src/entities/connection/connection.entity.ts index 0bd346899..a48774e0b 100644 --- a/backend/src/entities/connection/connection.entity.ts +++ b/backend/src/entities/connection/connection.entity.ts @@ -107,7 +107,7 @@ export class ConnectionEntity { saved_table_info: number; @Column({ default: null }) - signing_key: string; + signing_key: string | null; @Column({ default: null }) authSource?: string | null; diff --git a/backend/src/entities/connection/connection.module.ts b/backend/src/entities/connection/connection.module.ts index bf4d87b1e..75510367a 100644 --- a/backend/src/entities/connection/connection.module.ts +++ b/backend/src/entities/connection/connection.module.ts @@ -134,7 +134,7 @@ import { ValidateConnectionTokenUseCase } from './use-cases/validate-connection- controllers: [ConnectionController], }) export class ConnectionModule implements NestModule { - public configure(consumer: MiddlewareConsumer): any { + public configure(consumer: MiddlewareConsumer): void { consumer .apply(AuthMiddleware) .forRoutes( From f6a358f30efaf1dca4f064cd8bf05f11736d94ef Mon Sep 17 00:00:00 2001 From: Artem Niehrieiev Date: Mon, 23 Mar 2026 16:06:21 +0000 Subject: [PATCH 5/6] refactor: import Repository from typeorm and enhance customConnectionRepositoryExtension type definition --- .../repository/custom-connection-repository-extension.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/src/entities/connection/repository/custom-connection-repository-extension.ts b/backend/src/entities/connection/repository/custom-connection-repository-extension.ts index b56ca0848..159669333 100644 --- a/backend/src/entities/connection/repository/custom-connection-repository-extension.ts +++ b/backend/src/entities/connection/repository/custom-connection-repository-extension.ts @@ -1,3 +1,4 @@ +import { Repository } from 'typeorm'; import { Messages } from '../../../exceptions/text/messages.js'; import { Constants } from '../../../helpers/constants/constants.js'; import { Encryptor } from '../../../helpers/encryption/encryptor.js'; @@ -7,7 +8,8 @@ import { ConnectionEntity } from '../connection.entity.js'; import { isTestConnectionUtil } from '../utils/is-test-connection-util.js'; import { IConnectionRepository } from './connection.repository.interface.js'; -export const customConnectionRepositoryExtension: IConnectionRepository = { +export const customConnectionRepositoryExtension: IConnectionRepository & + ThisType & IConnectionRepository> = { async saveNewConnection(connection: ConnectionEntity): Promise { const savedConnection = await this.save(connection); if (!isConnectionTypeAgent(savedConnection.type)) { From f7721dac4874e8532fc437a2f94a91ec6ea90b1e Mon Sep 17 00:00:00 2001 From: Artem Niehrieiev Date: Mon, 23 Mar 2026 16:18:48 +0000 Subject: [PATCH 6/6] refactor: enhance error handling with type safety in connection use cases --- .../src/entities/connection/connection.controller.ts | 5 +++-- .../use-cases/find-all-users-in-connection.use.case.ts | 10 +++++----- .../use-cases/find-one-connection.use.case.ts | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/backend/src/entities/connection/connection.controller.ts b/backend/src/entities/connection/connection.controller.ts index a7d972c7c..fe6ce9a29 100644 --- a/backend/src/entities/connection/connection.controller.ts +++ b/backend/src/entities/connection/connection.controller.ts @@ -536,10 +536,11 @@ export class ConnectionController { }; try { await validateCreateConnectionData(inputData); - } catch (e) { + } catch (e: unknown) { + const err = e as { response?: { message?: string }; message?: string }; return { result: false, - message: e?.response?.message || e?.message || Messages.CONNECTION_TYPE_INVALID, + message: err?.response?.message || err?.message || Messages.CONNECTION_TYPE_INVALID, }; } const result = await this.testConnectionUseCase.execute(inputData, InTransactionEnum.OFF); diff --git a/backend/src/entities/connection/use-cases/find-all-users-in-connection.use.case.ts b/backend/src/entities/connection/use-cases/find-all-users-in-connection.use.case.ts index e257afe78..60a00b600 100644 --- a/backend/src/entities/connection/use-cases/find-all-users-in-connection.use.case.ts +++ b/backend/src/entities/connection/use-cases/find-all-users-in-connection.use.case.ts @@ -7,6 +7,8 @@ import { UserEntity } from '../../user/user.entity.js'; import { buildFoundUserDto } from '../../user/utils/build-found-user.dto.js'; import { IFindUsersInConnection } from './use-cases.interfaces.js'; +type UserWithoutRelations = Omit; + @Injectable() export class FindAllUsersInConnectionUseCase extends AbstractUseCase> @@ -20,10 +22,8 @@ export class FindAllUsersInConnectionUseCase } protected async implementation(connectionId: string): Promise> { - const userInConnection = await this._dbContext.userRepository.findAllUsersInConnection(connectionId); - return userInConnection.map((user) => { - //todo fix type after repository types are fixed - return buildFoundUserDto(user as UserEntity); - }); + const userInConnection: UserWithoutRelations[] = + await this._dbContext.userRepository.findAllUsersInConnection(connectionId); + return userInConnection.map((user) => buildFoundUserDto(user as UserEntity)); } } diff --git a/backend/src/entities/connection/use-cases/find-one-connection.use.case.ts b/backend/src/entities/connection/use-cases/find-one-connection.use.case.ts index 3ce8dcced..e9c65d9d9 100644 --- a/backend/src/entities/connection/use-cases/find-one-connection.use.case.ts +++ b/backend/src/entities/connection/use-cases/find-one-connection.use.case.ts @@ -85,7 +85,7 @@ export class FindOneConnectionUseCase if (filteredConnection.masterEncryption && inputData.masterPwd && accessLevel !== AccessLevelEnum.none) { try { filteredConnection = Encryptor.decryptConnectionCredentials(connection, inputData.masterPwd); - } catch (e) { + } catch (e: unknown) { console.error('-> Error decrypting connection credentials', e); throw new HttpException( {