AWS S3 generate presigned URL as File Operation

The idea is:

Add an option to generate presigned URL for AWS S3 File Operation

My use case:

Need to share the s3 file with someone.

I think it would be beneficial to add this because:

it’s quite a useful option when there is a need to share some files located on the S3 with somebody (I use that method quite a lot to share a 1-day expiration link with users).

Any resources to support this?

Reference: https://community.n8n.io/t/why-am-i-not-able-to-upload-files-to-aws-s3

yes please!

thanks @barn4k

+1
needed too

i try this on Code node but it’s not working:

const crypto = require('crypto');

const accessKeyId = 'YOUR_ACCESS_KEY_ID';
const secretAccessKey = 'YOUR_SECRET_ACCESS_KEY';
const region = 'YOUR_AWS_REGION';
const bucketName = 'YOUR_BUCKET_NAME';
const expiration = 60 * 60;
let outputs = [];

for (const item of $input.all()) {
	
	const objectKey = item.json. YOUR_OBJECT_KEY;
	const date = new Date();
	const amzDate = date.toISOString().replace(/[:-]|\.\d{3}/g, '') + 'Z';
	const dateStamp = date.toISOString().slice(0, 10).replace(/-/g, '');

	const canonicalUri = '/' + objectKey;
	const host = `${bucketName}.s3.${region}.amazonaws.com`;

	const canonicalQuerystring = `X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=${encodeURIComponent(accessKeyId + '/' + dateStamp + '/' + region + '/s3/aws4_request')}&X-Amz-Date=${amzDate}&X-Amz-Expires=${expiration}&X-Amz-SignedHeaders=host`;

	const canonicalHeaders = `host:${host}\n`;
	const signedHeaders = 'host';
	const payloadHash = crypto.createHash('sha256').update('', 'utf8').digest('hex');
	const canonicalRequest = `GET\n${canonicalUri}\n${canonicalQuerystring}\n${canonicalHeaders}\n${signedHeaders}\n${payloadHash}`;

	const algorithm = 'AWS4-HMAC-SHA256';
	const credentialScope = `${dateStamp}/${region}/s3/aws4_request`;
	const stringToSign = `${algorithm}\n${amzDate}\n${credentialScope}\n${crypto.createHash('sha256').update(canonicalRequest, 'utf8').digest('hex')}`;

	const getSignatureKey = (key, dateStamp, regionName, serviceName) => {
		const kDate = crypto.createHmac('sha256', 'AWS4' + key).update(dateStamp).digest();
		const kRegion = crypto.createHmac('sha256', kDate).update(regionName).digest();
		const kService = crypto.createHmac('sha256', kRegion).update(serviceName).digest();
		const kSigning = crypto.createHmac('sha256', kService).update('aws4_request').digest();
		return kSigning;
	};

	const signingKey = getSignatureKey(secretAccessKey, dateStamp, region, 's3');
	const signature = crypto.createHmac('sha256', signingKey).update(stringToSign).digest('hex');

	const signedUrl = `https://${host}${canonicalUri}?${canonicalQuerystring}&X-Amz-Signature=${signature}`;

	const output = {
		json: {
        signedUrl: signedUrl,
		id_request: item.json.id_request,
		file_path: item.json.file_path,
    }};

	outputs.push(output);
}

return outputs;
1 Like

I’m having the same issue.
Nice implementation with crypto library but where did you find the docs about the signature implementation?

on gpt 4 :slight_smile: