-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add example for Uppy with S3 and a Node.js server (#4129)
Co-authored-by: Merlijn Vos <merlijn@soverin.net> Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com>
- Loading branch information
1 parent
a315381
commit 3f07d79
Showing
19 changed files
with
366 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
# Uppy + AWS S3 with Node.JS | ||
|
||
A simple and fully working example of Uppy and AWS S3 storage with Node.js (and Express.js) It uses presigned URL at the backend level. | ||
|
||
This README file starts with AWS as this one need to be resolved first. | ||
|
||
# AWS Configuration | ||
|
||
It's assumed that you are familiar with AWS, at least, with the storage service (S3) and users & policies (IAM). | ||
|
||
These instructions are not fit for production but tightening the security is out of the scope here. | ||
|
||
## S3 Setup | ||
|
||
- Create new S3 bucket in AWS (e.g. `aws-nodejs`). | ||
- Add a bucket policy. | ||
```{ | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Sid": "PublicAccess", | ||
"Effect": "Allow", | ||
"Principal": "*", | ||
"Action": "s3:GetObject", | ||
"Resource": "arn:aws:s3:::aws-nodejs/*" | ||
} | ||
] | ||
} | ||
``` | ||
|
||
- Make the S3 bucket public. | ||
- Add CORS configuration. | ||
```[ | ||
{ | ||
"AllowedHeaders": [ | ||
"*" | ||
], | ||
"AllowedMethods": [ | ||
"GET", | ||
"PUT", | ||
"HEAD", | ||
"POST", | ||
"DELETE" | ||
], | ||
"AllowedOrigins": [ | ||
"*" | ||
], | ||
"ExposeHeaders": [] | ||
} | ||
] | ||
``` | ||
|
||
## AWS Credentials | ||
|
||
You may use existing AWS credentials or create a new user in the IAM page. | ||
|
||
- Make sure you setup the AWS credentials properly and write down the Access Key ID and Secret Access Key. | ||
- You may configure AWS S3 credentials using [environment variables](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-node-credentials-environment.html) or a [credentials file in `~/.aws/credentials`](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html). | ||
- You will need at least `PutObject` and `PutObjectAcl` permissions. | ||
```{ | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Sid": "VisualEditor0", | ||
"Effect": "Allow", | ||
"Action": [ | ||
"s3:PutObject", | ||
"s3:PutObjectAcl" | ||
], | ||
"Resource": "arn:aws:s3:::aws-nodejs/*" | ||
} | ||
] | ||
} | ||
``` | ||
# Install | ||
|
||
Download this code or clone repository into a folder and install dependencies: | ||
|
||
```bash | ||
corepack yarn install | ||
``` | ||
|
||
Add a `.env` file to the root directory and define the S3 bucket name and port variables like the example below: | ||
|
||
``` | ||
S3_BUCKET=aws-nodejs | ||
PORT=8080 | ||
``` | ||
|
||
# Enjoy it | ||
|
||
Start the application: | ||
|
||
```bash | ||
corepack yarn workspace @uppy-example/aws-nodejs start | ||
``` | ||
|
||
Dashboard demo should now be available at http://localhost:8080. | ||
|
||
You have also a Drag & Drop demo on http://localhost:8080/drag. | ||
|
||
*Feel free to check how the demo works and feel free to open an issue.* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
require('dotenv').config({ path: path.join(__dirname, '..', '..', '.env') }) | ||
|
||
const express = require('express') | ||
|
||
const app = express() | ||
const path = require('node:path') | ||
|
||
const port = process.env.PORT | ||
const bodyParser = require('body-parser') | ||
|
||
const aws = require('aws-sdk') | ||
|
||
app.use(bodyParser.json()) | ||
|
||
app.get('/', (req, res) => { | ||
const htmlPath = path.join(__dirname, 'public', 'index.html') | ||
res.sendFile(htmlPath) | ||
}) | ||
|
||
app.get('/drag', (req, res) => { | ||
const htmlPath = path.join(__dirname, 'public', 'drag.html') | ||
res.sendFile(htmlPath) | ||
}) | ||
|
||
app.post('/sign-s3', (req, res) => { | ||
const s3 = new aws.S3() | ||
const fileName = req.body.filename | ||
const { contentType } = req.body | ||
const s3Params = { | ||
Bucket: process.env.S3_BUCKET, | ||
Key: fileName, | ||
Expires: 60, | ||
ContentType: contentType, | ||
ACL: 'public-read', | ||
} | ||
|
||
s3.getSignedUrl('putObject', s3Params, (err, data) => { | ||
if (err) { | ||
console.log(err) | ||
return res.end() | ||
} | ||
const returnData = { | ||
url: data, | ||
method: 'PUT', | ||
} | ||
res.write(JSON.stringify(returnData)) | ||
res.end() | ||
}) | ||
}) | ||
|
||
app.listen(port, () => { | ||
console.log(`Example app listening on port ${port}`) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"name": "@uppy-example/aws-nodejs", | ||
"version": "1.0.0", | ||
"description": "Uppy for AWS S3 with a custom Node.js backend for signing URLs", | ||
"main": "index.js", | ||
"scripts": { | ||
"start": "node index.js" | ||
}, | ||
"author": "", | ||
"license": "MIT", | ||
"dependencies": { | ||
"aws-sdk": "^2.1038.0", | ||
"body-parser": "^1.20.0", | ||
"dotenv": "^16.0.0", | ||
"express": "^4.18.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
<!doctype html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>Uppy</title> | ||
<link href="https://releases.transloadit.com/uppy/v3.0.1/uppy.min.css" rel="stylesheet"> | ||
</head> | ||
<body> | ||
<section class="example"> | ||
<div id="drag-drop-area"></div> | ||
<div class="for-ProgressBar"></div> | ||
<div class="uploaded-files"> | ||
<h5>Uploaded files:</h5> | ||
<ol></ol> | ||
</div> | ||
<script type="module"> | ||
import {Uppy, DragDrop, ProgressBar, AwsS3 } from "https://releases.transloadit.com/uppy/v3.0.2/uppy.min.mjs" | ||
|
||
// Function for displaying uploaded files | ||
const onUploadSuccess = (elForUploadedFiles) => (file, response) => { | ||
const url = response.uploadURL | ||
const fileName = file.name | ||
|
||
const li = document.createElement('li') | ||
const a = document.createElement('a') | ||
a.href = url | ||
a.target = '_blank' | ||
a.appendChild(document.createTextNode(fileName)) | ||
li.appendChild(a) | ||
|
||
document.querySelector(elForUploadedFiles).appendChild(li) | ||
} | ||
|
||
var uppy = new Uppy({ | ||
autoProceed: true, | ||
restrictions: { | ||
maxNumberOfFiles: 10, | ||
} | ||
}) | ||
.use(DragDrop, { | ||
inline: true, | ||
target: '#drag-drop-area' | ||
}) | ||
.use(ProgressBar, { target: '.example .for-ProgressBar', hideAfterFinish: true }) | ||
.use(AwsS3, { | ||
getUploadParameters (file) { | ||
// Send a request to our PHP signing endpoint. | ||
return fetch('/sign-s3', { | ||
method: 'post', | ||
// Send and receive JSON. | ||
headers: { | ||
accept: 'application/json', | ||
'content-type': 'application/json', | ||
}, | ||
body: JSON.stringify({ | ||
filename: file.name, | ||
contentType: file.type, | ||
}), | ||
}).then((response) => { | ||
// Parse the JSON response. | ||
return response.json() | ||
}).then((data) => { | ||
// Return an object in the correct shape. | ||
return { | ||
method: data.method, | ||
url: data.url, | ||
fields: data.fields, | ||
// Provide content type header required by S3 | ||
headers: { | ||
'Content-Type': file.type, | ||
}, | ||
} | ||
}) | ||
}, | ||
}); | ||
|
||
uppy.on('complete', (result) => { | ||
console.log('Upload complete! We’ve uploaded these files:', result.successful) | ||
}); | ||
|
||
uppy.on('upload-success', onUploadSuccess('.example .uploaded-files ol')); | ||
</script> | ||
</section> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<!doctype html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>Uppy</title> | ||
<link href="https://releases.transloadit.com/uppy/v3.0.1/uppy.min.css" rel="stylesheet"> | ||
</head> | ||
<body> | ||
<div id="drag-drop-area"></div> | ||
<script type="module"> | ||
import { Uppy, Dashboard, AwsS3 } from "https://releases.transloadit.com/uppy/v3.0.2/uppy.min.mjs" | ||
var uppy = new Uppy() | ||
.use(Dashboard, { | ||
inline: true, | ||
target: '#drag-drop-area', | ||
}) | ||
.use(AwsS3, { | ||
getUploadParameters (file) { | ||
// Send a request to our PHP signing endpoint. | ||
return fetch('/sign-s3', { | ||
method: 'post', | ||
// Send and receive JSON. | ||
headers: { | ||
accept: 'application/json', | ||
'content-type': 'application/json', | ||
}, | ||
body: JSON.stringify({ | ||
filename: file.name, | ||
contentType: file.type, | ||
}), | ||
}).then((response) => { | ||
// Parse the JSON response. | ||
return response.json() | ||
}).then((data) => { | ||
// Return an object in the correct shape. | ||
return { | ||
method: data.method, | ||
url: data.url, | ||
fields: data.fields, // For presigned PUT uploads, this should be left empty. | ||
// Provide content type header required by S3 | ||
headers: { | ||
'Content-Type': file.type, | ||
}, | ||
} | ||
}) | ||
}, | ||
}); | ||
|
||
uppy.on('complete', (result) => { | ||
console.log('Upload complete! We’ve uploaded these files:', result.successful) | ||
}) | ||
|
||
uppy.on('upload-success', (file, data) => { | ||
console.log('Upload success! We’ve uploaded this file:', file.meta['name']) | ||
}) | ||
</script> | ||
</body> | ||
</html> |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion
2
examples/aws-presigned-url/package.json → examples/aws-php/package.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.