Skip to content

Instantly share code, notes, and snippets.

@chris-burkhardt
Last active October 27, 2021 03:39
Show Gist options
  • Save chris-burkhardt/906ed4a4a22bdb48f7cb249956798954 to your computer and use it in GitHub Desktop.
Save chris-burkhardt/906ed4a4a22bdb48f7cb249956798954 to your computer and use it in GitHub Desktop.
JS Upload Base64 Encoded Image to AWS S3 Bucket
'use strict'
const AWS = require("aws-sdk");
const S3 = new AWS.S3();
module.exports = async function (inputs, context) {
// example encoded images can be created here: https://www.base64-image.de/
// upload image to S3
try {
const s3BucketLocation = await uploadImageToS3(inputs.DeviceDiagnosticRequest.IMEIImage, "IMEIImage", inputs, context);
} catch (error) {
return Promise.reject(error);
}
return {
Response: {
Example: 'SomeValue'
}
};
}
/**
* Uploads a Base64 encoded string into an S3 bucket after validating its MIME type
*
* @param {string} imageData Base64 encoded image string
* @param {string} imageName Name of image for S3 bucket key
* @param {object} inputs Request object
* @param {object} context
*
* @returns The S3 bucker folder location as a string (does not include URL)
*/
async function uploadImageToS3(imageData, imageName, inputs, context) {
const imageMimeType = await validateImageMIMEType(imageData, inputs, context);
const body = Buffer.from(imageData.split('base64')[1], 'base64');
const ts = new Date().getTime();
// timestamp labeled image name
const s3ImageLocation = `folderName/${imageName.toLowerCase()}_${ts}.jpeg`
const params = {
Bucket: 's3-bucket-name-here',
Key: s3ImageLocation,
Body: Buffer.from(body, 'base64'),
ContentEncoding: 'base64',
ContentType: imageMimeType
};
try {
await S3.upload(params).promise();
return JSON.stringify(uploadOutput).body.Location;
}
catch (err) {
throwError(`Could not upload image data to S3 error: ${err}`, inputs, context);
}
}
/**
* Extracts the MIME type from the image in the request and throws error if its not supported type
*
* @param {string} imageData base64 encoded image data from request
* @param {object} inputs
* @param {object} context
*/
async function validateImageMIMEType(imageData, inputs, context) {
const imageDecode = /data:(.*);base64,(.*)/.exec(imageData);
const supportedMimeTypes = [
'image/jpeg',
'image/png',
'image/gif',
'image/bmp'
];
// imageDecode is null if something other than a base64 encoded image is sent in the request (string, int, etc.)
const imageMimeType = imageDecode ? imageDecode[1] : null;
const isSupportedMimeType = supportedMimeTypes.includes(imageMimeType);
if (!imageMimeType || !isSupportedMimeType) {
const errMessage = 'Upload not allowed due to invalid MIME type';
throwError(errMessage, inputs, context);
const error = new Error(errMessage);
error.status = 400;
error.code = 'ERR_UNSUPPORTED_MIME_TYPE'
throw error;
}
return imageMimeType;
}
/**
* Generates an error payload to be returned with promise reject
*
* @param {string} message
* @param {object} inputs
* @param {object} context
* @returns Object payload with error information
*/
function throwError(message, inputs, context) {
const errorLog = {
step: 'Diagnostics',
text: message,
payload: inputs,
};
logger.logMessage(
message,
context,
errorLog,
null,
'Diagnostics'
);
const error = new Error(message);
error.status = 400;
throw error;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment