Skip to content

Commit

Permalink
fix(BREAKING CHANGE): Refactor file uploads for aws-s3
Browse files Browse the repository at this point in the history
  • Loading branch information
icleitoncosta committed Jul 6, 2023
1 parent d06bd67 commit f7f6eab
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 19 deletions.
6 changes: 6 additions & 0 deletions README.md
Expand Up @@ -212,6 +212,12 @@ This server use config.ts file to define some options, default values are:
redisDb: 0,
redisPrefix: 'docker',
},
// Your configurations yo upload on AWS
aws_s3: {
region: 'sa-east-1',
access_key_id: '',
secret_key: '',
},
}
```

Expand Down
6 changes: 0 additions & 6 deletions package.json
Expand Up @@ -26,16 +26,10 @@
"swagger:fix-url": "sed -i \"s|https://petstore.swagger.io/v2/swagger.json|./swagger.json|g\" ./swagger-docs/index.html",
"swagger:generate": "yarn swagger:copy-assets && yarn swagger:copy-json && yarn swagger:fix-url"
},
"config": {
"commitizen": {
"path": "@commitlint/cz-commitlint"
}
},
"dependencies": {
"@wppconnect-team/wppconnect": "^1.27.3",
"archiver": "^5.3.1",
"@aws-sdk/client-s3": "^3.359.0",
"aws-sdk": "^2.1401.0",
"axios": "^1.4.0",
"bcrypt": "^5.1.0",
"buffer-to-stream": "1.0.0",
Expand Down
5 changes: 5 additions & 0 deletions src/config.ts
Expand Up @@ -80,4 +80,9 @@ export default {
redisDb: 0,
redisPrefix: 'docker',
},
aws_s3: {
region: 'sa-east-1',
access_key_id: '',
secret_key: '',
},
};
4 changes: 4 additions & 0 deletions src/index.ts
Expand Up @@ -20,6 +20,7 @@ import express, { NextFunction } from 'express';
import boolParser from 'express-query-boolean';
import { createServer } from 'http';
import mergeDeep from 'merge-deep';
import process from 'process';
import { Server as Socket } from 'socket.io';

import { version } from '../package.json';
Expand Down Expand Up @@ -56,6 +57,9 @@ export function initServer(serverOptions: any) {
app.use('/files', express.static('WhatsAppImages'));
app.use(boolParser());

process.env['AWS_ACCESS_KEY_ID'] = config.aws_s3.access_key_id;
process.env['AWS_SECRET_ACCESS_KEY'] = config.aws_s3.secret_key;

// Add request options
app.use((req: any, res: any, next: NextFunction) => {
req.serverOptions = serverOptions;
Expand Down
25 changes: 25 additions & 0 deletions src/util/bucketAlreadyExists.ts
@@ -0,0 +1,25 @@
import { HeadBucketCommand, S3Client } from '@aws-sdk/client-s3';

import { logger } from '..';
import config from '../config';

export async function bucketAlreadyExists(bucketName: string) {
// eslint-disable-next-line no-async-promise-executor
return new Promise(async (resolve, reject) => {
const s3Client = new S3Client({ region: config.aws_s3.region });

const command = new HeadBucketCommand({ Bucket: bucketName });

try {
await s3Client.send(command);
resolve(true);
} catch (error: any) {
if (error.name === 'NoSuchBucket' || error.name === 'NotFound') {
resolve(false);
} else {
logger.error(error);
reject(error);
}
}
});
}
63 changes: 50 additions & 13 deletions src/util/functions.ts
@@ -1,5 +1,5 @@
/*
* Copyright 2021 WPPConnect Team
* Copyright 2023 WPPConnect Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -13,7 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const { aws } = require("@aws-sdk/client-s3");
import {
CreateBucketCommand,
PutObjectCommand,
PutPublicAccessBlockCommand,
S3Client,
} from '@aws-sdk/client-s3';
import api from 'axios';
import Crypto from 'crypto';
import fs from 'fs';
Expand All @@ -25,6 +30,7 @@ import { promisify } from 'util';
import config from '../config';
import { convert } from '../mapper/index';
import { ServerOptions } from '../types/ServerOptions';
import { bucketAlreadyExists } from './bucketAlreadyExists';

let mime: any, crypto: any; //, aws: any;
if (config.webhook.uploadS3) {
Expand Down Expand Up @@ -136,23 +142,54 @@ async function autoDownload(client: any, req: any, message: any) {
if (req.serverOptions.webhook.uploadS3) {
const hashName = crypto.randomBytes(24).toString('hex');

const s3 = new aws.S3();
const bucketName = config.webhook?.awsBucketName
if (
!config.aws_s3.region ||
config.aws_s3.access_key_id ||
!config.aws_s3.secret_key
)
throw new Error('Please, configure your aws configs');
const s3Client = new S3Client({ region: config.aws_s3.region });
let bucketName = config.webhook?.awsBucketName
? config.webhook?.awsBucketName
: client.session;
bucketName = bucketName
.normalize('NFD')
.replace(/[\u0300-\u036f]|[-— _.,?!]/g, '')
.toLowerCase();
const fileName = `${
config.webhook?.awsBucketName ? client.session + '/' : ''
}${hashName}.${mime.extension(message.mimetype)}`;

const params = {
Bucket: bucketName,
Key: fileName,
Body: buffer,
ACL: 'public-read',
ContentType: message.mimetype,
};
const data = await s3.upload(params).promise();
message.fileUrl = data.Location;
if (!(await bucketAlreadyExists(bucketName))) {
await s3Client.send(
new CreateBucketCommand({
Bucket: bucketName,
ObjectOwnership: 'ObjectWriter',
})
);
await s3Client.send(
new PutPublicAccessBlockCommand({
Bucket: bucketName,
PublicAccessBlockConfiguration: {
BlockPublicAcls: false,
IgnorePublicAcls: false,
BlockPublicPolicy: false,
},
})
);
}

await s3Client.send(
new PutObjectCommand({
Bucket: bucketName,
Key: fileName,
Body: buffer,
ContentType: message.mimetype,
ACL: 'public-read',
})
);

message.fileUrl = `https://${bucketName}.s3.amazonaws.com/${fileName}`;
} else {
message.body = await buffer.toString('base64');
}
Expand Down

0 comments on commit f7f6eab

Please sign in to comment.