diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index 829a1ca9f17283904bb6175d0ad7bb9e5639f966..4d8145bd3159c15e263a6c9195d2e0d45787eb7d 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -36,6 +36,7 @@ import { EmailService } from './email/email.service'; import { UserResetCode } from './auth/user/entities/user-reset-code.entity'; import { MailerModule } from '@nestjs-modules/mailer'; import { MailConstants } from './constants/mail.constants'; +import { UserConfirmCode } from './auth/user/entities/user-confirm-code.entity'; @Module({ imports: [ @@ -62,6 +63,7 @@ import { MailConstants } from './constants/mail.constants'; TravelPlace, Visited, UserResetCode, + UserConfirmCode, ], synchronize: DbConstants.DB_SYNC, logging: false, diff --git a/backend/src/auth/user/authUser.module.ts b/backend/src/auth/user/authUser.module.ts index f618601598c10712dc105900069f1b00dfa0adb0..824f8c7d1e5ce74ba470e64d1aad1649b16ae9cf 100644 --- a/backend/src/auth/user/authUser.module.ts +++ b/backend/src/auth/user/authUser.module.ts @@ -10,10 +10,11 @@ import { Category } from 'src/category/entities/category.entity'; import { CategoryService } from 'src/category/category.service'; import { UserResetCode } from './entities/user-reset-code.entity'; import { EmailService } from 'src/email/email.service'; +import { UserConfirmCode } from './entities/user-confirm-code.entity'; @Module({ controllers: [AuthUserController], providers: [UserService, JwtService, EncryptionService, AuthUserService, CategoryService, EmailService], - imports: [TypeOrmModule.forFeature([User, Category, UserResetCode])], + imports: [TypeOrmModule.forFeature([User, Category, UserResetCode, UserConfirmCode])], }) export class AuthUserModule {} diff --git a/backend/src/auth/user/authUsercontroller.ts b/backend/src/auth/user/authUsercontroller.ts index 9723c6083dfb5ba33e05e76383d255945ee2f936..6d345f8dc5355850b50a42156f868a88a73311b4 100644 --- a/backend/src/auth/user/authUsercontroller.ts +++ b/backend/src/auth/user/authUsercontroller.ts @@ -1,4 +1,4 @@ -import { Body, Controller, Get, Patch, Post, Req, UseGuards } from '@nestjs/common'; +import { Body, Controller, Patch, Post, Req, UseGuards } from '@nestjs/common'; import { ApiBearerAuth, ApiBody, ApiCreatedResponse, ApiTags, ApiUnauthorizedResponse } from '@nestjs/swagger'; import { AuthUserService } from './authUserservice'; import { CreateUserDto } from 'src/user/dto/create-user.dto'; @@ -7,14 +7,22 @@ import { UserSigninResDto } from './dto/user-signin-res.dto'; import { AuthUserGuard } from './authUser.guard'; import { CustomUserRequest } from './interface/customUserReq'; import { UpdatePwdDto } from './dto/update-pwd.dto'; -import { UserRequestCodeBody, UserResetPasswordBody, UserResetPasswordDto } from './dto/user-reset-password.dto'; +import { + UserConfirmEmailBody, + UserRequestCodeBody, + UserResetPasswordBody, + UserResetPasswordDto, +} from './dto/user-reset-password.dto'; import { GetResetCode } from './dto/get-reset-code.dto'; import { EmailService } from 'src/email/email.service'; @Controller('') @ApiTags('Create user account and sign in as user') export class AuthUserController { - constructor(private readonly authUserService: AuthUserService, private readonly mailService: EmailService) {} + constructor( + private readonly authUserService: AuthUserService, + private readonly mailService: EmailService, + ) {} @ApiBody({ type: CreateUserDto }) @ApiCreatedResponse({ @@ -60,11 +68,37 @@ export class AuthUserController { @ApiBody({ type: UserRequestCodeBody }) @Post('user/get-reset-code') async getResetCode(@Body() resetPasswordInfo: GetResetCode) { - try{ + try { const code = await this.authUserService.getResetPasswordCode(resetPasswordInfo.email); await this.mailService.sendResetPasswordEmail(resetPasswordInfo.email, code); } catch (e) { throw e; } } + + @ApiBearerAuth('jwt') + @UseGuards(AuthUserGuard) + @Post('user/resend-confirmation-code') + async resendConfirmationCode(@Req() req: CustomUserRequest) { + try { + const email = req.user.email; + await this.authUserService.sendConfirmationCode(email); + return { message: 'Confirmation code sent' }; + } catch (e) { + throw e; + } + } + + @ApiBody({ type: UserConfirmEmailBody }) + @ApiBearerAuth('jwt') + @UseGuards(AuthUserGuard) + @Post('user/confirm-email') + async confirmEmail(@Body() { code }, @Req() req: CustomUserRequest) { + try { + const email = req.user.email; + return await this.authUserService.confirmEmail(email, { code }); + } catch (e) { + throw e; + } + } } diff --git a/backend/src/auth/user/authUserservice.ts b/backend/src/auth/user/authUserservice.ts index 7f53e41bd5fce688f1f9414227988207f8192e8e..ee0a07dc80bdd2135cb18161e0573b3f75be5be4 100644 --- a/backend/src/auth/user/authUserservice.ts +++ b/backend/src/auth/user/authUserservice.ts @@ -14,15 +14,19 @@ import { InjectRepository } from '@nestjs/typeorm'; import { UserResetCode } from './entities/user-reset-code.entity'; import { Repository } from 'typeorm'; import { randomInt } from 'crypto'; -import { UserResetPasswordDto } from './dto/user-reset-password.dto'; +import { UserConfirmEmailBody, UserResetPasswordDto } from './dto/user-reset-password.dto'; +import { UserConfirmCode } from './entities/user-confirm-code.entity'; +import { EmailService } from 'src/email/email.service'; @Injectable() export class AuthUserService { constructor( @InjectRepository(UserResetCode) private userResetCodeRepository: Repository, + @InjectRepository(UserConfirmCode) private userConfirmCodeRepository: Repository, private userService: UserService, private jwtService: JwtService, private encryptionService: EncryptionService, + private readonly mailService: EmailService, ) {} async signUp(createAdminDto: CreateUserDto): Promise { @@ -38,6 +42,8 @@ export class AuthUserService { await this.userService.create(createAdminDto); const adminSigninResDto: UserSigninResDto = await this.signIn(loginAdminDto); + await this.sendConfirmationCode(createAdminDto.email); + return adminSigninResDto; } @@ -91,7 +97,7 @@ export class AuthUserService { expirationDate.setHours(expirationDate.getHours() + 1); const existUserCode = await this.userResetCodeRepository.findBy({ user, code: resetCode }); console.log(existUserCode); - + if (existUserCode.length > 0) { await this.userResetCodeRepository.delete(existUserCode[0].id); } @@ -102,7 +108,7 @@ export class AuthUserService { async resetPassword({ email, resetCode, newPassword }: UserResetPasswordDto) { const user: User = await this.userService.findOne(email); if (!user) throw new UnauthorizedException('Invalid email'); - + const userResetCode: UserResetCode[] = await this.userResetCodeRepository.findBy({ user, code: resetCode }); if (userResetCode.length === 0) throw new UnauthorizedException('Invalid code'); @@ -112,4 +118,32 @@ export class AuthUserService { await this.userService.updatePassword(email, newPwdHashed); await this.userResetCodeRepository.delete(userResetCode[0].id); } + + async sendConfirmationCode(email: string) { + const user: User = await this.userService.findOne(email); + if (!user) throw new UnauthorizedException('Invalid email'); + const resetCode = randomInt(100000, 999999).toString(); + const expirationDate = new Date(); + expirationDate.setHours(expirationDate.getHours() + 1); + const existUserCode = await this.userConfirmCodeRepository.findBy({ user, code: resetCode }); + if (existUserCode.length > 0) { + await this.userConfirmCodeRepository.delete(existUserCode[0].id); + } + await this.userConfirmCodeRepository.save({ user, code: resetCode, expirationDate }); + await this.mailService.sendConfirmationCode(email, resetCode); + return resetCode; + } + + async confirmEmail(email: string, { code }: UserConfirmEmailBody) { + const user: User = await this.userService.findOne(email); + if (!user) throw new UnauthorizedException('Invalid email'); + + const userConfirmCode: UserResetCode[] = await this.userConfirmCodeRepository.findBy({ user, code: code }); + + if (userConfirmCode.length === 0) throw new UnauthorizedException('Invalid code'); + if (userConfirmCode[0].expirationDate < new Date()) throw new UnauthorizedException('Code expired'); + + await this.userService.confirmEmail(email); + await this.userConfirmCodeRepository.delete(userConfirmCode[0].id); + } } diff --git a/backend/src/auth/user/dto/user-reset-password.dto.ts b/backend/src/auth/user/dto/user-reset-password.dto.ts index c301d1fdbab4ee272ddbea35fb8d4d287cc3c149..35ac81ecb4394c011a131f3aed8b3312f6bef066 100644 --- a/backend/src/auth/user/dto/user-reset-password.dto.ts +++ b/backend/src/auth/user/dto/user-reset-password.dto.ts @@ -1,21 +1,26 @@ -import { ApiProperty } from "@nestjs/swagger"; +import { ApiProperty } from '@nestjs/swagger'; export interface UserResetPasswordDto { - email: string; - resetCode: string; - newPassword: string; -} + email: string; + resetCode: string; + newPassword: string; +} export class UserResetPasswordBody { - @ApiProperty() - email: string; - @ApiProperty() - resetCode: string; - @ApiProperty() - newPassword: string; + @ApiProperty() + email: string; + @ApiProperty() + resetCode: string; + @ApiProperty() + newPassword: string; } export class UserRequestCodeBody { - @ApiProperty() - email: string; -} \ No newline at end of file + @ApiProperty() + email: string; +} + +export class UserConfirmEmailBody { + @ApiProperty() + code: string; +} diff --git a/backend/src/auth/user/entities/user-confirm-code.entity.ts b/backend/src/auth/user/entities/user-confirm-code.entity.ts new file mode 100644 index 0000000000000000000000000000000000000000..d5a48770bdbae0f9f9940e14e6c15ad9d984f62c --- /dev/null +++ b/backend/src/auth/user/entities/user-confirm-code.entity.ts @@ -0,0 +1,17 @@ +import { User } from 'src/user/entities/user.entity'; +import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; + +@Entity() +export class UserConfirmCode { + @PrimaryGeneratedColumn() + id: number; + + @ManyToOne(() => User, (user) => user.resetCodes) + user: User; + + @Column() + code: string; + + @Column() + expirationDate: Date; +} diff --git a/backend/src/auth/user/entities/user-reset-code.entity.ts b/backend/src/auth/user/entities/user-reset-code.entity.ts index 8f58222d9b14f58d76eb2a8b9aebac6b2dfaa846..2bf019ac7216b481d666b595c32132a8bb13ed1a 100644 --- a/backend/src/auth/user/entities/user-reset-code.entity.ts +++ b/backend/src/auth/user/entities/user-reset-code.entity.ts @@ -1,13 +1,12 @@ -import { User } from "src/user/entities/user.entity"; -import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; - +import { User } from 'src/user/entities/user.entity'; +import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; @Entity() export class UserResetCode { @PrimaryGeneratedColumn() id: number; - @ManyToOne(() => User, user => user.resetCodes) + @ManyToOne(() => User, (user) => user.resetCodes) user: User; @Column() diff --git a/backend/src/email/email.service.ts b/backend/src/email/email.service.ts index 621bed1f0fc16cf201dd702e3536114fe5896cbd..3d553b3730620097e1047f5a24e67530ef3380e9 100644 --- a/backend/src/email/email.service.ts +++ b/backend/src/email/email.service.ts @@ -1,25 +1,35 @@ import { MailerService } from '@nestjs-modules/mailer'; import { Injectable } from '@nestjs/common'; -import { MailConstants } from 'src/constants/mail.constants'; -import { text } from 'stream/consumers'; @Injectable() export class EmailService { - constructor( - private readonly mailerService: MailerService, - ) { } + constructor(private readonly mailerService: MailerService) {} - async sendResetPasswordEmail(email: string, resetCode: string): Promise { - const mailOptions = { - to: email, - subject: 'Reset your password', - html: `

Your reset code is ${resetCode}

`, - }; - try { - await this.mailerService.sendMail(mailOptions); - } catch (error) { - console.error(error); - throw new Error('Error sending email'); - } + async sendResetPasswordEmail(email: string, resetCode: string): Promise { + const mailOptions = { + to: email, + subject: 'Reset your password', + html: `

Your reset code is ${resetCode}

`, + }; + try { + await this.mailerService.sendMail(mailOptions); + } catch (error) { + console.error(error); + throw new Error('Error sending email'); } + } + + async sendConfirmationCode(email: string, confirmationCode: string): Promise { + const mailOptions = { + to: email, + subject: 'Confirm your email', + html: `

Your confirmation code is ${confirmationCode}

`, + }; + try { + await this.mailerService.sendMail(mailOptions); + } catch (error) { + console.error(error); + throw new Error('Error sending email'); + } + } } diff --git a/backend/src/place/entities/place.entity.ts b/backend/src/place/entities/place.entity.ts index b4ed14c743b8e11fed25013537693d58aa39adee..ea48f3f012775d3fd1e67c6f067ac3c681db1795 100644 --- a/backend/src/place/entities/place.entity.ts +++ b/backend/src/place/entities/place.entity.ts @@ -9,11 +9,13 @@ import { ManyToMany, ManyToOne, OneToMany, + OneToOne, PrimaryGeneratedColumn, } from 'typeorm'; import { AvailableDate } from './available-date.entity'; import { Category } from 'src/category/entities/category.entity'; import { PlaceTraduction } from './place-traduction.entity'; +import { Visited } from 'src/visited/entities/visited.entity'; @Entity() export class Place { @@ -37,6 +39,8 @@ export class Place { @OneToMany(() => PlaceTraduction, (placeTraduction) => placeTraduction.idPlace) placeTraduction: PlaceTraduction[]; + @OneToOne(() => Visited, (visited) => visited.place) + visited: Visited[]; @Column() available: Available; diff --git a/backend/src/route/route.controller.ts b/backend/src/route/route.controller.ts index a4ea87438c42753393e31b34acec94ffc9f850d1..db4760ed3ce73c34057afc257ea9a994068ccd43 100644 --- a/backend/src/route/route.controller.ts +++ b/backend/src/route/route.controller.ts @@ -66,4 +66,12 @@ export class RouteController { async updateRoute(@Body() updateRouteStatusDto: UpdateRouteStatusDto, @Param('idRoute') idRoute: number) { return await this.routeService.updateRoute(idRoute, updateRouteStatusDto.status); } + + @Get('/info/:idRoute') + @ApiParam({ name: 'idRoute', type: Number }) + @ApiBearerAuth('jwt') + @UseGuards(AuthUserGuard) + async getRouteInfo(@Param('idRoute') idRoute: number) { + return await this.routeService.getRouteInfoById(idRoute); + } } diff --git a/backend/src/route/route.module.ts b/backend/src/route/route.module.ts index ed23bcf7393e73053f21757388c28dd6c5049f40..14a9b77b7e343aad8af3a16908a4a2bbab587d3b 100644 --- a/backend/src/route/route.module.ts +++ b/backend/src/route/route.module.ts @@ -20,6 +20,8 @@ import { PlaceTraduction } from 'src/place/entities/place-traduction.entity'; import { VisitedService } from 'src/visited/visited.service'; import { Visited } from 'src/visited/entities/visited.entity'; import { UserResetCode } from 'src/auth/user/entities/user-reset-code.entity'; +import { UserConfirmCode } from 'src/auth/user/entities/user-confirm-code.entity'; +import { EmailService } from 'src/email/email.service'; @Module({ controllers: [RouteController], @@ -33,6 +35,7 @@ import { UserResetCode } from 'src/auth/user/entities/user-reset-code.entity'; TravelPlaceService, PlaceService, VisitedService, + EmailService, ], imports: [ TypeOrmModule.forFeature([ @@ -46,6 +49,7 @@ import { UserResetCode } from 'src/auth/user/entities/user-reset-code.entity'; AvailableDate, PlaceTraduction, Visited, + UserConfirmCode, ]), ], }) diff --git a/backend/src/route/route.service.ts b/backend/src/route/route.service.ts index 048ca136addc5f9e572be9687445472eefef8aa8..6ee25f6fc8a8ebfbe8b5f4dae9e27a51f744f2c0 100644 --- a/backend/src/route/route.service.ts +++ b/backend/src/route/route.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Route, RouteStatus } from './entities/route.entity'; -import { MoreThan, Repository } from 'typeorm'; +import { DataSource, MoreThan, Repository } from 'typeorm'; import { User } from 'src/user/entities/user.entity'; import { Town } from 'src/town/entities/town.entity'; import { TravelPlaceService } from 'src/travel-place/travel-place.service'; @@ -28,6 +28,7 @@ export class RouteService { private readonly placeService: PlaceService, private readonly visitedService: VisitedService, private readonly userService: UserService, + private dataSource: DataSource, ) {} async recommend(idTown: number, email: string, language: LANGUAGES, start, end) { @@ -139,4 +140,16 @@ export class RouteService { return res; } + + async getRouteInfoById(idRoute: number) { + const res = await this.dataSource + .createQueryBuilder(Route, 'route') + .leftJoinAndSelect('route.travelPlace', 'travelPlace') + .leftJoinAndSelect('travelPlace.place', 'place') + .leftJoinAndSelect('place.visited', 'visited') + .where('route.idRoute = :idRoute', { idRoute }) + .getOne(); + + return res; + } } diff --git a/backend/src/user/entities/user.entity.ts b/backend/src/user/entities/user.entity.ts index 36aa4bbadfa89e4e3ac7b2494fa74167c0785a4b..9de8695637bfa619e02dceb4c076f030345caf55 100644 --- a/backend/src/user/entities/user.entity.ts +++ b/backend/src/user/entities/user.entity.ts @@ -1,3 +1,4 @@ +import { UserConfirmCode } from 'src/auth/user/entities/user-confirm-code.entity'; import { UserResetCode } from 'src/auth/user/entities/user-reset-code.entity'; import { Category } from 'src/category/entities/category.entity'; import { Entity, Column, ManyToMany, JoinTable, PrimaryColumn, OneToMany } from 'typeorm'; @@ -23,6 +24,12 @@ export class User { @Column() password: string; - @OneToMany(() => UserResetCode, resetCode => resetCode.user) + @Column({ default: false }) + isEmailConfirmed: boolean; + + @OneToMany(() => UserResetCode, (resetCode) => resetCode.user) resetCodes: UserResetCode[]; + + @OneToMany(() => UserConfirmCode, (confirmCode) => confirmCode.user) + confirmCodes: UserConfirmCode[]; } diff --git a/backend/src/user/user.controller.ts b/backend/src/user/user.controller.ts index 18ec00e5b3d79b467c07153ca50c60e285e89fb4..ebb7f80f55d6645ba1ea6efa81a7e438b890ce4d 100644 --- a/backend/src/user/user.controller.ts +++ b/backend/src/user/user.controller.ts @@ -40,4 +40,17 @@ export class UserController { throw error; } } + + @Get('is-verfied') + @ApiBearerAuth('jwt') + @UseGuards(AuthUserGuard) + async isVerified(@Req() req: CustomUserRequest) { + try { + const { email } = req.user; + const isVerified = await this.userService.isVerified(email); + return { isVerified }; + } catch (error) { + throw error; + } + } } diff --git a/backend/src/user/user.module.ts b/backend/src/user/user.module.ts index 80b6273b1c6c142e09f0c54a6c90aa78c6658fa3..0ff6a8e0f8ba99cddd9663c005a565692156270e 100644 --- a/backend/src/user/user.module.ts +++ b/backend/src/user/user.module.ts @@ -9,10 +9,12 @@ import { AuthUserService } from 'src/auth/user/authUserservice'; import { JwtService } from '@nestjs/jwt'; import { EncryptionService } from 'src/auth/encryption/encryption.service'; import { UserResetCode } from 'src/auth/user/entities/user-reset-code.entity'; +import { UserConfirmCode } from 'src/auth/user/entities/user-confirm-code.entity'; +import { EmailService } from 'src/email/email.service'; @Module({ controllers: [UserController], - providers: [UserService, CategoryService, AuthUserService, JwtService, EncryptionService], - imports: [TypeOrmModule.forFeature([User, Category, UserResetCode])], + providers: [UserService, CategoryService, AuthUserService, JwtService, EncryptionService, EmailService], + imports: [TypeOrmModule.forFeature([User, Category, UserResetCode, UserConfirmCode])], }) export class UserModule {} diff --git a/backend/src/user/user.service.ts b/backend/src/user/user.service.ts index 62e7b4d5521451543fdfe59bff71a0236d27d36b..d466391fb4cb2fd482bb680fac4f04e664d35086 100644 --- a/backend/src/user/user.service.ts +++ b/backend/src/user/user.service.ts @@ -68,4 +68,21 @@ export class UserService { }); return user?.preferedCategories || []; } + + async confirmEmail(email: string) { + try { + await this.userRepository.update({ email }, { isEmailConfirmed: true }); + } catch (error) { + throw new BadRequestException('Error confirming email'); + } + } + + async isVerified(email: string): Promise { + try { + const user = await this.userRepository.findOneBy({ email }); + return user.isEmailConfirmed; + } catch (error) { + throw new BadRequestException('Error getting email verification status'); + } + } } diff --git a/backend/src/visited/entities/visited.entity.ts b/backend/src/visited/entities/visited.entity.ts index 2ed305b32fbe99372717cc819aefb9dab52609d8..e99296ce9cb5be343ac82f0f966e446eb1258ea3 100644 --- a/backend/src/visited/entities/visited.entity.ts +++ b/backend/src/visited/entities/visited.entity.ts @@ -1,13 +1,13 @@ import { Place } from 'src/place/entities/place.entity'; import { User } from 'src/user/entities/user.entity'; -import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; +import { Column, Entity, JoinColumn, ManyToOne, OneToOne, PrimaryGeneratedColumn } from 'typeorm'; @Entity() export class Visited { @PrimaryGeneratedColumn() idVisited: number; - @ManyToOne(() => Place, (place) => place.idPlace, { eager: true }) + @OneToOne(() => Place, (place) => place.idPlace, { eager: true }) @JoinColumn({ name: 'place' }) place: Place; diff --git a/backend/src/visited/visited.controller.ts b/backend/src/visited/visited.controller.ts index e5a6741ef228f39010c0b8e386d80adb576d7e02..a2f1f386cc98d4cd8ed181906463d54b1a2c1f78 100644 --- a/backend/src/visited/visited.controller.ts +++ b/backend/src/visited/visited.controller.ts @@ -24,22 +24,15 @@ export class VisitedController { } @Get('/getImage/:routeId') - async getVisitedPlacesImage(@Param('routeId') routeId: string) { + async getVisitedPlacesImage() { return await this.visitedService.getVisitedPlacesImage(); } - @Get() - findAll() { - return this.visitedService.findAll(); - } - - @Get(':id') - findOne(@Param('id') id: string) { - return this.visitedService.findOne(+id); - } - - @Delete(':id') - remove(@Param('id') id: string) { - return this.visitedService.remove(+id); + @UseGuards(AuthUserGuard) + @ApiBearerAuth('jwt') + @Get('/user/') + async findAllByUser(@Req() req: CustomUserRequest) { + const { email } = req.user; + return this.visitedService.findAllByUser(email); } } diff --git a/backend/src/visited/visited.module.ts b/backend/src/visited/visited.module.ts index 7a9aad885f374bd55d43d7d3836b58621309abec..f79ac46ecca8acfe9cb96eb1838a7e496001b956 100644 --- a/backend/src/visited/visited.module.ts +++ b/backend/src/visited/visited.module.ts @@ -16,6 +16,8 @@ import { AuthUserService } from 'src/auth/user/authUserservice'; import { JwtService } from '@nestjs/jwt'; import { EncryptionService } from 'src/auth/encryption/encryption.service'; import { UserResetCode } from 'src/auth/user/entities/user-reset-code.entity'; +import { UserConfirmCode } from 'src/auth/user/entities/user-confirm-code.entity'; +import { EmailService } from 'src/email/email.service'; @Module({ controllers: [VisitedController], @@ -27,7 +29,21 @@ import { UserResetCode } from 'src/auth/user/entities/user-reset-code.entity'; AuthUserService, JwtService, EncryptionService, + EmailService, + ], + imports: [ + TypeOrmModule.forFeature([ + User, + Place, + Visited, + Category, + AvailableDate, + PlaceTraduction, + Town, + Visited, + UserResetCode, + UserConfirmCode, + ]), ], - imports: [TypeOrmModule.forFeature([User, Place, Visited, Category, AvailableDate, PlaceTraduction, Town, Visited, UserResetCode])], }) export class VisitedModule {} diff --git a/backend/src/visited/visited.service.ts b/backend/src/visited/visited.service.ts index 6b3f1d138c76d869b0f5e08f451c98580505adde..7f0c17e05c96da0093b408bb5d8631a449620062 100644 --- a/backend/src/visited/visited.service.ts +++ b/backend/src/visited/visited.service.ts @@ -1,4 +1,4 @@ -import { BadRequestException, HttpException, Injectable, InternalServerErrorException } from '@nestjs/common'; +import { BadRequestException, Injectable, InternalServerErrorException } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Visited } from './entities/visited.entity'; import { Repository } from 'typeorm'; @@ -9,7 +9,7 @@ import { Place } from 'src/place/entities/place.entity'; import { PlaceService } from 'src/place/place.service'; import { LANGUAGES } from 'src/shared/enum/languages.enum'; import { VisitedPlacesImageCreator } from './utils/visited_places_image_creator'; -import { HttpErrorByCode } from '@nestjs/common/utils/http-error-by-code.util'; +import { ServerConstants } from 'src/constants/server.contants'; @Injectable() export class VisitedService { @@ -35,26 +35,26 @@ export class VisitedService { }); } - findAll() { - return `This action returns all visited`; - } - - findOne(id: number) { - return `This action returns a #${id} visited`; - } - - // update(id: number, updateVisitedDto: UpdateVisitedDto) { - // return `This action updates a #${id} visited`; - // } - - remove(id: number) { - return `This action removes a #${id} visited`; + async findAllByUser(email: string) { + const res = await this.visitedRepository.find({ where: { user: { email } } }); + const visited = res.map((visit: Visited) => { + return { + ...visit, + place: { + ...visit.place, + imageName: `${ServerConstants.HOST}/places/${visit.place.imageName}`, + }, + }; + }); + return visited; } async getVisitedPlacesImage() { // obtener imágenes de los lugares visitados en una ruta try { - const visitedPlaces = (await this.placeService.findAllByTown(1, LANGUAGES.EN)).map((place) => place.imageName).slice(0, 5); + const visitedPlaces = (await this.placeService.findAllByTown(1, LANGUAGES.EN)) + .map((place) => place.imageName) + .slice(0, 5); const visitedPlacesImageCreator = new VisitedPlacesImageCreator(); return await visitedPlacesImageCreator.generateImage(visitedPlaces); } catch (error) {