S3 client module:
import * as AWS from 'aws-sdk'
export const REGION = 'eu-west-1'
export const TMP_FILES_CREDENTIALS = {
AWS_ACCESS_KEY_ID: '...',
AWS_SECRET_ACCESS_KEY: '...'
}
export const TMP_FILES_BUCKET = 'tmp-files'
export function configure(credentials: object) {
AWS.config.update({
region: REGION,
credentials: new AWS.Credentials(credentials['AWS_ACCESS_KEY_ID'], credentials['AWS_SECRET_ACCESS_KEY'])
})
}
export function upload(bucket: string, key: string, body: any, contentType: string) {
const s3 = new AWS.S3({params: {Bucket: bucket}})
const params = {Bucket: bucket, Key: key, ContentType: contentType, Body: body, ACL: 'public-read'}
// Documentation: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property
return s3.upload(params)
}
Test:
import client from './s3.upload.client'
import { assertEqual } from '../shared/spec-helper'
import HttpClient from '../shared/http-client'
describe('s3.upload.client', () => {
describe('upload', () => {
it('can upload a file to S3', (done) => {
client.configure(client.TMP_FILES_CREDENTIALS)
const bucket = client.TMP_FILES_BUCKET
const key = 'a2e2ad5b798a4242a4cac6367ba3a9c0.xml'
const data = '<s3-upload-client-test/>'
const contentType = 'application/xml'
client.upload(bucket, key, data, contentType)
.promise().then((result: any) => {
// console.log('s3.upload.client upload complete')
assertEqual(result['Key'], key)
assertEqual(result['Bucket'], bucket)
const url = result['Location']
HttpClient.get(url).then((result: object) => {
// console.log('s3.upload.client fetched S3 file from public URL', url)
assertEqual(result['data'], data)
done()
})
}, (error: any) => {
console.log('s3.upload.client error', error)
assertEqual(false, true)
})
})
})
})
A dedicated Tmp file upload user belonging to a "TmpFile" IAM Group with a policy that allows access to a specific tmp-files
bucket:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectAcl",
"s3:GetObjectTagging",
"s3:GetObjectTorrent",
"s3:GetObjectVersion",
"s3:GetObjectVersionAcl",
"s3:GetObjectVersionTagging",
"s3:GetObjectVersionTorrent",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutObjectTagging",
"s3:PutObjectVersionAcl",
"s3:PutObjectVersionTagging",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::tmp-files/*"
]
}
]
}
Bucket CORS configuration:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedMethod>GET</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
<ExposeHeader>ETag</ExposeHeader>
</CORSRule>
</CORSConfiguration>