Skip to content

Commit abba2c9

Browse files
committed
feat: modified usages of db queries to use tenant specific connection
1 parent dd1ad85 commit abba2c9

19 files changed

+91
-61
lines changed

src/authentication/service/password.auth.service.ts

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
} from '../exception/userauth.exception';
2626
import { Authenticatable } from '../interfaces/authenticatable';
2727
import { TokenService } from './token.service';
28+
import { getConnection } from '../../util/database.connection';
2829

2930
@Injectable()
3031
export default class PasswordAuthService implements Authenticatable {
@@ -86,31 +87,34 @@ export default class PasswordAuthService implements Authenticatable {
8687
userFromInput.lastName = userDetails.lastName;
8788
userFromInput.status = Status.INVITED;
8889
let invitationToken: { token: any; tokenExpiryTime?: any };
89-
const transaction = await this.dataSource.manager.transaction(async () => {
90-
const savedUser = await this.userService.createUser(userFromInput);
91-
invitationToken = this.authenticationHelper.generateInvitationToken(
92-
{ id: savedUser.id },
93-
this.configService.get('INVITATION_TOKEN_EXPTIME'),
94-
);
95-
await this.userService.updateField(
96-
savedUser.id,
97-
'inviteToken',
98-
invitationToken.token,
99-
);
100-
const user = await this.userService.getUserById(savedUser.id);
101-
const userResponse = {
102-
id: user.id,
103-
firstName: user.firstName,
104-
lastName: user.lastName,
105-
inviteToken: user?.inviteToken,
106-
status: user.status,
107-
};
108-
return {
109-
inviteToken: invitationToken.token,
110-
tokenExpiryTime: invitationToken.tokenExpiryTime,
111-
user: userResponse,
112-
};
113-
});
90+
const transaction = await (await getConnection()).manager.transaction(
91+
async () => {
92+
const savedUser = await this.userService.createUser(userFromInput);
93+
invitationToken = this.authenticationHelper.generateInvitationToken(
94+
{ id: savedUser.id },
95+
this.configService.get('INVITATION_TOKEN_EXPTIME'),
96+
);
97+
await this.userService.updateField(
98+
savedUser.id,
99+
'inviteToken',
100+
invitationToken.token,
101+
);
102+
const user = await this.userService.getUserById(savedUser.id);
103+
const userResponse = {
104+
id: user.id,
105+
firstName: user.firstName,
106+
lastName: user.lastName,
107+
inviteToken: user?.inviteToken,
108+
status: user.status,
109+
tenantId: user.tenantId,
110+
};
111+
return {
112+
inviteToken: invitationToken.token,
113+
tokenExpiryTime: invitationToken.tokenExpiryTime,
114+
user: userResponse,
115+
};
116+
},
117+
);
114118
return transaction;
115119
}
116120

src/authorization/repository/base.repository.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
import { DataSource, EntityTarget, ObjectLiteral, Repository } from 'typeorm';
1+
import {
2+
DataSource,
3+
EntityTarget,
4+
ObjectLiteral,
5+
Repository,
6+
SelectQueryBuilder,
7+
QueryRunner,
8+
SaveOptions,
9+
DeepPartial,
10+
} from 'typeorm';
211
import { getConnection } from '../../util/database.connection';
312

413
export class BaseRepository<T extends ObjectLiteral> extends Repository<T> {
@@ -53,4 +62,17 @@ export class BaseRepository<T extends ObjectLiteral> extends Repository<T> {
5362
const repository = await this.getDynamicRepository();
5463
return repository.count(options);
5564
}
65+
66+
async getQueryBuilder(
67+
alias?: string,
68+
queryRunner?: QueryRunner,
69+
): Promise<SelectQueryBuilder<T>> {
70+
const repository = await this.getDynamicRepository();
71+
return repository.createQueryBuilder(alias, queryRunner);
72+
}
73+
74+
async save(entity: any, options?: SaveOptions): Promise<any> {
75+
const repository = await this.getDynamicRepository();
76+
return repository.save(entity, options);
77+
}
5678
}

src/authorization/repository/group.repository.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export class GroupRepository extends BaseRepository<Group> {
2929
}
3030

3131
async getGroupsForUserId(userId: string): Promise<Group[]> {
32-
return this.createQueryBuilder('group')
32+
return (await this.getQueryBuilder('group'))
3333
.leftJoinAndSelect(UserGroup, 'userGroup', 'group.id = userGroup.groupId')
3434
.where('userGroup.userId = :userId', { userId })
3535
.getMany();

src/authorization/repository/groupRole.repository.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export class GroupRoleRepository extends BaseRepository<GroupRole> {
1111
}
1212

1313
async getGroupCountForRoleId(roleId: string): Promise<number> {
14-
return this.createQueryBuilder('groupRole')
14+
return (await this.getQueryBuilder('groupRole'))
1515
.innerJoinAndSelect(Group, 'group', 'group.id = groupRole.groupId')
1616
.where('groupRole.roleId= :roleId', { roleId })
1717
.getCount();

src/authorization/repository/permission.repository.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export class PermissionRepository extends BaseRepository<Permission> {
5050
}
5151

5252
async getPermissionsByRoleId(roleId: string): Promise<Permission[]> {
53-
return this.createQueryBuilder('permission')
53+
return (await this.getQueryBuilder('permission'))
5454
.leftJoinAndSelect(
5555
RolePermission,
5656
'rolePermission',
@@ -61,7 +61,7 @@ export class PermissionRepository extends BaseRepository<Permission> {
6161
}
6262

6363
async getPermissionsByGroupId(groupId: string): Promise<Permission[]> {
64-
return this.createQueryBuilder('permission')
64+
return (await this.getQueryBuilder('permission'))
6565
.leftJoinAndSelect(
6666
GroupPermission,
6767
'groupPermission',
@@ -72,7 +72,7 @@ export class PermissionRepository extends BaseRepository<Permission> {
7272
}
7373

7474
async getPermissionsByEntityId(entityId: string): Promise<Permission[]> {
75-
return this.createQueryBuilder('permission')
75+
return (await this.getQueryBuilder('permission'))
7676
.leftJoinAndSelect(
7777
EntityPermission,
7878
'entityPermission',
@@ -85,7 +85,7 @@ export class PermissionRepository extends BaseRepository<Permission> {
8585
}
8686

8787
async getPermissionsByUserId(userId: string): Promise<Permission[]> {
88-
return this.createQueryBuilder('permission')
88+
return (await this.getQueryBuilder('permission'))
8989
.leftJoinAndSelect(
9090
UserPermission,
9191
'userPermission',
@@ -98,7 +98,7 @@ export class PermissionRepository extends BaseRepository<Permission> {
9898
async getGroupRolePermissionsByGroupId(
9999
groupId: string,
100100
): Promise<Permission[]> {
101-
return this.createQueryBuilder('permission')
101+
return (await this.getQueryBuilder('permission'))
102102
.innerJoin(
103103
RolePermission,
104104
'rolePermission',

src/authorization/repository/role.repository.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export class RoleRepository extends BaseRepository<Role> {
2929
}
3030

3131
async getRolesForGroupId(groupId: string): Promise<Role[]> {
32-
return this.createQueryBuilder('role')
32+
return (await this.getQueryBuilder('role'))
3333
.leftJoinAndSelect(GroupRole, 'groupRole', 'role.id = groupRole.roleId')
3434
.where('groupRole.groupId = :groupId', { groupId })
3535
.getMany();

src/authorization/repository/user.repository.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export class UserRepository extends BaseRepository<User> {
1616
}
1717

1818
async getUserByEmail(email: string) {
19-
return this.createQueryBuilder('user')
19+
return (await this.getQueryBuilder('user'))
2020
.where('lower(user.email) = lower(:email)', { email })
2121
.getOne();
2222
}
@@ -42,14 +42,14 @@ export class UserRepository extends BaseRepository<User> {
4242
}
4343

4444
async getUsersByGroupId(groupId: string): Promise<User[]> {
45-
return this.createQueryBuilder('user')
45+
return (await this.getQueryBuilder('user'))
4646
.leftJoinAndSelect(UserGroup, 'userGroup', 'userGroup.userId = user.id')
4747
.where('userGroup.groupId = :groupId', { groupId })
4848
.getMany();
4949
}
5050

5151
async getUserCountForGroupId(groupId: string): Promise<number> {
52-
return this.createQueryBuilder('user')
52+
return (await this.getQueryBuilder('user'))
5353
.innerJoinAndSelect(UserGroup, 'userGroup', 'userGroup.userId = user.id')
5454
.where('userGroup.groupId = :groupId', { groupId })
5555
.getCount();

src/authorization/service/entity.service.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ import { EntityModelRepository } from '../repository/entity.repository';
1414
import { EntityPermissionRepository } from '../repository/entityPermission.repository';
1515
import { PermissionRepository } from '../repository/permission.repository';
1616
import { EntityServiceInterface } from './entity.service.interface';
17-
import { ExecutionManager } from '../../util/execution.manager';
1817
import { getConnection } from '../../util/database.connection';
18+
import { ExecutionManager } from '../../util/execution.manager';
1919

2020
@Injectable()
2121
export class EntityService implements EntityServiceInterface {
@@ -114,7 +114,8 @@ export class EntityService implements EntityServiceInterface {
114114
})),
115115
);
116116

117-
await this.dataSource.manager.transaction(async (entityManager) => {
117+
const entityManager = (await getConnection()).manager;
118+
await entityManager.transaction(async (entityManager) => {
118119
const entityPermissionsRepo = entityManager.getRepository(
119120
EntityPermission,
120121
);

src/authorization/service/group.service.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import { UserCacheServiceInterface } from './usercache.service.interface';
4242
import { DUPLICATE_ERROR_CODE } from '../../constants/db.error.constants';
4343
import { LoggerService } from '../../logger/logger.service';
4444
import { ExecutionManager } from '../../util/execution.manager';
45+
import { getConnection } from '../../util/database.connection';
4546

4647
@Injectable()
4748
export class GroupService implements GroupServiceInterface {
@@ -74,7 +75,7 @@ export class GroupService implements GroupServiceInterface {
7475
['name', 'group.name'],
7576
['updatedAt', 'group.updated_at'],
7677
]);
77-
let queryBuilder = this.groupRepository.createQueryBuilder('group');
78+
let queryBuilder = await this.groupRepository.getQueryBuilder('group');
7879

7980
if (input?.search) {
8081
queryBuilder = this.searchService.generateSearchTermForEntity(
@@ -170,7 +171,7 @@ export class GroupService implements GroupServiceInterface {
170171
throw new GroupDeleteNotAllowedException();
171172
}
172173

173-
await this.dataSource.manager.transaction(async (entityManager) => {
174+
await (await getConnection()).manager.transaction(async (entityManager) => {
174175
const groupRepo = entityManager.getRepository(Group);
175176
const groupRoleRepo = entityManager.getRepository(GroupRole);
176177
const groupPermissionRepo = entityManager.getRepository(GroupPermission);
@@ -222,7 +223,7 @@ export class GroupService implements GroupServiceInterface {
222223
})),
223224
);
224225

225-
await this.dataSource.manager.transaction(async (entityManager) => {
226+
await (await getConnection()).manager.transaction(async (entityManager) => {
226227
const groupPermissionsRepo = entityManager.getRepository(GroupPermission);
227228
await groupPermissionsRepo.remove(permissionsToBeRemovedFromGroup);
228229
await groupPermissionsRepo.save(groupPermission);
@@ -251,7 +252,7 @@ export class GroupService implements GroupServiceInterface {
251252
userIds.map((userId) => ({ userId: userId, groupId: id })),
252253
);
253254

254-
await this.dataSource.manager.transaction(async (entityManager) => {
255+
await (await getConnection()).manager.transaction(async (entityManager) => {
255256
const userGroupsRepo = entityManager.getRepository(UserGroup);
256257
await userGroupsRepo.remove(usersToBeRemovedFromGroup);
257258
await userGroupsRepo.save(userGroups);
@@ -321,7 +322,7 @@ export class GroupService implements GroupServiceInterface {
321322
})),
322323
);
323324

324-
await this.dataSource.manager.transaction(async (entityManager) => {
325+
await (await getConnection()).manager.transaction(async (entityManager) => {
325326
const groupRolesRepo = entityManager.getRepository(GroupRole);
326327
await groupRolesRepo.remove(rolesToBeRemovedFromGroup);
327328
await groupRolesRepo.save(groupRoles);

src/authorization/service/role.service.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { RoleServiceInterface } from './role.service.interface';
2424
import { RoleCacheServiceInterface } from './rolecache.service.interface';
2525
import SearchService from './search.service';
2626
import { ExecutionManager } from '../../util/execution.manager';
27+
import { getConnection } from '../../util/database.connection';
2728

2829
@Injectable()
2930
export class RoleService implements RoleServiceInterface {
@@ -43,7 +44,7 @@ export class RoleService implements RoleServiceInterface {
4344
['name', 'role.name'],
4445
['updatedAt', 'role.updated_at'],
4546
]);
46-
let queryBuilder = this.rolesRepository.createQueryBuilder('role');
47+
let queryBuilder = await this.rolesRepository.getQueryBuilder('role');
4748
if (input?.search) {
4849
queryBuilder = this.searchService.generateSearchTermForEntity(
4950
queryBuilder,
@@ -106,7 +107,7 @@ export class RoleService implements RoleServiceInterface {
106107
throw new RoleDeleteNotAllowedException();
107108
}
108109

109-
await this.dataSource.manager.transaction(async (entityManager) => {
110+
await (await getConnection()).manager.transaction(async (entityManager) => {
110111
const rolePermissionsRepo = entityManager.getRepository(RolePermission);
111112
const roleRepo = entityManager.getRepository(Role);
112113
await rolePermissionsRepo.softDelete({ roleId: id });
@@ -155,7 +156,7 @@ export class RoleService implements RoleServiceInterface {
155156
})),
156157
);
157158

158-
await this.dataSource.manager.transaction(async (entityManager) => {
159+
await (await getConnection()).manager.transaction(async (entityManager) => {
159160
const rolePermissionsRepo = entityManager.getRepository(RolePermission);
160161
await rolePermissionsRepo.remove(permissionsToBeRemovedFromRole);
161162
await rolePermissionsRepo.save(rolePermissions);

src/authorization/service/user.service.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { BadRequestException, Inject, Injectable } from '@nestjs/common';
2-
import { DataSource, SelectQueryBuilder } from 'typeorm';
2+
import { DataSource, EntityManager, SelectQueryBuilder } from 'typeorm';
33
import { UserNotAuthorized } from '../../authentication/exception/userauth.exception';
44
import { FilterBuilder } from '../../common/filter.builder';
55
import { SearchEntity } from '../../constants/search.entity.enum';
@@ -33,6 +33,7 @@ import SearchService from './search.service';
3333
import { UserServiceInterface } from './user.service.interface';
3434
import { UserCacheServiceInterface } from './usercache.service.interface';
3535
import { ExecutionManager } from '../../util/execution.manager';
36+
import { getConnection } from '../../util/database.connection';
3637

3738
@Injectable()
3839
export class UserService implements UserServiceInterface {
@@ -54,7 +55,7 @@ export class UserService implements UserServiceInterface {
5455
private roleCacheService: RoleCacheServiceInterface,
5556
) {}
5657

57-
getAllUsers(input?: UserInputFilter): Promise<[User[], number]> {
58+
async getAllUsers(input?: UserInputFilter): Promise<[User[], number]> {
5859
const SortFieldMapping = new Map([
5960
['firstName', 'user.firstName'],
6061
['updatedAt', 'user.updated_at'],
@@ -74,7 +75,7 @@ export class UserService implements UserServiceInterface {
7475
);
7576
}
7677
};
77-
const qb = this.userRepository.createQueryBuilder('user');
78+
const qb = await this.userRepository.getQueryBuilder('user');
7879
if (input?.search) {
7980
this.searchService.generateSearchTermForEntity(
8081
qb,
@@ -156,7 +157,7 @@ export class UserService implements UserServiceInterface {
156157
user.groups.map((group) => ({ userId: id, groupId: group })),
157158
);
158159

159-
await this.dataSource.manager.transaction(async (entityManager) => {
160+
await (await getConnection()).manager.transaction(async (entityManager) => {
160161
const userGroupsRepo = entityManager.getRepository(UserGroup);
161162
await userGroupsRepo.remove(groupsToBeRemovedFromUser);
162163
await userGroupsRepo.save(userGroups);
@@ -227,7 +228,7 @@ export class UserService implements UserServiceInterface {
227228
throw new UserNotFoundException(id);
228229
}
229230

230-
await this.dataSource.manager.transaction(async (entityManager) => {
231+
await (await getConnection()).manager.transaction(async (entityManager) => {
231232
const userRepo = entityManager.getRepository(User);
232233
const userGroupRepo = entityManager.getRepository(UserGroup);
233234
const userPermissionRepo = entityManager.getRepository(UserPermission);
@@ -370,7 +371,7 @@ export class UserService implements UserServiceInterface {
370371
'Username should be provided with email or phone',
371372
);
372373
}
373-
let query = this.userRepository.createQueryBuilder('user');
374+
let query = await this.userRepository.getQueryBuilder('user');
374375
if (email) {
375376
query = query.orWhere('lower(user.email) = lower(:email)', {
376377
email: nullCheckedEmail,

test/authorization/repository/group.repository.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ describe('test Group repository', () => {
4848
updateMock = groupRepository.update = jest.fn();
4949
findMock = groupRepository.find = jest.fn();
5050

51-
createQueryBuilderMock = groupRepository.createQueryBuilder = jest
51+
createQueryBuilderMock = groupRepository.getQueryBuilder = jest
5252
.fn()
5353
.mockReturnValue({
5454
leftJoinAndSelect: jest.fn().mockReturnThis(),

test/authorization/repository/groupRole.repository.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ describe('test GroupRole repository', () => {
2626

2727
groupRoleRepository = moduleRef.get(GroupRoleRepository);
2828

29-
createQueryBuilderMock = groupRoleRepository.createQueryBuilder = jest
29+
createQueryBuilderMock = groupRoleRepository.getQueryBuilder = jest
3030
.fn()
3131
.mockReturnValue({
3232
innerJoinAndSelect: jest.fn().mockReturnThis(),

test/authorization/repository/permission.repository.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ describe('test Permission repository', () => {
6060
updateMock = permissionRepository.update = jest.fn();
6161
softDeleteMock = permissionRepository.softDelete = jest.fn();
6262

63-
createQueryBuilderMock = permissionRepository.createQueryBuilder = jest
63+
createQueryBuilderMock = permissionRepository.getQueryBuilder = jest
6464
.fn()
6565
.mockReturnValue({
6666
innerJoin: jest.fn().mockReturnThis(),

0 commit comments

Comments
 (0)