Skip to content

Commit

Permalink
feat: aws, upload api (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
HungLV46 committed Aug 17, 2024
1 parent db84498 commit 63468a0
Show file tree
Hide file tree
Showing 6 changed files with 1,196 additions and 9 deletions.
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,10 @@ HOST=localhost
DATABASE_URL=postgresql://postgres:password@localhost:5432/ip-scan?schema=public
REDIS_URL=localhost:6379
ELASTICSEARCH_URL=http://localhost:9200

S3_ACCESS_KEY=xxx
S3_ACCESS_KEY_ID=xxx
S3_BUCKET=ipscan
S3_BUCKET_FOLDER=dev
S3_DOMAIN_NAME=xxx.amazonaws.com
S3_REGION=xxx
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"style:check": "yarn eslint"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.629.0",
"@bull-board/hapi": "^5.21.1",
"@elastic/elasticsearch": "^8.14.0",
"@hapi/boom": "^10.0.1",
Expand All @@ -43,6 +44,7 @@
"joi": "^17.13.3",
"lint-check": "^0.0.2",
"pino": "^9.3.2",
"randomstring": "^1.3.0",
"underscore": "^1.13.7",
"viem": "^2.19.2"
},
Expand All @@ -52,6 +54,7 @@
"@hapi/code": "^9.0.3",
"@hapi/lab": "^25.3.1",
"@types/node": "^20.14.12",
"@types/randomstring": "^1.3.0",
"eslint": "9.x",
"git-format-staged": "^3.1.1",
"globals": "^15.8.0",
Expand Down
15 changes: 8 additions & 7 deletions src/apis/routes/utils/upload.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { logger } from '#common/loggger';
import { save } from '#common/aws';
import Hapi from '@hapi/hapi';
import Joi from 'joi';

Expand All @@ -21,18 +21,19 @@ export const uploadFileRoute: Hapi.ServerRoute = {
.description('file to upload'),
}),
},
// parse = true, will load the whole file to memory
payload: {
multipart: true,
maxBytes: 1048576,
parse: true,
output: 'file',
output: 'stream',
},
},
handler: async (request: Hapi.Request) => {
const file = request.payload;
logger.warn(file);
return {
message: 'Uploaded',
};
const file = request.payload as any;

const s3Url = await save(file);

return { data: { s3_url: s3Url } };
},
};
59 changes: 59 additions & 0 deletions src/common/aws.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { config } from '#configs/index';
import { S3, PutObjectCommand } from '@aws-sdk/client-s3';
import path from 'path';
import randomstring from 'randomstring';

const s3 = new S3({
region: config.s3Region,
credentials: {
accessKeyId: config.s3AccessKeyId,
secretAccessKey: config.s3SecretAccessKey,
},
});

function getS3Url(fileName: string) {
return `https://${config.s3DomainName}/${config.s3BucketFolder}/${fileName}`;
}

function generateFilename(filename: string) {
return `${randomstring.generate({ length: 32, charset: 'alphanumeric' })}${path.extname(filename)}`;
}

function generateS3Key(fileName: string) {
return `${config.s3BucketFolder}/${fileName}`;
}

async function isExit(filename: string): Promise<boolean> {
try {
await s3.headObject({
Bucket: process.env.S3_BUCKET,
Key: generateS3Key(filename),
});

return true;
} catch (error) {
return false;
}
}

async function save(fileStream: any): Promise<string> {
const filename = generateFilename(fileStream.file.hapi.filename);

if (await isExit(filename)) {
throw new Error(`Filename (${filename}) is already existed on S3`);
}

const command = new PutObjectCommand({
Bucket: config.s3BucketName,
Body: fileStream.file._data,
Key: generateS3Key(filename),
ContentType: fileStream.file.hapi.headers['content-type'],
});

// Upload to s3
await s3.send(command);

return getS3Url(filename);
}

export { s3, save };
8 changes: 8 additions & 0 deletions src/configs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,12 @@ export const config = {

// Network
chainId: Number(process.env.CHAIN_ID || 1),

// AWS
s3Region: String(process.env.S3_REGION || ''),
s3AccessKeyId: String(process.env.S3_ACCESS_KEY_ID || ''),
s3SecretAccessKey: String(process.env.S3_ACCESS_KEY || ''),
s3DomainName: String(process.env.S3_DOMAIN_NAME || ''),
s3BucketName: String(process.env.S3_BUCKET_NAME || ''),
s3BucketFolder: String(process.env.S3_BUCKET_FOLDER || ''),
};
Loading

0 comments on commit 63468a0

Please sign in to comment.