Skip to content

Commit

Permalink
Merge branch 'main' of github.com:polijrorg/Apogeo-Back
Browse files Browse the repository at this point in the history
  • Loading branch information
tassyla committed Oct 20, 2024
2 parents 2469234 + 2da069f commit efbef64
Show file tree
Hide file tree
Showing 11 changed files with 1,532 additions and 28 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# npm
node_modules
package-lock.json
yarn.lock
*.log
*.gz

Expand Down
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@types/cors": "^2.8.10",
"@types/express": "^4.17.11",
"@types/jsonwebtoken": "^8.5.0",
"@types/multer": "^1.4.12",
"@types/nodemailer": "^6.4.0",
"@types/swagger-ui-express": "^4.1.3",
"@types/uuid": "^8.3.0",
Expand All @@ -41,6 +42,8 @@
"typescript": "^4.1.5"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.675.0",
"@aws-sdk/s3-request-presigner": "^3.675.0",
"@prisma/client": "^3.14.0",
"@sendgrid/mail": "^8.1.3",
"aws-sdk": "^2.846.0",
Expand All @@ -52,12 +55,14 @@
"handlebars": "^4.7.7",
"jsonwebtoken": "^9.0.2",
"moment": "^2.30.1",
"multer": "^1.4.5-lts.1",
"nodemailer": "^6.4.18",
"openapi-types": "^10.0.0",
"pg": "^8.5.1",
"prisma": "^3.14.0",
"prisma-aurora": "^1.3.6",
"reflect-metadata": "^0.1.13",
"sharp": "^0.33.5",
"swagger-ui-express": "^4.3.0",
"tsyringe": "^4.8.0",
"typeorm": "^0.2.31",
Expand Down
6 changes: 3 additions & 3 deletions src/modules/users/dtos/IUpdateUserDTO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ interface IUpdateUserDTO {
password?: string;
language?: string;
phone?: string;
image?: string;
gender?: string;
birthdate?: Date;
image?: string | Buffer | null;
gender?: string | null;
birthdate?: Date | null;
}

export default IUpdateUserDTO;
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default class PedigreeController {
id,
});

return res.status(201).json(user.pedigree);
return res.status(201).json(user?.pedigree);
}

public async save(req: Request, res: Response): Promise<Response> {
Expand Down
2 changes: 2 additions & 0 deletions src/modules/users/infra/http/controller/SessionsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Request, Response } from 'express';
import { container } from 'tsyringe';

import AuthenticateUserService from '@modules/users/services/AuthenticateUserService';
import generateUserImageUrl from '@shared/infra/http/middlewares/GenerateUserImageUrl';

export default class SessionsController {
public async create(req: Request, res: Response): Promise<Response> {
Expand All @@ -21,6 +22,7 @@ export default class SessionsController {
pin: undefined,
pinExpires: undefined,
pedigree: undefined,
image: user ? await generateUserImageUrl(user) : null,
});

return res.json({ ommitedUser, token });
Expand Down
6 changes: 5 additions & 1 deletion src/modules/users/infra/http/controller/UsersController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import UpdateUserService from '@modules/users/services/UpdateUserService';
import SendPinToUserEmailService from '@modules/users/services/SendPinToUserEmailService';
import VerifyPinService from '@modules/users/services/VerifyPinService';
import ResetPasswordService from '@modules/users/services/ResetPasswordService';
import generateUserImageUrl from '@shared/infra/http/middlewares/GenerateUserImageUrl';

export default class UserController {
public async create(req: Request, res: Response): Promise<Response> {
Expand Down Expand Up @@ -68,6 +69,7 @@ export default class UserController {
pin: undefined,
pinExpires: undefined,
pedigree: undefined,
image: user ? await generateUserImageUrl(user) : null,
});
}

Expand All @@ -80,12 +82,13 @@ export default class UserController {
password,
language,
phone,
image,
gender,
birthdate,
pedigree,
} = req.body;

const image = req.file ? req.file.buffer : undefined;

const updateUser = container.resolve(UpdateUserService);

const user = await updateUser.execute(
Expand All @@ -109,6 +112,7 @@ export default class UserController {
pin: undefined,
pinExpires: undefined,
pedigree: undefined,
image: user ? await generateUserImageUrl(user) : null,
});
}

Expand Down
8 changes: 5 additions & 3 deletions src/modules/users/infra/http/routes/users.routes.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import ensureAuthenticated from '@shared/infra/http/middlewares/EnsureAuthenticated';
import { Router } from 'express';

import multer from 'multer';
import UsersController from '../controller/UsersController';

const usersRoutes = Router();

const usersController = new UsersController();

const storage = multer.memoryStorage();
const upload = multer({ storage: storage});

usersRoutes.post('/register', usersController.create);
usersRoutes.patch('/update', ensureAuthenticated, usersController.update);
usersRoutes.patch('/update',upload.single('image'), ensureAuthenticated, usersController.update);
usersRoutes.delete('/delete', ensureAuthenticated, usersController.delete);
usersRoutes.get('/readAll', usersController.readAll);
usersRoutes.get('/read', ensureAuthenticated, usersController.readById);
Expand Down
23 changes: 23 additions & 0 deletions src/modules/users/services/DeleteUserService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import AppError from '@shared/errors/AppError';

import IHashProvider from '@shared/container/providers/HashProvider/models/IHashProvider';
import IUsersRepository from '../repositories/IUsersRepository';
import { DeleteObjectCommand, S3Client } from '@aws-sdk/client-s3';

const bucketRegion = process.env.BUCKET_REGION
const accessKey = process.env.ACCESS_KEY
const secretAccessKey = process.env.SECRET_ACCESS_KEY

interface IRequest {
id: string;
Expand All @@ -26,6 +31,24 @@ export default class DeleteUserService {

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

if (userAlreadyExists.image) {
const s3 = new S3Client({
region: bucketRegion,
credentials: {
accessKeyId: accessKey as string,
secretAccessKey: secretAccessKey as string
}
});

const getObjectParams = {
Bucket: process.env.BUCKET_NAME,
Key: userAlreadyExists.image,
}

const command = await new DeleteObjectCommand(getObjectParams);
await s3.send(command);
}

const deletedUser = this.usersRepository.delete(id);

return deletedUser;
Expand Down
39 changes: 38 additions & 1 deletion src/modules/users/services/UpdateUserService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,21 @@ import AppError from '@shared/errors/AppError';
import IHashProvider from '@shared/container/providers/HashProvider/models/IHashProvider';
import IUsersRepository from '../repositories/IUsersRepository';

import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import sharp from 'sharp';

const bucketName = process.env.BUCKET_NAME
const bucketRegion = process.env.BUCKET_REGION
const accessKey = process.env.ACCESS_KEY
const secretAccessKey = process.env.SECRET_ACCESS_KEY

interface IRequest {
name?: string;
email?: string;
password?: string;
language?: string;
phone?: string;
image?: string;
image?: Buffer;
gender?: string;
birthdate?: Date;
pedigree?: JSON;
Expand Down Expand Up @@ -64,6 +72,35 @@ export default class UpdateUserService {
hashedPassword = data.password;
}

if(!data.pedigree) {
const s3 = new S3Client({
region: bucketRegion,
credentials: {
accessKeyId: accessKey as string,
secretAccessKey: secretAccessKey as string
}
});

if (data.image && s3) {

const buffer = await sharp(data.image).resize({height: 300, width: 300, fit: 'contain'}).png().toBuffer();

const params = {
Bucket: bucketName,
Key: `${id}.png`,
Body: buffer,
ContentType: 'image/png',
};

try {
await s3.send(new PutObjectCommand(params));
data.image = `${id}.png`;
} catch (error: any) {
throw new AppError('Error uploading image to S3');
}
}
}

const updatedUser = this.usersRepository.update(
id,
{
Expand Down
32 changes: 32 additions & 0 deletions src/shared/infra/http/middlewares/GenerateUserImageUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Users } from '@prisma/client';
import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';

const bucketRegion = process.env.BUCKET_REGION
const accessKey = process.env.ACCESS_KEY
const secretAccessKey = process.env.SECRET_ACCESS_KEY

export default async function generateUserImageUrl(user: Users): Promise<String | null> {
let url = null;

if (user.image) {

const s3 = new S3Client({
region: bucketRegion,
credentials: {
accessKeyId: accessKey as string,
secretAccessKey: secretAccessKey as string
}
});

const getObjectParams = {
Bucket: process.env.BUCKET_NAME,
Key: user.image,
}

const command = new GetObjectCommand(getObjectParams);
url = await getSignedUrl(s3, command, { expiresIn: 3600 });
}

return url;
}
Loading

0 comments on commit efbef64

Please sign in to comment.