diff --git a/.changeset/long-bags-itch.md b/.changeset/long-bags-itch.md new file mode 100644 index 00000000000..f7ff2f682d5 --- /dev/null +++ b/.changeset/long-bags-itch.md @@ -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', + } +}); +``` diff --git a/packages/file-adapters/README.md b/packages/file-adapters/README.md index e988f87e31b..c9bb0a130d7 100644 --- a/packages/file-adapters/README.md +++ b/packages/file-adapters/README.md @@ -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: { @@ -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 diff --git a/packages/file-adapters/lib/s3.js b/packages/file-adapters/lib/s3.js index c83a9e006d1..5050fef8073 100644 --- a/packages/file-adapters/lib/s3.js +++ b/packages/file-adapters/lib/s3.js @@ -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) {