Skip to content

Commit 6f20a9c

Browse files
authored
Merge pull request #1686 from rocket-admin/backend_refactoring_ts
Backend refactoring ts
2 parents c021a6e + 61015bb commit 6f20a9c

File tree

44 files changed

+261
-255
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+261
-255
lines changed

backend/src/common/application/global-database-context.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { ConnectionPropertiesEntity } from '../../entities/connection-properties
3131
import { IConnectionPropertiesRepository } from '../../entities/connection-properties/repository/connection-properties.repository.interface.js';
3232
import { customConnectionPropertiesRepositoryExtension } from '../../entities/connection-properties/repository/custom-connection-properties-repository-extension.js';
3333
import { CustomFieldsEntity } from '../../entities/custom-field/custom-fields.entity.js';
34-
import { cusomFieldsCustomRepositoryExtension } from '../../entities/custom-field/repository/custom-field-repository-extension.js';
34+
import { customFieldsCustomRepositoryExtension } from '../../entities/custom-field/repository/custom-field-repository-extension.js';
3535
import { ICustomFieldsRepository } from '../../entities/custom-field/repository/custom-fields-repository.interface.js';
3636
import { EmailVerificationEntity } from '../../entities/email/email-verification.entity.js';
3737
import { IEmailVerificationRepository } from '../../entities/email/repository/email-verification.repository.interface.js';
@@ -192,7 +192,7 @@ export class GlobalDatabaseContext implements IGlobalDatabaseContext {
192192
.extend(customConnectionPropertiesRepositoryExtension);
193193
this._customFieldsRepository = this.appDataSource
194194
.getRepository(CustomFieldsEntity)
195-
.extend(cusomFieldsCustomRepositoryExtension);
195+
.extend(customFieldsCustomRepositoryExtension);
196196
this._tableLogsRepository = this.appDataSource
197197
.getRepository(TableLogsEntity)
198198
.extend(tableLogsCustomRepositoryExtension);

backend/src/entities/agent/agent.entity.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,26 @@ export class AgentEntity {
2525
@Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
2626
updatedAt: Date;
2727

28+
private _tokenChanged = false;
29+
30+
setToken(token: string): void {
31+
this.token = token;
32+
this._tokenChanged = true;
33+
}
34+
2835
@BeforeInsert()
2936
encryptToken(): void {
3037
this.token = Encryptor.hashDataHMAC(this.token);
38+
this._tokenChanged = false;
3139
}
3240

3341
@BeforeUpdate()
3442
updateTimestampAndEncryptToken(): void {
3543
this.updatedAt = new Date();
36-
this.token = Encryptor.hashDataHMAC(this.token);
44+
if (this._tokenChanged) {
45+
this.token = Encryptor.hashDataHMAC(this.token);
46+
this._tokenChanged = false;
47+
}
3748
}
3849

3950
@OneToOne(

backend/src/entities/agent/agent.module.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
1+
import { Module } from '@nestjs/common';
22
import { TypeOrmModule } from '@nestjs/typeorm';
3-
import { AuthMiddleware } from '../../authorization/index.js';
43
import { GlobalDatabaseContext } from '../../common/application/global-database-context.js';
54
import { BaseType } from '../../common/data-injection.tokens.js';
65
import { LogOutEntity } from '../log-out/log-out.entity.js';
@@ -17,8 +16,4 @@ import { AgentEntity } from './agent.entity.js';
1716
],
1817
exports: [],
1918
})
20-
export class AgentModule implements NestModule {
21-
public configure(consumer: MiddlewareConsumer): any {
22-
consumer.apply(AuthMiddleware).forRoutes();
23-
}
24-
}
19+
export class AgentModule {}

backend/src/entities/agent/repository/agent.repository.interface.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ConnectionTypeTestEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js';
12
import { ConnectionEntity } from '../../connection/connection.entity.js';
23
import { AgentEntity } from '../agent.entity.js';
34

@@ -7,4 +8,6 @@ export interface IAgentRepository {
78
createNewAgentForConnectionAndReturnToken(connection: ConnectionEntity): Promise<string>;
89

910
renewOrCreateConnectionToken(connectionId: string): Promise<string>;
11+
12+
getTestAgentToken(connectionType: ConnectionTypeTestEnum): string;
1013
}

backend/src/entities/agent/repository/custom-agent-repository-extension.ts

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,18 @@ import { ConnectionTypeTestEnum } from '@rocketadmin/shared-code/dist/src/shared
22
import { nanoid } from 'nanoid';
33
import { ConnectionEntity } from '../../connection/connection.entity.js';
44
import { AgentEntity } from '../agent.entity.js';
5+
import { IAgentRepository } from './agent.repository.interface.js';
56

6-
export const customAgentRepositoryExtension = {
7-
async saveNewAgent(agent: AgentEntity): Promise<AgentEntity> {
8-
return await this.save(agent);
9-
},
10-
7+
export const customAgentRepositoryExtension: IAgentRepository = {
118
async createNewAgentForConnectionAndReturnToken(connection: ConnectionEntity): Promise<string> {
129
const newAgent = await this.createNewAgentForConnection(connection);
1310
return newAgent.token;
1411
},
1512

1613
async createNewAgentForConnection(connection: ConnectionEntity): Promise<AgentEntity> {
1714
const agent = new AgentEntity();
18-
let token = nanoid(64);
19-
if (process.env.NODE_ENV !== 'test') {
20-
agent.token = token;
21-
} else {
22-
token = this.getTestAgentToken(connection.type);
23-
agent.token = token;
24-
}
15+
const token = process.env.NODE_ENV !== 'test' ? nanoid(64) : this.getTestAgentToken(connection.type);
16+
agent.setToken(token);
2517
agent.connection = connection;
2618
const savedAgent = await this.save(agent);
2719
savedAgent.token = token;
@@ -42,7 +34,7 @@ export const customAgentRepositoryExtension = {
4234
return await this.createNewAgentForConnectionAndReturnToken(foundConnection);
4335
} else {
4436
const newToken = nanoid(64);
45-
foundAgent.token = newToken;
37+
foundAgent.setToken(newToken);
4638
await this.save(foundAgent);
4739
return newToken;
4840
}

backend/src/entities/amplitude/amplitude.service.ts

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,56 @@
11
import Amplitude from '@amplitude/node';
2-
import { Injectable } from '@nestjs/common';
2+
import { Injectable, OnModuleInit } from '@nestjs/common';
33
import { InjectRepository } from '@nestjs/typeorm';
44
import { Repository } from 'typeorm';
55
import { AmplitudeEventTypeEnum } from '../../enums/index.js';
66
import { UserEntity } from '../user/user.entity.js';
77

8+
export interface AmplitudeLogOptions {
9+
user_email?: string;
10+
tablesCount?: number;
11+
reason?: string;
12+
message?: string;
13+
operationCount?: number;
14+
}
15+
816
@Injectable()
9-
export class AmplitudeService {
17+
export class AmplitudeService implements OnModuleInit {
18+
private client: ReturnType<typeof Amplitude.init>;
19+
1020
constructor(
1121
@InjectRepository(UserEntity)
1222
private readonly userRepository: Repository<UserEntity>,
1323
) {}
1424

15-
public async formAndSendLogRecord(event_type: AmplitudeEventTypeEnum, user_id: string, options = null) {
25+
public onModuleInit(): void {
26+
if (process.env.AMPLITUDE_API_KEY) {
27+
this.client = Amplitude.init(process.env.AMPLITUDE_API_KEY);
28+
}
29+
}
30+
31+
public async formAndSendLogRecord(
32+
event_type: AmplitudeEventTypeEnum,
33+
user_id: string,
34+
options?: AmplitudeLogOptions,
35+
): Promise<void> {
1636
try {
1737
if (process.env.NODE_ENV === 'test') return;
1838
let user_email = (await this.userRepository.findOne({ where: { id: user_id } }))?.email;
1939
if (!user_email && options) {
20-
user_email = options?.user_email;
40+
user_email = options.user_email;
2141
}
22-
let event_properties;
42+
let event_properties: Record<string, unknown> | undefined;
2343
if (user_email) {
2444
event_properties = {
2545
user_properties: {
26-
email: user_email ? user_email : 'unknown',
27-
tablesCount: options?.tablesCount ? options.tablesCount : undefined,
28-
reason: options?.reason ? options?.reason : undefined,
29-
message: options?.message ? options.message : undefined,
46+
email: user_email ?? 'unknown',
47+
tablesCount: options?.tablesCount,
48+
reason: options?.reason,
49+
message: options?.message,
3050
},
3151
};
3252
}
33-
if (options?.operationCount && options?.operationCount > 0) {
53+
if (options?.operationCount && options.operationCount > 0) {
3454
const promisesArr = Array.from(Array(options.operationCount), () =>
3555
this.sendLog(event_type, user_id, event_properties),
3656
);
@@ -43,21 +63,19 @@ export class AmplitudeService {
4363
}
4464
}
4565

46-
private async sendLog(eventType, cognitoUserName, eventProperties) {
47-
const client = Amplitude.init(process.env.AMPLITUDE_API_KEY);
66+
private async sendLog(
67+
eventType: AmplitudeEventTypeEnum,
68+
userId: string,
69+
eventProperties?: Record<string, unknown>,
70+
): Promise<void> {
71+
if (!this.client) return;
4872
try {
49-
client
50-
.logEvent({
51-
event_type: eventType,
52-
user_id: cognitoUserName,
53-
event_properties: eventProperties ? eventProperties : undefined,
54-
})
55-
.catch((e) => {
56-
throw new Error(e);
57-
});
58-
client.flush().catch((e) => {
59-
throw new Error(e);
73+
await this.client.logEvent({
74+
event_type: eventType,
75+
user_id: userId,
76+
event_properties: eventProperties,
6077
});
78+
await this.client.flush();
6179
} catch (e) {
6280
console.error(e);
6381
}

backend/src/entities/company-info/company-info-helper.service.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ export class CompanyInfoHelperService {
2121

2222
const companyInformationFromSaaS = await this.saasCompanyGatewayService.getCompanyInfo(companyId);
2323

24-
const countUsersInCompany = await this._dbContext.userRepository.countUsersInCompany(companyId);
25-
const countInvitationsInCompany =
26-
await this._dbContext.invitationInCompanyRepository.countNonExpiredInvitationsInCompany(companyId);
24+
const [countUsersInCompany, countInvitationsInCompany] = await Promise.all([
25+
this._dbContext.userRepository.countUsersInCompany(companyId),
26+
this._dbContext.invitationInCompanyRepository.countNonExpiredInvitationsInCompany(companyId),
27+
]);
2728

2829
if (companyInformationFromSaaS.subscriptionLevel === SubscriptionLevelEnum.FREE_PLAN) {
2930
return countUsersInCompany + countInvitationsInCompany < Constants.FREE_PLAN_USERS_COUNT;

backend/src/entities/company-info/company-info.controller.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ import {
8181
IRemoveUserFromCompany,
8282
IRevokeUserInvitationInCompany,
8383
ISuspendUsersInCompany,
84+
IUnsuspendUsersInCompany,
8485
IToggleCompanyTestConnectionsMode,
8586
IUpdateCompanyName,
8687
IUpdateUsers2faStatusInCompany,
@@ -128,7 +129,7 @@ export class CompanyInfoController {
128129
@Inject(UseCaseType.SUSPEND_USERS_IN_COMPANY)
129130
private readonly suspendUsersInCompanyUseCase: ISuspendUsersInCompany,
130131
@Inject(UseCaseType.UNSUSPEND_USERS_IN_COMPANY)
131-
private readonly unSuspendUsersInCompanyUseCase: ISuspendUsersInCompany,
132+
private readonly unSuspendUsersInCompanyUseCase: IUnsuspendUsersInCompany,
132133
@Inject(UseCaseType.TOGGLE_TEST_CONNECTIONS_DISPLAY_MODE_IN_COMPANY)
133134
private readonly toggleTestConnectionsCompanyDisplayModeUseCase: IToggleCompanyTestConnectionsMode,
134135
@Inject(UseCaseType.UPLOAD_COMPANY_LOGO)

backend/src/entities/company-info/invitation-in-company/repository/invitation-in-company-custom-repository-extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export const invitationInCompanyCustomRepositoryExtension: IInvitationInCompanyR
5252
.leftJoinAndSelect('invitation_in_company.company', 'company')
5353
.leftJoinAndSelect('company.users', 'users')
5454
.where("invitation_in_company.createdAt > NOW() - INTERVAL '1 day'")
55-
.where('invitation_in_company.verification_string = :verificationString', { verificationString });
55+
.andWhere('invitation_in_company.verification_string = :verificationString', { verificationString });
5656
return await qb.getOne();
5757
},
5858

backend/src/entities/company-info/repository/company-info-custom-repository.extension.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,6 @@ export const companyInfoRepositoryExtension: ICompanyInfoRepository = {
2626
.getOne();
2727
},
2828

29-
async finOneCompanyInfoByUserId(userId: string): Promise<CompanyInfoEntity> {
30-
return await this.createQueryBuilder('company_info')
31-
.leftJoinAndSelect('company_info.users', 'users')
32-
.where('users.id = :userId', { userId })
33-
.getOne();
34-
},
35-
3629
async findCompanyInfoByUserId(userId: string): Promise<CompanyInfoEntity> {
3730
return await this.createQueryBuilder('company_info')
3831
.leftJoinAndSelect('company_info.users', 'users')
@@ -94,9 +87,10 @@ export const companyInfoRepositoryExtension: ICompanyInfoRepository = {
9487
.andWhere('connections.isTestConnection IS FALSE')
9588
.andWhere('connections.is_frozen IS FALSE')
9689
.getMany();
97-
return foundCompaniesWithPaidConnections.map((companyInfo: CompanyInfoEntity) => {
98-
return companyInfo.connections;
99-
});
90+
return foundCompaniesWithPaidConnections
91+
.map((companyInfo: CompanyInfoEntity) => companyInfo.connections)
92+
.filter(Boolean)
93+
.flat();
10094
},
10195

10296
async findCompanyFrozenPaidConnections(companyIds: Array<string>): Promise<Array<ConnectionEntity>> {
@@ -108,9 +102,10 @@ export const companyInfoRepositoryExtension: ICompanyInfoRepository = {
108102
.andWhere('connections.isTestConnection IS FALSE')
109103
.andWhere('connections.is_frozen IS TRUE')
110104
.getMany();
111-
return foundCompaniesWithPaidConnections.map((companyInfo: CompanyInfoEntity) => {
112-
return companyInfo.connections;
113-
});
105+
return foundCompaniesWithPaidConnections
106+
.map((companyInfo: CompanyInfoEntity) => companyInfo.connections)
107+
.filter(Boolean)
108+
.flat();
114109
},
115110

116111
async findCompanyWithLogo(companyId: string): Promise<CompanyInfoEntity> {

0 commit comments

Comments
 (0)