Skip to content

Commit

Permalink
Merge pull request #25 from fga-eps-mds/qas
Browse files Browse the repository at this point in the history
[RELEASE] Introduz correções gerais no backend
  • Loading branch information
dartmol203 authored Jan 11, 2025
2 parents d3cb9d2 + ce8d79c commit 1dd2462
Show file tree
Hide file tree
Showing 14 changed files with 251 additions and 68 deletions.
11 changes: 5 additions & 6 deletions src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export class AuthController {

@Post('login')
async login(@Body() loginDto: LoginDto) {
this.logger.log('AuthController - Login Request:', loginDto);

const user = await this.authService.validateUser(
loginDto.email,
Expand All @@ -48,7 +47,7 @@ export class AuthController {
@Get('google/callback')
@UseGuards(AuthGuard('google'))
googleAuthRedirect(@Req() req: Request, @Res() res: Response) {
this.logger.log('AuthController - Google Callback Request:', req.user);
//this.logger.log('AuthController - Google Callback Request:', req.user);
this.authService.redirectFederated(req.user as any, res);
}

Expand All @@ -61,10 +60,10 @@ export class AuthController {
@Get('microsoft/callback')
@UseGuards(AuthGuard('microsoft'))
microsoftAuthRedirect(@Req() req: Request, @Res() res: Response) {
this.logger.log(
'AuthController - Microsoft Callback Request:',
JSON.stringify(req.user),
);
//this.logger.log(
//'AuthController - Microsoft Callback Request:',
// JSON.stringify(req.user),
//);
this.authService.redirectFederated(req.user as any, res);
}

Expand Down
28 changes: 14 additions & 14 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {
Injectable,
Logger,
NotFoundException,
UnauthorizedException,
Injectable,
Logger,
NotFoundException,
UnauthorizedException,
} from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { JwtService } from '@nestjs/jwt';
Expand Down Expand Up @@ -50,13 +50,13 @@ export class AuthService {

async login(user: any) {
const tokens = await this.generateTokens({
id: user._id,
userId: user._id,
name: user.name,
email: user.email,
role: user.role,
});
return {
id: user._id,
userId: user._id,
name: user.name,
email: user.email,
...tokens,
Expand All @@ -75,7 +75,7 @@ export class AuthService {
});
}
const token = await this.generateTokens({
id: user._id,
userId: user._id,
name: user.name,
email: user.email,
role: user.role,
Expand All @@ -84,21 +84,21 @@ export class AuthService {
return { user, token };
}

async generateTokens({ id, name, email, role }) {
async generateTokens({ userId, name, email, role }) {
const payload = {
id: id,
userId: userId,
name: name,
email: email,
sub: id,
sub: userId,
role: role,
};
const accessToken = this.jwtService.sign(
{ id, ...payload },
{ userId, ...payload },
{ expiresIn: '10h' },
);

const refreshToken = uuidv4();
await this.storeRefreshToken(refreshToken, id);
await this.storeRefreshToken(refreshToken, userId);
return {
accessToken,
refreshToken,
Expand Down Expand Up @@ -142,7 +142,7 @@ export class AuthService {
const user = await this.usersService.findById(token.userId.toString());

return this.generateTokens({
id: user._id,
userId: user._id,
name: user.name,
email: user.email,
role: user.role,
Expand All @@ -165,7 +165,7 @@ export class AuthService {
}

redirectFederated(user: any, res: Response) {
this.logger.log('redirectFederated', user);
//this.logger.log('redirectFederated', user);
const { accessToken, refreshToken } = user || {};

if (accessToken) {
Expand Down
2 changes: 1 addition & 1 deletion src/auth/guards/auth.guard.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
Injectable,
CanActivate,
ExecutionContext,
Injectable,
UnauthorizedException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
Expand Down
2 changes: 1 addition & 1 deletion src/auth/strategies/google.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
profile: Profile,
done: VerifyCallback,
) {
this.logger.log('GoogleStrategy - Profile:', profile);
//this.logger.log('GoogleStrategy - Profile:', profile);
const { user, token } = await this.authService.loginFederated({
email: profile.emails[0].value,
name: profile.displayName,
Expand Down
2 changes: 1 addition & 1 deletion src/auth/strategies/microsoft.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class MicrosoftStrategy extends PassportStrategy(Strategy, 'microsoft') {
profile: Profile,
done: VerifyCallback,
) {
this.logger.log('MicrosoftStrategy - Profile:', JSON.stringify(profile));
//this.logger.log('MicrosoftStrategy - Profile:', JSON.stringify(profile));
const { user, token } = await this.authService.loginFederated({
email: profile.emails[0].value,
name: profile.displayName,
Expand Down
27 changes: 9 additions & 18 deletions src/dtos/create-user.dto.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,33 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsEmail, IsEnum, IsNotEmpty, IsOptional } from 'class-validator';
import { UserRole } from './user-role.enum';
import { IsEmail, IsNotEmpty } from 'class-validator';

export class CreateUserDto {
@ApiProperty({
example: 'Nome',
required: true
})
required: true,
})
@IsNotEmpty()
name: string;

@ApiProperty({
example: 'nome@dominio.com',
required: true
})
required: true,
})
@IsEmail()
@IsNotEmpty()
email: string;

@ApiProperty({
example: 'Username',
required: true
})
required: true,
})
@IsNotEmpty()
username: string;

@ApiProperty({
example: 'Senha123',
required: true
})
required: true,
})
@IsNotEmpty()
password: string;

@ApiProperty({
example: 'aluno',
required: false
})
@IsOptional()
@IsEnum(UserRole)
role?: UserRole;
}
38 changes: 35 additions & 3 deletions src/dtos/update-user.dto.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,36 @@
import { PartialType } from '@nestjs/mapped-types';
import { CreateUserDto } from './create-user.dto';
import { ApiProperty } from '@nestjs/swagger';
import { IsBoolean, IsEmail, IsOptional, IsString, MinLength } from 'class-validator';

export class UpdateUserDto extends PartialType(CreateUserDto) {}
export class UpdateUserDto {

@ApiProperty({
example: 'Nome',
required: false
})
@IsString()
@MinLength(3)
@IsOptional()
name?: string

@ApiProperty({
example: 'Username',
required: false
})
@IsString()
@MinLength(3)
@IsOptional()
username?: string

@ApiProperty({
example: 'email@email.com',
required: false
})
@IsEmail()
@IsOptional()
email?: string

@IsBoolean()
@IsOptional()
isVerified?: boolean

}
23 changes: 23 additions & 0 deletions src/users/users.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
Patch,
Post,
Query,
Req,
UseGuards,
UsePipes,
ValidationPipe,
Expand All @@ -18,6 +19,7 @@ import { Roles } from 'src/auth/guards/roles.decorator';
import { RolesGuard } from 'src/auth/guards/roles.guard';
import { CreateUserDto } from '../dtos/create-user.dto';
import { UpdateRoleDto } from '../dtos/update-role.dto';
import { UpdateUserDto } from '../dtos/update-user.dto';
import { UserRole } from '../dtos/user-role.enum';
import { UsersService } from './users.service';

Expand All @@ -38,6 +40,27 @@ export class UsersController {
}
}

@Patch('')
@UseGuards(JwtAuthGuard)
@UsePipes(ValidationPipe)
async updateUser(
@Req() req,
@Body() body: UpdateUserDto
) {
try {
const user = await this.usersService.updateUser(req.userId, body)

return {
message: `User ${user.username} updated successfully!`
}
} catch ( error ) {
if (error instanceof NotFoundException) {
throw new NotFoundException(`User with ID ${req.userId} not found`);
}
throw error;
}
}

@Get('verify')
async verifyUser(@Query('token') token: string) {
const user = await this.usersService.verifyUser(token);
Expand Down
10 changes: 5 additions & 5 deletions src/users/users.module.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { JwtModule } from '@nestjs/jwt';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { UserSchema } from './interface/user.schema';
import { MongooseModule } from '@nestjs/mongoose';
import { AuthService } from 'src/auth/auth.service';
import { EmailService } from './email.service';
import { RefreshTokenSchema } from './interface/refresh-token.schema';
import { ResetTokenSchema } from './interface/reset-token.schema';
import { AuthService } from 'src/auth/auth.service';
import { UserSchema } from './interface/user.schema';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
imports: [
Expand Down
42 changes: 37 additions & 5 deletions src/users/users.service.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import {
ConflictException,
Injectable,
NotFoundException,
ConflictException,
Injectable,
NotFoundException,
} from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { MongoError } from 'mongodb';
import { Model, Types } from 'mongoose';
import { CreateUserDtoFederated } from '../dtos/create-user-federated.dto';
import { CreateUserDto } from '../dtos/create-user.dto';
import { UpdateRoleDto } from '../dtos/update-role.dto';
import { UpdateUserDto } from '../dtos/update-user.dto';
import { UserRole } from '../dtos/user-role.enum';
import { EmailService } from './email.service';
import { User } from './interface/user.interface';
Expand All @@ -21,13 +22,13 @@ export class UsersService {
) {}

async createUser(createUserDto: CreateUserDto): Promise<User> {
const { name, email, username, password, role } = createUserDto;
const { name, email, username, password } = createUserDto;
const createdUser = new this.userModel({
name,
email,
username,
password,
role: role || UserRole.ALUNO,
role: UserRole.ALUNO,
});

try {
Expand All @@ -44,6 +45,37 @@ export class UsersService {
}
}

async updateUser ( userId: string, updateUserDto: UpdateUserDto ): Promise<User> {
await this.getUserById(userId);

if ( updateUserDto.email ) updateUserDto.isVerified = false;

var updateAttr = Object.fromEntries(
Object.entries(updateUserDto).filter(([value]) => value !== null)
)

try {
const updatedUser = await this.userModel.findByIdAndUpdate(
userId,
{ $set: updateAttr },
{
upsert: false,
new: true
}
)

if ( updateAttr['isVerified'] === false ) await this.emailService.sendVerificationEmail(updateAttr['email']);

return updatedUser;

} catch ( error ) {
if ( error instanceof MongoError ) {
throw new NotFoundException(`User with ID ${userId} not found!`)
}
throw error
}
}

async createFederatedUser(
createFederatedUserDto: CreateUserDtoFederated,
): Promise<any> {
Expand Down
10 changes: 5 additions & 5 deletions test/auth.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Logger, UnauthorizedException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { JwtService } from '@nestjs/jwt';
import { Test, TestingModule } from '@nestjs/testing';
import { Request } from 'express';
import { AuthController } from 'src/auth/auth.controller';
import { AuthService } from 'src/auth/auth.service';
import { JwtService } from '@nestjs/jwt';
import { ConfigService } from '@nestjs/config';
import { Logger, UnauthorizedException } from '@nestjs/common';
import { Request } from 'express';

describe('AuthController', () => {
let authController: AuthController;
Expand Down Expand Up @@ -58,7 +58,7 @@ describe('AuthController', () => {
const result = {
accessToken: 'token',
refreshToken: 'refresh-token',
id: 1,
userId: 1,
name: 'Test User',
email: 'test@test.com',
};
Expand Down
Loading

0 comments on commit 1dd2462

Please sign in to comment.