UNPKG

@cumulus/aws-client

Version:
101 lines 4.77 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; const url_1 = require("url"); const uuid_1 = require("uuid"); const client_s3_1 = require("@aws-sdk/client-s3"); const s3_request_presigner_1 = require("@aws-sdk/s3-request-presigner"); const logger_1 = __importDefault(require("@cumulus/logger")); const S3_1 = require("./S3"); const client_1 = __importDefault(require("./client")); // Code modified from https://github.com/nasa/harmony/blob/main/app/util/object-store.ts const log = new logger_1.default({ sender: '@cumulus/aws-client/S3ObjectStore' }); const S3_LINK_EXPIRY_SECONDS_DEFAULT = 3600; /** * Class to use when interacting with S3 * */ class S3ObjectStore { constructor(config) { this.s3 = (0, client_1.default)(client_s3_1.S3, '2006-03-01', { signatureVersion: 'v4', })(config); this.queryParams = {}; this.middlewareName = `customQueryParams${(0, uuid_1.v4)()}`; } getQueryParams() { return this.queryParams; } setQueryParams(queryParams) { this.queryParams = queryParams; } async getS3SignedUrlWithCustomQueryParams(command, presignOptions = {}) { this.s3.middlewareStack.addRelativeTo((next) => (args) => { const { request } = args; request.query = { ...this.getQueryParams(), ...request.query, }; return next(args); }, { name: this.middlewareName, relation: 'before', toMiddleware: 'presignInterceptMiddleware', }); const signedUrl = await (0, s3_request_presigner_1.getSignedUrl)(this.s3, command, { expiresIn: S3_LINK_EXPIRY_SECONDS_DEFAULT, ...presignOptions }); this.s3.middlewareStack.remove(this.middlewareName); return signedUrl; } /** * Returns an HTTPS URL that can be used to perform a GET on the given object * store URL * * @param {string} objectUrl - the URL of the object to sign * @param {string} [options] - options to pass to S3.getObject * @param {string} [queryParams] - a mapping of parameter key/values to put in the URL * @param {RequestPresigningArguments} presignOptions - presignOptions * @returns {Promise<string>} a signed URL * @throws TypeError - if the URL is not a recognized protocol or cannot be parsed */ async signGetObject(objectUrl, options = {}, queryParams = {}, presignOptions = {}) { log.info(`Executing signGetObject with objectUrl: ${objectUrl}, options: ${JSON.stringify(options)}, queryParams: ${JSON.stringify(queryParams)}`); const url = new url_1.URL(objectUrl); if (url.protocol.toLowerCase() !== 's3:') { throw new TypeError(`Invalid S3 URL: ${objectUrl}`); } const { Bucket, Key } = (0, S3_1.parseS3Uri)(objectUrl); await (0, S3_1.headObject)(Bucket, Key); const command = new client_s3_1.GetObjectCommand({ Bucket, Key, ...options }); this.setQueryParams(queryParams); const signedUrl = await this.getS3SignedUrlWithCustomQueryParams(command, presignOptions); log.debug(`Signed GetObject request URL: ${signedUrl}`); return signedUrl; } /** * Returns an HTTPS URL that can be used to perform a HEAD on the given object * store URL * * @param {string} objectUrl - the URL of the object to sign * @param {string} [options] - options to pass to S3.getObject * @param {string} [queryParams] - a mapping of parameter key/values to put in the URL * @param {RequestPresigningArguments} presignOptions - presignOptions * @returns {Promise<string>} a signed URL * @throws TypeError - if the URL is not a recognized protocol or cannot be parsed */ async signHeadObject(objectUrl, options = {}, queryParams, presignOptions = {}) { log.info(`Executing signHeadObject with objectUrl: ${objectUrl}, options: ${JSON.stringify(options)}, queryParams: ${JSON.stringify(queryParams)}`); const url = new url_1.URL(objectUrl); if (url.protocol.toLowerCase() !== 's3:') { throw new TypeError(`Invalid S3 URL: ${objectUrl}`); } const { Bucket, Key } = (0, S3_1.parseS3Uri)(objectUrl); const command = new client_s3_1.HeadObjectCommand({ Bucket, Key, ...options }); this.setQueryParams(queryParams); const signedUrl = await this.getS3SignedUrlWithCustomQueryParams(command, presignOptions); log.debug(`Signed HeadObject request URL: ${signedUrl}`); return signedUrl; } } module.exports = S3ObjectStore; //# sourceMappingURL=S3ObjectStore.js.map