Compare commits

..

4 Commits

6 changed files with 48 additions and 76 deletions

View File

@ -125,7 +125,7 @@ import { VisitorPasswordEntity } from '../modules/visitor-password/entities';
logger: typeOrmLogger, logger: typeOrmLogger,
extra: { extra: {
charset: 'utf8mb4', charset: 'utf8mb4',
max: 50, // set pool max size max: 20, // set pool max size
idleTimeoutMillis: 5000, // close idle clients after 5 second idleTimeoutMillis: 5000, // close idle clients after 5 second
connectionTimeoutMillis: 12_000, // return an error after 11 second if connection could not be established connectionTimeoutMillis: 12_000, // return an error after 11 second if connection could not be established
maxUses: 7500, // close (and replace) a connection after it has been used 7500 times (see below for discussion) maxUses: 7500, // close (and replace) a connection after it has been used 7500 times (see below for discussion)

View File

@ -1,7 +1,7 @@
import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config'; import { ConfigService } from '@nestjs/config';
import axios from 'axios';
import * as nodemailer from 'nodemailer'; import * as nodemailer from 'nodemailer';
import axios from 'axios';
import { import {
SEND_EMAIL_API_URL_DEV, SEND_EMAIL_API_URL_DEV,
SEND_EMAIL_API_URL_PROD, SEND_EMAIL_API_URL_PROD,
@ -83,17 +83,12 @@ export class EmailService {
); );
} }
} }
async sendEmailWithTemplate({ async sendEmailWithTemplate(
email, email: string,
name, name: string,
isEnable, isEnable: boolean,
isDelete, isDelete: boolean,
}: { ): Promise<void> {
email: string;
name: string;
isEnable: boolean;
isDelete: boolean;
}): Promise<void> {
const isProduction = process.env.NODE_ENV === 'production'; const isProduction = process.env.NODE_ENV === 'production';
const API_TOKEN = this.configService.get<string>( const API_TOKEN = this.configService.get<string>(
'email-config.MAILTRAP_API_TOKEN', 'email-config.MAILTRAP_API_TOKEN',

View File

@ -207,8 +207,7 @@ export class CommunityService {
if (search) { if (search) {
qb.andWhere( qb.andWhere(
`c.name ILIKE :search ${includeSpaces ? 'OR space.space_name ILIKE :search' : ''}`, `c.name ILIKE '%${search}%' ${includeSpaces ? "OR space.space_name ILIKE '%" + search + "%'" : ''}`,
{ search: `%${search}%` },
); );
} }
@ -216,22 +215,12 @@ export class CommunityService {
const { baseResponseDto, paginationResponseDto } = const { baseResponseDto, paginationResponseDto } =
await customModel.findAll({ ...pageable, modelName: 'community' }, qb); await customModel.findAll({ ...pageable, modelName: 'community' }, qb);
if (includeSpaces) {
baseResponseDto.data = baseResponseDto.data.map((community) => ({
...community,
spaces: this.spaceService.buildSpaceHierarchy(community.spaces || []),
}));
}
return new PageResponse<CommunityDto>( return new PageResponse<CommunityDto>(
baseResponseDto, baseResponseDto,
paginationResponseDto, paginationResponseDto,
); );
} catch (error) { } catch (error) {
// Generic error handling // Generic error handling
if (error instanceof HttpException) {
throw error;
}
throw new HttpException( throw new HttpException(
error.message || 'An error occurred while fetching communities.', error.message || 'An error occurred while fetching communities.',
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,

View File

@ -1,42 +1,36 @@
import { RoleType } from '@app/common/constants/role.type.enum'; import {
import { UserStatusEnum } from '@app/common/constants/user-status.enum'; Injectable,
HttpException,
HttpStatus,
BadRequestException,
} from '@nestjs/common';
import { AddUserInvitationDto } from '../dtos';
import { BaseResponseDto } from '@app/common/dto/base.response.dto'; import { BaseResponseDto } from '@app/common/dto/base.response.dto';
import { UserStatusEnum } from '@app/common/constants/user-status.enum';
import { SuccessResponseDto } from '@app/common/dto/success.response.dto'; import { SuccessResponseDto } from '@app/common/dto/success.response.dto';
import { generateRandomString } from '@app/common/helper/randomString'; import { generateRandomString } from '@app/common/helper/randomString';
import { InviteUserEntity } from '@app/common/modules/Invite-user/entities'; import { EntityManager, In, IsNull, Not, QueryRunner } from 'typeorm';
import { DataSource } from 'typeorm';
import { UserEntity } from '@app/common/modules/user/entities';
import { RoleType } from '@app/common/constants/role.type.enum';
import { import {
InviteUserRepository, InviteUserRepository,
InviteUserSpaceRepository, InviteUserSpaceRepository,
} from '@app/common/modules/Invite-user/repositiories'; } from '@app/common/modules/Invite-user/repositiories';
import { RoleTypeRepository } from '@app/common/modules/role-type/repositories'; import { CheckEmailDto } from '../dtos/check-email.dto';
import { SpaceRepository } from '@app/common/modules/space';
import { SpaceEntity } from '@app/common/modules/space/entities/space.entity';
import { UserEntity } from '@app/common/modules/user/entities';
import { UserRepository } from '@app/common/modules/user/repositories'; import { UserRepository } from '@app/common/modules/user/repositories';
import { EmailService } from '@app/common/util/email.service'; import { EmailService } from '@app/common/util/email.service';
import { import { SpaceRepository } from '@app/common/modules/space';
BadRequestException,
HttpException,
HttpStatus,
Injectable,
} from '@nestjs/common';
import { SpaceUserService } from 'src/space/services';
import { UserSpaceService } from 'src/users/services';
import {
DataSource,
EntityManager,
In,
IsNull,
Not,
QueryRunner,
} from 'typeorm';
import { AddUserInvitationDto } from '../dtos';
import { ActivateCodeDto } from '../dtos/active-code.dto'; import { ActivateCodeDto } from '../dtos/active-code.dto';
import { CheckEmailDto } from '../dtos/check-email.dto'; import { UserSpaceService } from 'src/users/services';
import { SpaceUserService } from 'src/space/services';
import { import {
DisableUserInvitationDto, DisableUserInvitationDto,
UpdateUserInvitationDto, UpdateUserInvitationDto,
} from '../dtos/update.invite-user.dto'; } from '../dtos/update.invite-user.dto';
import { RoleTypeRepository } from '@app/common/modules/role-type/repositories';
import { InviteUserEntity } from '@app/common/modules/Invite-user/entities';
import { SpaceEntity } from '@app/common/modules/space/entities/space.entity';
@Injectable() @Injectable()
export class InviteUserService { export class InviteUserService {
@ -664,12 +658,12 @@ export class InviteUserService {
HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST,
); );
} }
await this.emailService.sendEmailWithTemplate({ await this.emailService.sendEmailWithTemplate(
email: userData.email, userData.email,
name: userData.firstName, userData.firstName,
isEnable: !disable, disable,
isDelete: false, false,
}); );
await queryRunner.commitTransaction(); await queryRunner.commitTransaction();
return new SuccessResponseDto({ return new SuccessResponseDto({
@ -803,12 +797,12 @@ export class InviteUserService {
{ isActive: false }, { isActive: false },
); );
} }
await this.emailService.sendEmailWithTemplate({ await this.emailService.sendEmailWithTemplate(
email: userData.email, userData.email,
name: userData.firstName, userData.firstName,
isEnable: false, false,
isDelete: true, true,
}); );
await queryRunner.commitTransaction(); await queryRunner.commitTransaction();
return new SuccessResponseDto({ return new SuccessResponseDto({

View File

@ -1,14 +1,15 @@
import { RequestContextMiddleware } from '@app/common/middleware/request-context.middleware';
import { SeederService } from '@app/common/seed/services/seeder.service';
import { Logger, ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core'; import { NestFactory } from '@nestjs/core';
import { json, urlencoded } from 'body-parser'; import { AppModule } from './app.module';
import rateLimit from 'express-rate-limit'; import rateLimit from 'express-rate-limit';
import helmet from 'helmet'; import helmet from 'helmet';
import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston';
import { setupSwaggerAuthentication } from '../libs/common/src/util/user-auth.swagger.utils'; import { setupSwaggerAuthentication } from '../libs/common/src/util/user-auth.swagger.utils';
import { AppModule } from './app.module'; import { ValidationPipe } from '@nestjs/common';
import { json, urlencoded } from 'body-parser';
import { SeederService } from '@app/common/seed/services/seeder.service';
import { HttpExceptionFilter } from './common/filters/http-exception/http-exception.filter'; import { HttpExceptionFilter } from './common/filters/http-exception/http-exception.filter';
import { Logger } from '@nestjs/common';
import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston';
import { RequestContextMiddleware } from '@app/common/middleware/request-context.middleware';
async function bootstrap() { async function bootstrap() {
const app = await NestFactory.create(AppModule); const app = await NestFactory.create(AppModule);
@ -29,13 +30,6 @@ async function bootstrap() {
}), }),
); );
app.use((req, res, next) => {
console.log('Real IP:', req.ip);
next();
});
// app.getHttpAdapter().getInstance().set('trust proxy', 1);
app.use( app.use(
helmet({ helmet({
contentSecurityPolicy: false, contentSecurityPolicy: false,

View File

@ -681,7 +681,7 @@ export class SpaceService {
} }
} }
buildSpaceHierarchy(spaces: SpaceEntity[]): SpaceEntity[] { private buildSpaceHierarchy(spaces: SpaceEntity[]): SpaceEntity[] {
const map = new Map<string, SpaceEntity>(); const map = new Map<string, SpaceEntity>();
// Step 1: Create a map of spaces by UUID // Step 1: Create a map of spaces by UUID