UNPKG

aws-crt

Version:

NodeJS bindings to the aws-c-* libraries

85 lines 4.31 kB
"use strict"; /* Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const WebsocketStream = require("websocket-stream"); const Crypto = __importStar(require("crypto-js")); function zero_pad(n) { return (n > 9) ? n : '0' + n.toString(); } function canonical_time() { const now = new Date(); return `${now.getUTCFullYear()}${zero_pad(now.getUTCMonth() + 1)}${zero_pad(now.getUTCDate())}T` + `${zero_pad(now.getUTCHours())}${zero_pad(now.getUTCMinutes())}${zero_pad(now.getUTCSeconds())}Z`; } function canonical_day(time = canonical_time()) { return time.substring(0, time.indexOf('T')); } function make_signing_key(credentials, day, service_name) { const hash_opts = { asBytes: true }; let hash = Crypto.HmacSHA256(day, 'AWS4' + credentials.aws_secret_key, hash_opts); hash = Crypto.HmacSHA256(credentials.aws_region || '', hash, hash_opts); hash = Crypto.HmacSHA256(service_name, hash, hash_opts); hash = Crypto.HmacSHA256('aws4_request', hash, hash_opts); return hash; } function sign_url(method, url, credentials, service_name, time = canonical_time(), day = canonical_day(time), payload = '') { const signed_headers = 'host'; const canonical_headers = `host:${url.hostname.toLowerCase()}\n`; const payload_hash = Crypto.SHA256(payload, { asBytes: true }); const canonical_params = url.search.replace(new RegExp('^\\?'), ''); const canonical_request = `${method}\n${url.pathname}\n${canonical_params}\n${canonical_headers}\n${signed_headers}\n${payload_hash}`; const canonical_request_hash = Crypto.SHA256(canonical_request, { asBytes: true }); const signature_raw = `AWS4-HMAC-SHA256\n${time}\n${day}/${credentials.aws_region}/${service_name}/aws4_request\n${canonical_request_hash}`; const signing_key = make_signing_key(credentials, day, service_name); const signature = Crypto.HmacSHA256(signature_raw, signing_key, { asBytes: true }); let query_params = `${url.search}&X-Amz-Signature=${signature}`; if (credentials.aws_sts_token) { query_params += `&X-Amz-Security-Token=${encodeURIComponent(credentials.aws_sts_token)}`; } const signed_url = `${url.protocol}${url.hostname}${url.pathname}${query_params}`; return signed_url; } function create_websocket_url(config) { const time = canonical_time(); const day = canonical_day(time); const path = '/mqtt'; const protocol = (config.websocket || {}).protocol || 'wss'; if (protocol === 'wss') { const service_name = 'iotdevicegateway'; const credentials = config.credentials; const query_params = `X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=${credentials.aws_access_id}` + `%2F${day}%2F${credentials.aws_region}%2F${service_name}%2Faws4_request&X-Amz-Date=${time}&X-Amz-SignedHeaders=host`; const url = new URL(`wss://${config.host_name}${path}?${query_params}`); return sign_url('GET', url, credentials, service_name, time, day); } else if (protocol === 'wss-custom-auth') { return `wss://${config.host_name}/${path}`; } throw new URIError(`Invalid protocol requested: ${protocol}`); } exports.create_websocket_url = create_websocket_url; function create_websocket_stream(config) { const url = create_websocket_url(config); return WebsocketStream(url, ['mqttv3.1'], config.websocket); } exports.create_websocket_stream = create_websocket_stream; //# sourceMappingURL=ws.js.map