Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

file-adapters - Removed unnecessary required fields for S3Adapter #2967

Merged
merged 9 commits into from
May 20, 2020
19 changes: 19 additions & 0 deletions .changeset/long-bags-itch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
'@keystonejs/file-adapters': major
---

Providing an access key, secret access key or region directly to AWS has been deprecated (according to AWS). As such, parameters `accessKeyId`, `secretAccessKey` and `region` are no longer `required` on the S3Adapter's constructor and - if provided this way - are ignored by the S3Adapter. These parameters can however, still be provided via the optional `s3Options` parameter object if required like so:

``` Javascript
const fileAdapter = new S3Adapter({
bucket: 'bucket-name',
// accessKeyId: 'ACCESS_KEY_ID', // No longer required. Ignored if provided here
// secretAccessKey: 'SECRET_ACCESS_KEY', // No longer required. Ignored if provided here
// region: 'us-west-2' // No longer required. Ignored if provided here
s3Options: {
accessKeyId: 'ACCESS_KEY_ID',
secretAccessKey: 'SECRET_ACCESS_KEY',
region: 'us-west-2',
}
});
```
28 changes: 14 additions & 14 deletions packages/file-adapters/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,16 @@ const CF_DISTRIBUTION_ID = 'cloudfront-distribution-id';
const S3_PATH = 'uploads';

const fileAdapter = new S3Adapter({
accessKeyId: 'ACCESS_KEY_ID',
secretAccessKey: 'SECRET_ACCESS_KEY',
region: 'us-west-2',
bucket: 'bucket-name',
folder: S3_PATH,
publicUrl: ({ id, filename, _meta }) =>
`https://${CF_DISTRIBUTION_ID}.cloudfront.net/${S3_PATH}/${filename}`,
s3Options: {
// Optional paramaters to be supplied directly to AWS.S3 constructor
apiVersion: '2006-03-01',
accessKeyId: 'ACCESS_KEY_ID',
secretAccessKey: 'SECRET_ACCESS_KEY',
region: 'us-west-2',
},
uploadParams: ({ filename, id, mimetype, encoding }) => ({
Metadata: {
Expand All @@ -125,17 +126,16 @@ const fileAdapter = new S3Adapter({

### Config

| Option | Type | Default | Description |
| ----------------- | ----------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `accessKeyId` | `String` | Required | AWS access key ID |
| `secretAccessKey` | `String` | Required | AWS secret access key |
| `region` | `String` | Required | AWS region |
| `bucket` | `String` | Required | S3 bucket name |
| `folder` | `String` | Required | Upload folder from root of bucket |
| `getFilename` | `Function` | `null` | Function taking a `{ id, originalFilename }` parameter. Should return a string with the name for the uploaded file on disk. |
| `publicUrl` | `Function` | | By default the publicUrl returns a url for the S3 bucket in the form `https://{bucket}.s3.amazonaws.com/{key}/{filename}`. This will only work if the bucket is configured to allow public access. |
| `s3Options` | `Object` | `undefined` | For available options refer to the [AWS S3 API](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html) |
| `uploadParams` | `Object|Function` | `{}` | A config object or function returning a config object to be passed with each call to S3.upload. For available options refer to the [AWS S3 upload API](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property). |
| Option | Type | Default | Description |
| -------------- | ----------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `bucket` | `String` | Required | S3 bucket name |
| `folder` | `String` | `''` | Upload folder from root of bucket. By default uploads will be sent to the bucket's root folder. |
| `getFilename` | `Function` | `null` | Function taking a `{ id, originalFilename }` parameter. Should return a string with the name for the uploaded file on disk. |
| `publicUrl` | `Function` | | By default the publicUrl returns a url for the S3 bucket in the form `https://{bucket}.s3.amazonaws.com/{key}/{filename}`. This will only work if the bucket is configured to allow public access. |
| `s3Options` | `Object` | `undefined` | For available options refer to the [AWS S3 API](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html) |
| `uploadParams` | `Object|Function` | `{}` | A config object or function returning a config object to be passed with each call to S3.upload. For available options refer to the [AWS S3 upload API](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property). |

> **Note:** Authentication can be done in many different ways. One option is to include valid `accessKeyId` and `secretAccessKey` properties in the `s3Options` parameter. Other methods include setting environment variables. See [Setting Credentials in Node.js](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html) for a complete set of options.

### Methods

Expand Down
23 changes: 4 additions & 19 deletions packages/file-adapters/lib/s3.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,11 @@ const AWS = require('aws-sdk');
const urlJoin = require('url-join');

module.exports = class S3Adapter {
constructor({
accessKeyId,
secretAccessKey,
region,
bucket,
folder,
getFilename,
publicUrl,
s3Options,
uploadParams,
}) {
if (!accessKeyId || !secretAccessKey || !region || !bucket || !folder) {
throw new Error('S3Adapter requires accessKeyId, secretAccessKey, region, bucket, folder.');
constructor({ bucket, getFilename, publicUrl, s3Options, uploadParams, folder = '' }) {
if (!bucket) {
throw new Error('S3Adapter requires a bucket name.');
}
this.s3 = new AWS.S3({
accessKeyId,
secretAccessKey,
region,
...s3Options,
});
this.s3 = new AWS.S3(s3Options);
this.bucket = bucket;
this.folder = folder;
if (getFilename) {
Expand Down