Converting a buffer to a base64-string
Buffer.from(buffer.Body, 'binary').toString('base64')
Serializing a buffer (JSON.stringify(buffer)) can increase the content size (JSON.stringify(biuffer).length) a lot. It might be better to convert the buffer to a base64 string when transporting it between different backends. File-upload from frontend to backend usually happens through a buffer.
Uploading a file to S3
const body = typeof fileToUpload === 'string' ? Buffer.from(fileToUpload as string, 'base64') : (fileToUpload as { file: FileUpload }).file?.createReadStream(); // second option is in the case of an upload through graphql-upload package
const RAND_BYTE_LENGTH = 20;
const rnd = crypto.randomBytes(RAND_BYTE_LENGTH);
hash = crypto
.createHash('sha256')
.update(name + rnd)
.digest('hex');
const keyName = `${S3_fOLDER}/${hash}`;
if (!body) {
throw new Error('No file to upload found');
}
const params = {
Bucket: process.env.S3_BUCKET,
Key: keyName,
Body: body,
ContentType: /* mimetype of file */,
};
await this.s3.upload(params).promise();
Creating a presigned url from S3
const params = {
Bucket: process.env.S3_BUCKET,
Key: `${S3_fOLDER}/${hash}`,
Expires: 3600, // 60 min
ResponseContentDisposition: download ? undefined : 'inline',
ResponseContentType: download ? undefined : mimetype,
};
return await this.s3.getSignedUrlPromise('getObject', params);
Showing a base64 file in the browser
For images
<img src=`data:${type};base64,${base64}`/>
For pdf
const pdfWindow = window.open('');
const binStr = atob(base64);
const len = binStr.length;
const arr = new Uint8Array(len);
for (let i = 0; i < len; i++) {
arr[i] = binStr.charCodeAt(i);
}
const blob = new Blob([arr], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
pdfWindow?.document.write('<html<head><style>body{margin: 0px;}iframe{border-width: 0px;}</style></head>');
pdfWindow?.document.write(`<body><embed width='100%' height='100%' src='${url}'></embed></body></html>`);
File upload protection defaults
By default , node has a file-upload limit. (= Payload to large error in backend terminal) Solve it by highering the limits:
app.use(json({ limit: '50mb' }));
app.use(urlencoded({ extended: true, limit: '50mb' }));
By default, nginx prevents a file upload bigger then 1Mb. (Payload too large error in frontend network tab with no size limit specified and a ref to nginx) . Solve it by adding annotations to the config files:
for ingress: nginx.ingress.kubernetes.io/proxy-body-size: 25m
for nginx config:client_max_body_size 25M;
Request CSP headers on a frontend to backend call, can prevent certain visualisatons. For example obj-src ‘self’ will prevent a pdf from viewing inside an embed-tag. Check the following tool for security
Chrome prevents the preview of an embedded data:-src that is bigger then 1-2Mb (The screen that shows the pdf stays blank). Therefore it is better to use a blob. (See code in showing a pdf in browser)
Be First to Comment