UNPKG

@aws-amplify/core

Version:
138 lines (136 loc) 5.47 kB
'use strict'; // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 Object.defineProperty(exports, "__esModule", { value: true }); exports.Signer = void 0; const signatureV4_1 = require("../clients/middleware/signing/signer/signatureV4"); const amplifyUrl_1 = require("../utils/amplifyUrl"); const DateUtils_1 = require("./DateUtils"); const IOT_SERVICE_NAME = 'iotdevicegateway'; // Best practice regex to parse the service and region from an AWS endpoint const AWS_ENDPOINT_REGEX = /([^.]+)\.(?:([^.]*)\.)?amazonaws\.com(.cn)?$/; /** * This class is intended to be deprecated and replaced by `signRequest` and `presignUrl` functions from * `clients/middleware/signing/signer/signatureV4`. * * TODO: refactor the logics here into `signRequest` and `presignUrl` functions and remove this class. * * @internal * @deprecated */ class Signer { /** * Sign a HTTP request, add 'Authorization' header to request param * @method sign * @memberof Signer * @static * * @param {object} request - HTTP request object <pre> request: { method: GET | POST | PUT ... url: ..., headers: { header1: ... }, data: data } </pre> * @param {object} access_info - AWS access credential info <pre> access_info: { access_key: ..., secret_key: ..., session_token: ... } </pre> * @param {object} [service_info] - AWS service type and region, optional, * if not provided then parse out from url <pre> service_info: { service: ..., region: ... } </pre> * * @returns {object} Signed HTTP request */ static sign(request, accessInfo, serviceInfo) { request.headers = request.headers || {}; if (request.body && !request.data) { throw new Error('The attribute "body" was found on the request object. Please use the attribute "data" instead.'); } const requestToSign = { ...request, body: request.data, url: new amplifyUrl_1.AmplifyUrl(request.url), }; const options = getOptions(requestToSign, accessInfo, serviceInfo); const signedRequest = (0, signatureV4_1.signRequest)(requestToSign, options); // Prior to using `signRequest`, Signer accepted urls as strings and outputted urls as string. Coerce the property // back to a string so as not to disrupt consumers of Signer. signedRequest.url = signedRequest.url.toString(); // HTTP headers should be case insensitive but, to maintain parity with the previous Signer implementation and // limit the impact of this implementation swap, replace lowercased headers with title cased ones. signedRequest.headers.Authorization = signedRequest.headers.authorization; signedRequest.headers['X-Amz-Security-Token'] = signedRequest.headers['x-amz-security-token']; delete signedRequest.headers.authorization; delete signedRequest.headers['x-amz-security-token']; return signedRequest; } static signUrl(urlOrRequest, accessInfo, serviceInfo, expiration) { const urlToSign = typeof urlOrRequest === 'object' ? urlOrRequest.url : urlOrRequest; const method = typeof urlOrRequest === 'object' ? urlOrRequest.method : 'GET'; const body = typeof urlOrRequest === 'object' ? urlOrRequest.body : undefined; const presignable = { body, method, url: new amplifyUrl_1.AmplifyUrl(urlToSign), }; const options = getOptions(presignable, accessInfo, serviceInfo, expiration); const signedUrl = (0, signatureV4_1.presignUrl)(presignable, options); if (accessInfo.session_token && !sessionTokenRequiredInSigning(options.signingService)) { signedUrl.searchParams.append(signatureV4_1.TOKEN_QUERY_PARAM, accessInfo.session_token); } return signedUrl.toString(); } } exports.Signer = Signer; const getOptions = (request, accessInfo, serviceInfo, expiration) => { const { access_key, secret_key, session_token } = accessInfo ?? {}; const { region: urlRegion, service: urlService } = parseServiceInfo(request.url); const { region = urlRegion, service = urlService } = serviceInfo ?? {}; const credentials = { accessKeyId: access_key, secretAccessKey: secret_key, ...(sessionTokenRequiredInSigning(service) ? { sessionToken: session_token } : {}), }; return { credentials, signingDate: DateUtils_1.DateUtils.getDateWithClockOffset(), signingRegion: region, signingService: service, ...(expiration && { expiration }), }; }; const parseServiceInfo = (url) => { const { host } = url; const matched = host.match(AWS_ENDPOINT_REGEX) ?? []; let parsed = matched.slice(1, 3); if (parsed[1] === 'es') { // Elastic Search parsed = parsed.reverse(); } return { service: parsed[0], region: parsed[1], }; }; // IoT service does not allow the session token in the canonical request // https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html const sessionTokenRequiredInSigning = (service) => service !== IOT_SERVICE_NAME; //# sourceMappingURL=Signer.js.map