Skip to content

Commit

Permalink
Merge pull request #11 from polijrorg/feat/update-optional
Browse files Browse the repository at this point in the history
Feat/update optional
  • Loading branch information
tassyla authored Aug 25, 2024
2 parents 6ffeacf + 5e2582c commit fd4e861
Show file tree
Hide file tree
Showing 13 changed files with 979 additions and 67 deletions.
880 changes: 876 additions & 4 deletions docs/bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/insomnia.json

Large diffs are not rendered by default.

13 changes: 8 additions & 5 deletions src/modules/users/dtos/IUpdateUserDTO.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
interface IUpdateUserDTO {
name: string;
email: string;
password: string;
language: string;
phone: string;
name?: string;
email?: string;
password?: string;
language?: string;
phone?: string;
image?: string;
gender?: string;
birthdate?: Date;
}

export default IUpdateUserDTO;
50 changes: 27 additions & 23 deletions src/modules/users/infra/http/controller/UsersController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,21 @@ export default class UserController {
}

public async readAll(req: Request, res: Response): Promise<Response> {

const readUsers = container.resolve(ReadAllUsersService);

const users = await readUsers.execute();

return res.status(201).json(users?.map(user => {
return {
...user,
password: undefined,
pin: undefined,
pinExpires: undefined,
};
}));

return res.status(201).json(users?.map((user) => ({
...user,
password: undefined,
pin: undefined,
pinExpires: undefined,
})));
}

public async readById(req: Request, res: Response): Promise<Response> {
const { id } = req.token;

const readUser = container.resolve(ReadUserByIdService);

const user = await readUser.execute({
Expand All @@ -80,18 +77,26 @@ export default class UserController {
password,
language,
phone,
image,
gender,
birthdate,
} = req.body;

const updateUser = container.resolve(UpdateUserService);

const user = await updateUser.execute({
const user = await updateUser.execute(
id,
name,
email,
password,
language,
phone,
});
{
name,
email,
password,
language,
phone,
image,
gender,
birthdate,
},
);

return res.status(201).json({
...user,
Expand Down Expand Up @@ -127,7 +132,7 @@ export default class UserController {
email,
});

return res.status(201).json({id: user.id});
return res.status(201).json({ id: user.id });
}

public async verifyPin(req: Request, res: Response): Promise<Response> {
Expand All @@ -141,7 +146,7 @@ export default class UserController {
pin,
});

return res.status(201).json({id: user.id});
return res.status(201).json({ id: user.id });
}

public async resetPassword(req: Request, res: Response): Promise<Response> {
Expand All @@ -150,9 +155,8 @@ export default class UserController {

const resetPassword = container.resolve(ResetPasswordService);

const user = await resetPassword.execute({id, pin, password});
const user = await resetPassword.execute({ id, pin, password });

return res.status(201).json({id: user.id});
return res.status(201).json({ id: user.id });
}

}
1 change: 0 additions & 1 deletion src/modules/users/infra/http/routes/users.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,4 @@ usersRoutes.post('/send-pin', usersController.sendPin);
usersRoutes.post('/verify-pin/:id', usersController.verifyPin);
usersRoutes.post('/reset-password/:id', usersController.resetPassword);


export default usersRoutes;
3 changes: 3 additions & 0 deletions src/modules/users/infra/prisma/entities/users.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ model Users {
phone String
pin String?
pinExpires DateTime?
image String?
gender String?
birthdate DateTime?
created_at DateTime @default(now())
updated_at DateTime @default(now())
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ export default class UsersRepository implements IUsersRepository {
where: { email },
data: { pin, pinExpires },
});

}

public resetPassword(id: string, password: string): Promise<Users> {
Expand All @@ -70,5 +69,4 @@ export default class UsersRepository implements IUsersRepository {
data: { password },
});
}

}
1 change: 0 additions & 1 deletion src/modules/users/services/ReadAllUsersService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export default class ReadAllUsersService {
) { }

public async execute(): Promise<Users[] | null> {

const users = this.usersRepository.findAll();

return users;
Expand Down
12 changes: 6 additions & 6 deletions src/modules/users/services/ResetPasswordService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ export default class ResetPasswordService {
private hashProvider: IHashProvider,
) { }

public async execute({
id,
pin,
password,
}: IRequest): Promise<Users> {
public async execute({
id,
pin,
password,
}: IRequest): Promise<Users> {
const userAlreadyExists = await this.usersRepository.findById(id);

if (!userAlreadyExists) throw new AppError('User with this id does not exist');

if (userAlreadyExists?.pinExpires && userAlreadyExists.pin != pin) throw new AppError('Pin is incorrect');
if (userAlreadyExists?.pinExpires && userAlreadyExists.pinExpires < new Date()) throw new AppError('Pin is expired');

Expand Down
12 changes: 6 additions & 6 deletions src/modules/users/services/SendPinToUserEmailService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default class SendPinToUserEmailService {
}: IRequest): Promise<Users> {
const userAlreadyExists = await this.usersRepository.findByEmailWithRelations(email);
if (!userAlreadyExists) throw new AppError('User with this email does not exist');

const expiration = 15;
const pin = Math.floor(Math.random() * 9999).toString();
const data = new Date();
Expand All @@ -34,13 +34,13 @@ export default class SendPinToUserEmailService {
data,
);

sgMail.setApiKey(process.env.SENDGRID_API_KEY as string)
sgMail.setApiKey(process.env.SENDGRID_API_KEY as string);
const msg = {
to: email,
from: '[email protected]',
to: email,
from: '[email protected]',
subject: 'Apogeo | Recuperação de senha',
text: user.name + ', seu pin para recuperação de senha é: ' + pin + '. O processo de recuperação expira em ' + expiration + ' minutos.',
html: user.name + ', seu pin para recuperação de senha é: <strong>' + pin + '</strong>. O processo de recuperação expira em ' + expiration + ' minutos.',
text: `${user.name}, seu pin para recuperação de senha é: ${pin}. O processo de recuperação expira em ${expiration} minutos.`,
html: `${user.name}, seu pin para recuperação de senha é: <strong>${pin}</strong>. O processo de recuperação expira em ${expiration} minutos.`,
};

try {
Expand Down
63 changes: 45 additions & 18 deletions src/modules/users/services/UpdateUserService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import IHashProvider from '@shared/container/providers/HashProvider/models/IHash
import IUsersRepository from '../repositories/IUsersRepository';

interface IRequest {
id: string;
name: string;
email: string;
password: string;
language: string;
phone: string;
name?: string;
email?: string;
password?: string;
language?: string;
phone?: string;
image?: string;
gender?: string;
birthdate?: Date;
}

@injectable()
Expand All @@ -26,24 +28,49 @@ export default class UpdateUserService {
private hashProvider: IHashProvider,
) { }

public async execute({
id, name, email, password, language, phone,
}: IRequest): Promise<Users> {
public async execute(id: string, updateData: IRequest): Promise<Users> {
const userAlreadyExists = await this.usersRepository.findById(id);

if (!userAlreadyExists) throw new AppError('User with this id does not exist');
if (updateData.email) {
const userWithUpdatedEmail = await this.usersRepository.findByEmailWithRelations(updateData.email);
if (userWithUpdatedEmail) {
if (userWithUpdatedEmail.id == id) {
throw new AppError('You cannot update your email to the same email');
}
if (userWithUpdatedEmail.id !== id) {
throw new AppError('User with same email already exists');
}
}
}
if (updateData.birthdate || updateData.birthdate == '') {
const birthdate = new Date(updateData.birthdate);
if (isNaN(birthdate.getTime())) {
throw new AppError('Birthdate is not a valid date');
}

const hashedPassword = await this.hashProvider.generateHash(password);
if (birthdate > new Date()) {
throw new AppError('Birthdate cannot be greater than current date');
}
}

const data = { ...userAlreadyExists, ...updateData };

let hashedPassword;
if (data.password) {
hashedPassword = await this.hashProvider.generateHash(data.password.toString());
} else {
hashedPassword = data.password;
}

const updatedUser = this.usersRepository.update(
id,
{
name,
email: email.toLowerCase(),
password: hashedPassword,
language,
phone,
});
id,
{
...data,
email: data.email?.toLowerCase(),
password: hashedPassword,
},
);

return updatedUser;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- AlterTable
ALTER TABLE "Users" ADD COLUMN "birthdate" TIMESTAMP(3),
ADD COLUMN "gender" TEXT,
ADD COLUMN "image" TEXT;
3 changes: 3 additions & 0 deletions src/shared/infra/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ model Users {
phone String
pin String?
pinExpires DateTime?
image String?
gender String?
birthdate DateTime?
created_at DateTime @default(now())
updated_at DateTime @default(now())
}

0 comments on commit fd4e861

Please sign in to comment.