forked from enviPath/enviPy
Current Dev State
This commit is contained in:
6
static/js/ketcher2/node_modules/coveralls/node_modules/assert-plus/AUTHORS
generated
vendored
Normal file
6
static/js/ketcher2/node_modules/coveralls/node_modules/assert-plus/AUTHORS
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
Dave Eddy <dave@daveeddy.com>
|
||||
Fred Kuo <fred.kuo@joyent.com>
|
||||
Lars-Magnus Skog <ralphtheninja@riseup.net>
|
||||
Mark Cavage <mcavage@gmail.com>
|
||||
Patrick Mooney <pmooney@pfmooney.com>
|
||||
Rob Gulewich <robert.gulewich@joyent.com>
|
||||
8
static/js/ketcher2/node_modules/coveralls/node_modules/assert-plus/CHANGES.md
generated
vendored
Normal file
8
static/js/ketcher2/node_modules/coveralls/node_modules/assert-plus/CHANGES.md
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# assert-plus Changelog
|
||||
|
||||
## 0.2.0
|
||||
|
||||
- Fix `assert.object(null)` so it throws
|
||||
- Fix optional/arrayOf exports for non-type-of asserts
|
||||
- Add optiona/arrayOf exports for Stream/Date/Regex/uuid
|
||||
- Add basic unit test coverage
|
||||
155
static/js/ketcher2/node_modules/coveralls/node_modules/assert-plus/README.md
generated
vendored
Normal file
155
static/js/ketcher2/node_modules/coveralls/node_modules/assert-plus/README.md
generated
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
# assert-plus
|
||||
|
||||
This library is a super small wrapper over node's assert module that has two
|
||||
things: (1) the ability to disable assertions with the environment variable
|
||||
NODE\_NDEBUG, and (2) some API wrappers for argument testing. Like
|
||||
`assert.string(myArg, 'myArg')`. As a simple example, most of my code looks
|
||||
like this:
|
||||
|
||||
```javascript
|
||||
var assert = require('assert-plus');
|
||||
|
||||
function fooAccount(options, callback) {
|
||||
assert.object(options, 'options');
|
||||
assert.number(options.id, 'options.id');
|
||||
assert.bool(options.isManager, 'options.isManager');
|
||||
assert.string(options.name, 'options.name');
|
||||
assert.arrayOfString(options.email, 'options.email');
|
||||
assert.func(callback, 'callback');
|
||||
|
||||
// Do stuff
|
||||
callback(null, {});
|
||||
}
|
||||
```
|
||||
|
||||
# API
|
||||
|
||||
All methods that *aren't* part of node's core assert API are simply assumed to
|
||||
take an argument, and then a string 'name' that's not a message; `AssertionError`
|
||||
will be thrown if the assertion fails with a message like:
|
||||
|
||||
AssertionError: foo (string) is required
|
||||
at test (/home/mark/work/foo/foo.js:3:9)
|
||||
at Object.<anonymous> (/home/mark/work/foo/foo.js:15:1)
|
||||
at Module._compile (module.js:446:26)
|
||||
at Object..js (module.js:464:10)
|
||||
at Module.load (module.js:353:31)
|
||||
at Function._load (module.js:311:12)
|
||||
at Array.0 (module.js:484:10)
|
||||
at EventEmitter._tickCallback (node.js:190:38)
|
||||
|
||||
from:
|
||||
|
||||
```javascript
|
||||
function test(foo) {
|
||||
assert.string(foo, 'foo');
|
||||
}
|
||||
```
|
||||
|
||||
There you go. You can check that arrays are of a homogeneous type with `Arrayof$Type`:
|
||||
|
||||
```javascript
|
||||
function test(foo) {
|
||||
assert.arrayOfString(foo, 'foo');
|
||||
}
|
||||
```
|
||||
|
||||
You can assert IFF an argument is not `undefined` (i.e., an optional arg):
|
||||
|
||||
```javascript
|
||||
assert.optionalString(foo, 'foo');
|
||||
```
|
||||
|
||||
Lastly, you can opt-out of assertion checking altogether by setting the
|
||||
environment variable `NODE_NDEBUG=1`. This is pseudo-useful if you have
|
||||
lots of assertions, and don't want to pay `typeof ()` taxes to v8 in
|
||||
production. Be advised: The standard functions re-exported from `assert` are
|
||||
also disabled in assert-plus if NDEBUG is specified. Using them directly from
|
||||
the `assert` module avoids this behavior.
|
||||
|
||||
The complete list of APIs is:
|
||||
|
||||
* assert.array
|
||||
* assert.bool
|
||||
* assert.buffer
|
||||
* assert.func
|
||||
* assert.number
|
||||
* assert.object
|
||||
* assert.string
|
||||
* assert.stream
|
||||
* assert.date
|
||||
* assert.regex
|
||||
* assert.uuid
|
||||
* assert.arrayOfArray
|
||||
* assert.arrayOfBool
|
||||
* assert.arrayOfBuffer
|
||||
* assert.arrayOfFunc
|
||||
* assert.arrayOfNumber
|
||||
* assert.arrayOfObject
|
||||
* assert.arrayOfString
|
||||
* assert.arrayOfStream
|
||||
* assert.arrayOfDate
|
||||
* assert.arrayOfUuid
|
||||
* assert.optionalArray
|
||||
* assert.optionalBool
|
||||
* assert.optionalBuffer
|
||||
* assert.optionalFunc
|
||||
* assert.optionalNumber
|
||||
* assert.optionalObject
|
||||
* assert.optionalString
|
||||
* assert.optionalStream
|
||||
* assert.optionalDate
|
||||
* assert.optionalUuid
|
||||
* assert.optionalArrayOfArray
|
||||
* assert.optionalArrayOfBool
|
||||
* assert.optionalArrayOfBuffer
|
||||
* assert.optionalArrayOfFunc
|
||||
* assert.optionalArrayOfNumber
|
||||
* assert.optionalArrayOfObject
|
||||
* assert.optionalArrayOfString
|
||||
* assert.optionalArrayOfStream
|
||||
* assert.optionalArrayOfDate
|
||||
* assert.optionalArrayOfUuid
|
||||
* assert.AssertionError
|
||||
* assert.fail
|
||||
* assert.ok
|
||||
* assert.equal
|
||||
* assert.notEqual
|
||||
* assert.deepEqual
|
||||
* assert.notDeepEqual
|
||||
* assert.strictEqual
|
||||
* assert.notStrictEqual
|
||||
* assert.throws
|
||||
* assert.doesNotThrow
|
||||
* assert.ifError
|
||||
|
||||
# Installation
|
||||
|
||||
npm install assert-plus
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2012 Mark Cavage
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
## Bugs
|
||||
|
||||
See <https://github.com/mcavage/node-assert-plus/issues>.
|
||||
206
static/js/ketcher2/node_modules/coveralls/node_modules/assert-plus/assert.js
generated
vendored
Normal file
206
static/js/ketcher2/node_modules/coveralls/node_modules/assert-plus/assert.js
generated
vendored
Normal file
@ -0,0 +1,206 @@
|
||||
// Copyright (c) 2012, Mark Cavage. All rights reserved.
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
var assert = require('assert');
|
||||
var Stream = require('stream').Stream;
|
||||
var util = require('util');
|
||||
|
||||
|
||||
///--- Globals
|
||||
|
||||
/* JSSTYLED */
|
||||
var UUID_REGEXP = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/;
|
||||
|
||||
|
||||
///--- Internal
|
||||
|
||||
function _capitalize(str) {
|
||||
return (str.charAt(0).toUpperCase() + str.slice(1));
|
||||
}
|
||||
|
||||
function _toss(name, expected, oper, arg, actual) {
|
||||
throw new assert.AssertionError({
|
||||
message: util.format('%s (%s) is required', name, expected),
|
||||
actual: (actual === undefined) ? typeof (arg) : actual(arg),
|
||||
expected: expected,
|
||||
operator: oper || '===',
|
||||
stackStartFunction: _toss.caller
|
||||
});
|
||||
}
|
||||
|
||||
function _getClass(arg) {
|
||||
return (Object.prototype.toString.call(arg).slice(8, -1));
|
||||
}
|
||||
|
||||
function noop() {
|
||||
// Why even bother with asserts?
|
||||
}
|
||||
|
||||
|
||||
///--- Exports
|
||||
|
||||
var types = {
|
||||
bool: {
|
||||
check: function (arg) { return typeof (arg) === 'boolean'; }
|
||||
},
|
||||
func: {
|
||||
check: function (arg) { return typeof (arg) === 'function'; }
|
||||
},
|
||||
string: {
|
||||
check: function (arg) { return typeof (arg) === 'string'; }
|
||||
},
|
||||
object: {
|
||||
check: function (arg) {
|
||||
return typeof (arg) === 'object' && arg !== null;
|
||||
}
|
||||
},
|
||||
number: {
|
||||
check: function (arg) {
|
||||
return typeof (arg) === 'number' && !isNaN(arg) && isFinite(arg);
|
||||
}
|
||||
},
|
||||
buffer: {
|
||||
check: function (arg) { return Buffer.isBuffer(arg); },
|
||||
operator: 'Buffer.isBuffer'
|
||||
},
|
||||
array: {
|
||||
check: function (arg) { return Array.isArray(arg); },
|
||||
operator: 'Array.isArray'
|
||||
},
|
||||
stream: {
|
||||
check: function (arg) { return arg instanceof Stream; },
|
||||
operator: 'instanceof',
|
||||
actual: _getClass
|
||||
},
|
||||
date: {
|
||||
check: function (arg) { return arg instanceof Date; },
|
||||
operator: 'instanceof',
|
||||
actual: _getClass
|
||||
},
|
||||
regexp: {
|
||||
check: function (arg) { return arg instanceof RegExp; },
|
||||
operator: 'instanceof',
|
||||
actual: _getClass
|
||||
},
|
||||
uuid: {
|
||||
check: function (arg) {
|
||||
return typeof (arg) === 'string' && UUID_REGEXP.test(arg);
|
||||
},
|
||||
operator: 'isUUID'
|
||||
}
|
||||
};
|
||||
|
||||
function _setExports(ndebug) {
|
||||
var keys = Object.keys(types);
|
||||
var out;
|
||||
|
||||
/* re-export standard assert */
|
||||
if (process.env.NODE_NDEBUG) {
|
||||
out = noop;
|
||||
} else {
|
||||
out = function (arg, msg) {
|
||||
if (!arg) {
|
||||
_toss(msg, 'true', arg);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/* standard checks */
|
||||
keys.forEach(function (k) {
|
||||
if (ndebug) {
|
||||
out[k] = noop;
|
||||
return;
|
||||
}
|
||||
var type = types[k];
|
||||
out[k] = function (arg, msg) {
|
||||
if (!type.check(arg)) {
|
||||
_toss(msg, k, type.operator, arg, type.actual);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/* optional checks */
|
||||
keys.forEach(function (k) {
|
||||
var name = 'optional' + _capitalize(k);
|
||||
if (ndebug) {
|
||||
out[name] = noop;
|
||||
return;
|
||||
}
|
||||
var type = types[k];
|
||||
out[name] = function (arg, msg) {
|
||||
if (arg === undefined || arg === null) {
|
||||
return;
|
||||
}
|
||||
if (!type.check(arg)) {
|
||||
_toss(msg, k, type.operator, arg, type.actual);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/* arrayOf checks */
|
||||
keys.forEach(function (k) {
|
||||
var name = 'arrayOf' + _capitalize(k);
|
||||
if (ndebug) {
|
||||
out[name] = noop;
|
||||
return;
|
||||
}
|
||||
var type = types[k];
|
||||
var expected = '[' + k + ']';
|
||||
out[name] = function (arg, msg) {
|
||||
if (!Array.isArray(arg)) {
|
||||
_toss(msg, expected, type.operator, arg, type.actual);
|
||||
}
|
||||
var i;
|
||||
for (i = 0; i < arg.length; i++) {
|
||||
if (!type.check(arg[i])) {
|
||||
_toss(msg, expected, type.operator, arg, type.actual);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/* optionalArrayOf checks */
|
||||
keys.forEach(function (k) {
|
||||
var name = 'optionalArrayOf' + _capitalize(k);
|
||||
if (ndebug) {
|
||||
out[name] = noop;
|
||||
return;
|
||||
}
|
||||
var type = types[k];
|
||||
var expected = '[' + k + ']';
|
||||
out[name] = function (arg, msg) {
|
||||
if (arg === undefined || arg === null) {
|
||||
return;
|
||||
}
|
||||
if (!Array.isArray(arg)) {
|
||||
_toss(msg, expected, type.operator, arg, type.actual);
|
||||
}
|
||||
var i;
|
||||
for (i = 0; i < arg.length; i++) {
|
||||
if (!type.check(arg[i])) {
|
||||
_toss(msg, expected, type.operator, arg, type.actual);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/* re-export built-in assertions */
|
||||
Object.keys(assert).forEach(function (k) {
|
||||
if (k === 'AssertionError') {
|
||||
out[k] = assert[k];
|
||||
return;
|
||||
}
|
||||
if (ndebug) {
|
||||
out[k] = noop;
|
||||
return;
|
||||
}
|
||||
out[k] = assert[k];
|
||||
});
|
||||
|
||||
/* export ourselves (for unit tests _only_) */
|
||||
out._setExports = _setExports;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
module.exports = _setExports(process.env.NODE_NDEBUG);
|
||||
82
static/js/ketcher2/node_modules/coveralls/node_modules/assert-plus/package.json
generated
vendored
Normal file
82
static/js/ketcher2/node_modules/coveralls/node_modules/assert-plus/package.json
generated
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
{
|
||||
"_from": "assert-plus@^0.2.0",
|
||||
"_id": "assert-plus@0.2.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
|
||||
"_location": "/coveralls/assert-plus",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "assert-plus@^0.2.0",
|
||||
"name": "assert-plus",
|
||||
"escapedName": "assert-plus",
|
||||
"rawSpec": "^0.2.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^0.2.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/coveralls/http-signature"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
|
||||
"_shasum": "d74e1b87e7affc0db8aadb7021f3fe48101ab234",
|
||||
"_spec": "assert-plus@^0.2.0",
|
||||
"_where": "/home/manfred/enviPath/ketcher2/ketcher/node_modules/coveralls/node_modules/http-signature",
|
||||
"author": {
|
||||
"name": "Mark Cavage",
|
||||
"email": "mcavage@gmail.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/mcavage/node-assert-plus/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Dave Eddy",
|
||||
"email": "dave@daveeddy.com"
|
||||
},
|
||||
{
|
||||
"name": "Fred Kuo",
|
||||
"email": "fred.kuo@joyent.com"
|
||||
},
|
||||
{
|
||||
"name": "Lars-Magnus Skog",
|
||||
"email": "ralphtheninja@riseup.net"
|
||||
},
|
||||
{
|
||||
"name": "Mark Cavage",
|
||||
"email": "mcavage@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Patrick Mooney",
|
||||
"email": "pmooney@pfmooney.com"
|
||||
},
|
||||
{
|
||||
"name": "Rob Gulewich",
|
||||
"email": "robert.gulewich@joyent.com"
|
||||
}
|
||||
],
|
||||
"dependencies": {},
|
||||
"deprecated": false,
|
||||
"description": "Extra assertions on top of node's assert module",
|
||||
"devDependencies": {
|
||||
"faucet": "0.0.1",
|
||||
"tape": "4.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
},
|
||||
"homepage": "https://github.com/mcavage/node-assert-plus#readme",
|
||||
"license": "MIT",
|
||||
"main": "./assert.js",
|
||||
"name": "assert-plus",
|
||||
"optionalDependencies": {},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/mcavage/node-assert-plus.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape tests/*.js | ./node_modules/.bin/faucet"
|
||||
},
|
||||
"version": "0.2.0"
|
||||
}
|
||||
55
static/js/ketcher2/node_modules/coveralls/node_modules/aws-sign2/LICENSE
generated
vendored
Normal file
55
static/js/ketcher2/node_modules/coveralls/node_modules/aws-sign2/LICENSE
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
Apache License
|
||||
|
||||
Version 2.0, January 2004
|
||||
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||
|
||||
You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||
|
||||
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
||||
|
||||
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
4
static/js/ketcher2/node_modules/coveralls/node_modules/aws-sign2/README.md
generated
vendored
Normal file
4
static/js/ketcher2/node_modules/coveralls/node_modules/aws-sign2/README.md
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
aws-sign
|
||||
========
|
||||
|
||||
AWS signing. Originally pulled from LearnBoost/knox, maintained as vendor in request, now a standalone module.
|
||||
212
static/js/ketcher2/node_modules/coveralls/node_modules/aws-sign2/index.js
generated
vendored
Normal file
212
static/js/ketcher2/node_modules/coveralls/node_modules/aws-sign2/index.js
generated
vendored
Normal file
@ -0,0 +1,212 @@
|
||||
|
||||
/*!
|
||||
* Copyright 2010 LearnBoost <dev@learnboost.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var crypto = require('crypto')
|
||||
, parse = require('url').parse
|
||||
;
|
||||
|
||||
/**
|
||||
* Valid keys.
|
||||
*/
|
||||
|
||||
var keys =
|
||||
[ 'acl'
|
||||
, 'location'
|
||||
, 'logging'
|
||||
, 'notification'
|
||||
, 'partNumber'
|
||||
, 'policy'
|
||||
, 'requestPayment'
|
||||
, 'torrent'
|
||||
, 'uploadId'
|
||||
, 'uploads'
|
||||
, 'versionId'
|
||||
, 'versioning'
|
||||
, 'versions'
|
||||
, 'website'
|
||||
]
|
||||
|
||||
/**
|
||||
* Return an "Authorization" header value with the given `options`
|
||||
* in the form of "AWS <key>:<signature>"
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function authorization (options) {
|
||||
return 'AWS ' + options.key + ':' + sign(options)
|
||||
}
|
||||
|
||||
module.exports = authorization
|
||||
module.exports.authorization = authorization
|
||||
|
||||
/**
|
||||
* Simple HMAC-SHA1 Wrapper
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function hmacSha1 (options) {
|
||||
return crypto.createHmac('sha1', options.secret).update(options.message).digest('base64')
|
||||
}
|
||||
|
||||
module.exports.hmacSha1 = hmacSha1
|
||||
|
||||
/**
|
||||
* Create a base64 sha1 HMAC for `options`.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function sign (options) {
|
||||
options.message = stringToSign(options)
|
||||
return hmacSha1(options)
|
||||
}
|
||||
module.exports.sign = sign
|
||||
|
||||
/**
|
||||
* Create a base64 sha1 HMAC for `options`.
|
||||
*
|
||||
* Specifically to be used with S3 presigned URLs
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function signQuery (options) {
|
||||
options.message = queryStringToSign(options)
|
||||
return hmacSha1(options)
|
||||
}
|
||||
module.exports.signQuery= signQuery
|
||||
|
||||
/**
|
||||
* Return a string for sign() with the given `options`.
|
||||
*
|
||||
* Spec:
|
||||
*
|
||||
* <verb>\n
|
||||
* <md5>\n
|
||||
* <content-type>\n
|
||||
* <date>\n
|
||||
* [headers\n]
|
||||
* <resource>
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function stringToSign (options) {
|
||||
var headers = options.amazonHeaders || ''
|
||||
if (headers) headers += '\n'
|
||||
var r =
|
||||
[ options.verb
|
||||
, options.md5
|
||||
, options.contentType
|
||||
, options.date ? options.date.toUTCString() : ''
|
||||
, headers + options.resource
|
||||
]
|
||||
return r.join('\n')
|
||||
}
|
||||
module.exports.queryStringToSign = stringToSign
|
||||
|
||||
/**
|
||||
* Return a string for sign() with the given `options`, but is meant exclusively
|
||||
* for S3 presigned URLs
|
||||
*
|
||||
* Spec:
|
||||
*
|
||||
* <date>\n
|
||||
* <resource>
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function queryStringToSign (options){
|
||||
return 'GET\n\n\n' + options.date + '\n' + options.resource
|
||||
}
|
||||
module.exports.queryStringToSign = queryStringToSign
|
||||
|
||||
/**
|
||||
* Perform the following:
|
||||
*
|
||||
* - ignore non-amazon headers
|
||||
* - lowercase fields
|
||||
* - sort lexicographically
|
||||
* - trim whitespace between ":"
|
||||
* - join with newline
|
||||
*
|
||||
* @param {Object} headers
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function canonicalizeHeaders (headers) {
|
||||
var buf = []
|
||||
, fields = Object.keys(headers)
|
||||
;
|
||||
for (var i = 0, len = fields.length; i < len; ++i) {
|
||||
var field = fields[i]
|
||||
, val = headers[field]
|
||||
, field = field.toLowerCase()
|
||||
;
|
||||
if (0 !== field.indexOf('x-amz')) continue
|
||||
buf.push(field + ':' + val)
|
||||
}
|
||||
return buf.sort().join('\n')
|
||||
}
|
||||
module.exports.canonicalizeHeaders = canonicalizeHeaders
|
||||
|
||||
/**
|
||||
* Perform the following:
|
||||
*
|
||||
* - ignore non sub-resources
|
||||
* - sort lexicographically
|
||||
*
|
||||
* @param {String} resource
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function canonicalizeResource (resource) {
|
||||
var url = parse(resource, true)
|
||||
, path = url.pathname
|
||||
, buf = []
|
||||
;
|
||||
|
||||
Object.keys(url.query).forEach(function(key){
|
||||
if (!~keys.indexOf(key)) return
|
||||
var val = '' == url.query[key] ? '' : '=' + encodeURIComponent(url.query[key])
|
||||
buf.push(key + val)
|
||||
})
|
||||
|
||||
return path + (buf.length ? '?' + buf.sort().join('&') : '')
|
||||
}
|
||||
module.exports.canonicalizeResource = canonicalizeResource
|
||||
50
static/js/ketcher2/node_modules/coveralls/node_modules/aws-sign2/package.json
generated
vendored
Normal file
50
static/js/ketcher2/node_modules/coveralls/node_modules/aws-sign2/package.json
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
{
|
||||
"_from": "aws-sign2@~0.6.0",
|
||||
"_id": "aws-sign2@0.6.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
|
||||
"_location": "/coveralls/aws-sign2",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "aws-sign2@~0.6.0",
|
||||
"name": "aws-sign2",
|
||||
"escapedName": "aws-sign2",
|
||||
"rawSpec": "~0.6.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "~0.6.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/coveralls/request"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
|
||||
"_shasum": "14342dd38dbcc94d0e5b87d763cd63612c0e794f",
|
||||
"_spec": "aws-sign2@~0.6.0",
|
||||
"_where": "/home/manfred/enviPath/ketcher2/ketcher/node_modules/coveralls/node_modules/request",
|
||||
"author": {
|
||||
"name": "Mikeal Rogers",
|
||||
"email": "mikeal.rogers@gmail.com",
|
||||
"url": "http://www.futurealoof.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/mikeal/aws-sign/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {},
|
||||
"deprecated": false,
|
||||
"description": "AWS signing. Originally pulled from LearnBoost/knox, maintained as vendor in request, now a standalone module.",
|
||||
"devDependencies": {},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"homepage": "https://github.com/mikeal/aws-sign#readme",
|
||||
"license": "Apache-2.0",
|
||||
"main": "index.js",
|
||||
"name": "aws-sign2",
|
||||
"optionalDependencies": {},
|
||||
"repository": {
|
||||
"url": "git+https://github.com/mikeal/aws-sign.git"
|
||||
},
|
||||
"version": "0.6.0"
|
||||
}
|
||||
1
static/js/ketcher2/node_modules/coveralls/node_modules/boom/CONTRIBUTING.md
generated
vendored
Normal file
1
static/js/ketcher2/node_modules/coveralls/node_modules/boom/CONTRIBUTING.md
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
Please view our [hapijs contributing guide](https://github.com/hapijs/hapi/blob/master/CONTRIBUTING.md).
|
||||
28
static/js/ketcher2/node_modules/coveralls/node_modules/boom/LICENSE
generated
vendored
Executable file
28
static/js/ketcher2/node_modules/coveralls/node_modules/boom/LICENSE
generated
vendored
Executable file
@ -0,0 +1,28 @@
|
||||
Copyright (c) 2012-2014, Walmart and other contributors.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* The names of any contributors may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
* * *
|
||||
|
||||
The complete list of contributors can be found at: https://github.com/hapijs/boom/graphs/contributors
|
||||
652
static/js/ketcher2/node_modules/coveralls/node_modules/boom/README.md
generated
vendored
Executable file
652
static/js/ketcher2/node_modules/coveralls/node_modules/boom/README.md
generated
vendored
Executable file
@ -0,0 +1,652 @@
|
||||

|
||||
|
||||
HTTP-friendly error objects
|
||||
|
||||
[](http://travis-ci.org/hapijs/boom)
|
||||
[](https://www.npmjs.com/package/boom)
|
||||
|
||||
Lead Maintainer: [Adam Bretz](https://github.com/arb)
|
||||
|
||||
**boom** provides a set of utilities for returning HTTP errors. Each utility returns a `Boom` error response
|
||||
object (instance of `Error`) which includes the following properties:
|
||||
- `isBoom` - if `true`, indicates this is a `Boom` object instance.
|
||||
- `isServer` - convenience bool indicating status code >= 500.
|
||||
- `message` - the error message.
|
||||
- `output` - the formatted response. Can be directly manipulated after object construction to return a custom
|
||||
error response. Allowed root keys:
|
||||
- `statusCode` - the HTTP status code (typically 4xx or 5xx).
|
||||
- `headers` - an object containing any HTTP headers where each key is a header name and value is the header content.
|
||||
- `payload` - the formatted object used as the response payload (stringified). Can be directly manipulated but any
|
||||
changes will be lost
|
||||
if `reformat()` is called. Any content allowed and by default includes the following content:
|
||||
- `statusCode` - the HTTP status code, derived from `error.output.statusCode`.
|
||||
- `error` - the HTTP status message (e.g. 'Bad Request', 'Internal Server Error') derived from `statusCode`.
|
||||
- `message` - the error message derived from `error.message`.
|
||||
- inherited `Error` properties.
|
||||
|
||||
The `Boom` object also supports the following method:
|
||||
- `reformat()` - rebuilds `error.output` using the other object properties.
|
||||
|
||||
## Overview
|
||||
|
||||
- Helper methods
|
||||
- [`wrap(error, [statusCode], [message])`](#wraperror-statuscode-message)
|
||||
- [`create(statusCode, [message], [data])`](#createstatuscode-message-data)
|
||||
- HTTP 4xx Errors
|
||||
- 400: [`Boom.badRequest([message], [data])`](#boombadrequestmessage-data)
|
||||
- 401: [`Boom.unauthorized([message], [scheme], [attributes])`](#boomunauthorizedmessage-scheme-attributes)
|
||||
- 403: [`Boom.forbidden([message], [data])`](#boomforbiddenmessage-data)
|
||||
- 404: [`Boom.notFound([message], [data])`](#boomnotfoundmessage-data)
|
||||
- 405: [`Boom.methodNotAllowed([message], [data])`](#boommethodnotallowedmessage-data)
|
||||
- 406: [`Boom.notAcceptable([message], [data])`](#boomnotacceptablemessage-data)
|
||||
- 407: [`Boom.proxyAuthRequired([message], [data])`](#boomproxyauthrequiredmessage-data)
|
||||
- 408: [`Boom.clientTimeout([message], [data])`](#boomclienttimeoutmessage-data)
|
||||
- 409: [`Boom.conflict([message], [data])`](#boomconflictmessage-data)
|
||||
- 410: [`Boom.resourceGone([message], [data])`](#boomresourcegonemessage-data)
|
||||
- 411: [`Boom.lengthRequired([message], [data])`](#boomlengthrequiredmessage-data)
|
||||
- 412: [`Boom.preconditionFailed([message], [data])`](#boompreconditionfailedmessage-data)
|
||||
- 413: [`Boom.entityTooLarge([message], [data])`](#boomentitytoolargemessage-data)
|
||||
- 414: [`Boom.uriTooLong([message], [data])`](#boomuritoolongmessage-data)
|
||||
- 415: [`Boom.unsupportedMediaType([message], [data])`](#boomunsupportedmediatypemessage-data)
|
||||
- 416: [`Boom.rangeNotSatisfiable([message], [data])`](#boomrangenotsatisfiablemessage-data)
|
||||
- 417: [`Boom.expectationFailed([message], [data])`](#boomexpectationfailedmessage-data)
|
||||
- 422: [`Boom.badData([message], [data])`](#boombaddatamessage-data)
|
||||
- 428: [`Boom.preconditionRequired([message], [data])`](#boompreconditionrequiredmessage-data)
|
||||
- 429: [`Boom.tooManyRequests([message], [data])`](#boomtoomanyrequestsmessage-data)
|
||||
- HTTP 5xx Errors
|
||||
- 500: [`Boom.badImplementation([message], [data])`](#boombadimplementationmessage-data)
|
||||
- 501: [`Boom.notImplemented([message], [data])`](#boomnotimplementedmessage-data)
|
||||
- 502: [`Boom.badGateway([message], [data])`](#boombadgatewaymessage-data)
|
||||
- 503: [`Boom.serverTimeout([message], [data])`](#boomservertimeoutmessage-data)
|
||||
- 504: [`Boom.gatewayTimeout([message], [data])`](#boomgatewaytimeoutmessage-data)
|
||||
- [FAQ](#faq)
|
||||
|
||||
|
||||
## Helper Methods
|
||||
|
||||
### `wrap(error, [statusCode], [message])`
|
||||
|
||||
Decorates an error with the **boom** properties where:
|
||||
- `error` - the error object to wrap. If `error` is already a **boom** object, returns back the same object.
|
||||
- `statusCode` - optional HTTP status code. Defaults to `500`.
|
||||
- `message` - optional message string. If the error already has a message, it adds the message as a prefix.
|
||||
Defaults to no message.
|
||||
|
||||
```js
|
||||
var error = new Error('Unexpected input');
|
||||
Boom.wrap(error, 400);
|
||||
```
|
||||
|
||||
### `create(statusCode, [message], [data])`
|
||||
|
||||
Generates an `Error` object with the **boom** decorations where:
|
||||
- `statusCode` - an HTTP error code number. Must be greater or equal 400.
|
||||
- `message` - optional message string.
|
||||
- `data` - additional error data set to `error.data` property.
|
||||
|
||||
```js
|
||||
var error = Boom.create(400, 'Bad request', { timestamp: Date.now() });
|
||||
```
|
||||
|
||||
## HTTP 4xx Errors
|
||||
|
||||
### `Boom.badRequest([message], [data])`
|
||||
|
||||
Returns a 400 Bad Request error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.badRequest('invalid query');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 400,
|
||||
"error": "Bad Request",
|
||||
"message": "invalid query"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.unauthorized([message], [scheme], [attributes])`
|
||||
|
||||
Returns a 401 Unauthorized error where:
|
||||
- `message` - optional message.
|
||||
- `scheme` can be one of the following:
|
||||
- an authentication scheme name
|
||||
- an array of string values. These values will be separated by ', ' and set to the 'WWW-Authenticate' header.
|
||||
- `attributes` - an object of values to use while setting the 'WWW-Authenticate' header. This value is only used
|
||||
when `schema` is a string, otherwise it is ignored. Every key/value pair will be included in the
|
||||
'WWW-Authenticate' in the format of 'key="value"' as well as in the response payload under the `attributes` key.
|
||||
`null` and `undefined` will be replaced with an empty string. If `attributes` is set, `message` will be used as
|
||||
the 'error' segment of the 'WWW-Authenticate' header. If `message` is unset, the 'error' segment of the header
|
||||
will not be present and `isMissing` will be true on the error object.
|
||||
|
||||
If either `scheme` or `attributes` are set, the resultant `Boom` object will have the 'WWW-Authenticate' header set for the response.
|
||||
|
||||
```js
|
||||
Boom.unauthorized('invalid password');
|
||||
```
|
||||
|
||||
Generates the following response:
|
||||
|
||||
```json
|
||||
"payload": {
|
||||
"statusCode": 401,
|
||||
"error": "Unauthorized",
|
||||
"message": "invalid password"
|
||||
},
|
||||
"headers" {}
|
||||
```
|
||||
|
||||
```js
|
||||
Boom.unauthorized('invalid password', 'sample');
|
||||
```
|
||||
|
||||
Generates the following response:
|
||||
|
||||
```json
|
||||
"payload": {
|
||||
"statusCode": 401,
|
||||
"error": "Unauthorized",
|
||||
"message": "invalid password",
|
||||
"attributes": {
|
||||
"error": "invalid password"
|
||||
}
|
||||
},
|
||||
"headers" {
|
||||
"WWW-Authenticate": "sample error=\"invalid password\""
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
Boom.unauthorized('invalid password', 'sample', { ttl: 0, cache: null, foo: 'bar' });
|
||||
```
|
||||
|
||||
Generates the following response:
|
||||
|
||||
```json
|
||||
"payload": {
|
||||
"statusCode": 401,
|
||||
"error": "Unauthorized",
|
||||
"message": "invalid password",
|
||||
"attributes": {
|
||||
"error": "invalid password",
|
||||
"ttl": 0,
|
||||
"cache": "",
|
||||
"foo": "bar"
|
||||
}
|
||||
},
|
||||
"headers" {
|
||||
"WWW-Authenticate": "sample ttl=\"0\", cache=\"\", foo=\"bar\", error=\"invalid password\""
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.forbidden([message], [data])`
|
||||
|
||||
Returns a 403 Forbidden error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.forbidden('try again some time');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 403,
|
||||
"error": "Forbidden",
|
||||
"message": "try again some time"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.notFound([message], [data])`
|
||||
|
||||
Returns a 404 Not Found error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.notFound('missing');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 404,
|
||||
"error": "Not Found",
|
||||
"message": "missing"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.methodNotAllowed([message], [data])`
|
||||
|
||||
Returns a 405 Method Not Allowed error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.methodNotAllowed('that method is not allowed');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 405,
|
||||
"error": "Method Not Allowed",
|
||||
"message": "that method is not allowed"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.notAcceptable([message], [data])`
|
||||
|
||||
Returns a 406 Not Acceptable error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.notAcceptable('unacceptable');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 406,
|
||||
"error": "Not Acceptable",
|
||||
"message": "unacceptable"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.proxyAuthRequired([message], [data])`
|
||||
|
||||
Returns a 407 Proxy Authentication Required error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.proxyAuthRequired('auth missing');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 407,
|
||||
"error": "Proxy Authentication Required",
|
||||
"message": "auth missing"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.clientTimeout([message], [data])`
|
||||
|
||||
Returns a 408 Request Time-out error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.clientTimeout('timed out');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 408,
|
||||
"error": "Request Time-out",
|
||||
"message": "timed out"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.conflict([message], [data])`
|
||||
|
||||
Returns a 409 Conflict error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.conflict('there was a conflict');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 409,
|
||||
"error": "Conflict",
|
||||
"message": "there was a conflict"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.resourceGone([message], [data])`
|
||||
|
||||
Returns a 410 Gone error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.resourceGone('it is gone');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 410,
|
||||
"error": "Gone",
|
||||
"message": "it is gone"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.lengthRequired([message], [data])`
|
||||
|
||||
Returns a 411 Length Required error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.lengthRequired('length needed');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 411,
|
||||
"error": "Length Required",
|
||||
"message": "length needed"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.preconditionFailed([message], [data])`
|
||||
|
||||
Returns a 412 Precondition Failed error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.preconditionFailed();
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 412,
|
||||
"error": "Precondition Failed"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.entityTooLarge([message], [data])`
|
||||
|
||||
Returns a 413 Request Entity Too Large error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.entityTooLarge('too big');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 413,
|
||||
"error": "Request Entity Too Large",
|
||||
"message": "too big"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.uriTooLong([message], [data])`
|
||||
|
||||
Returns a 414 Request-URI Too Large error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.uriTooLong('uri is too long');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 414,
|
||||
"error": "Request-URI Too Large",
|
||||
"message": "uri is too long"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.unsupportedMediaType([message], [data])`
|
||||
|
||||
Returns a 415 Unsupported Media Type error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.unsupportedMediaType('that media is not supported');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 415,
|
||||
"error": "Unsupported Media Type",
|
||||
"message": "that media is not supported"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.rangeNotSatisfiable([message], [data])`
|
||||
|
||||
Returns a 416 Requested Range Not Satisfiable error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.rangeNotSatisfiable();
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 416,
|
||||
"error": "Requested Range Not Satisfiable"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.expectationFailed([message], [data])`
|
||||
|
||||
Returns a 417 Expectation Failed error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.expectationFailed('expected this to work');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 417,
|
||||
"error": "Expectation Failed",
|
||||
"message": "expected this to work"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.badData([message], [data])`
|
||||
|
||||
Returns a 422 Unprocessable Entity error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.badData('your data is bad and you should feel bad');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 422,
|
||||
"error": "Unprocessable Entity",
|
||||
"message": "your data is bad and you should feel bad"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.preconditionRequired([message], [data])`
|
||||
|
||||
Returns a 428 Precondition Required error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.preconditionRequired('you must supply an If-Match header');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 428,
|
||||
"error": "Precondition Required",
|
||||
"message": "you must supply an If-Match header"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.tooManyRequests([message], [data])`
|
||||
|
||||
Returns a 429 Too Many Requests error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.tooManyRequests('you have exceeded your request limit');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 429,
|
||||
"error": "Too Many Requests",
|
||||
"message": "you have exceeded your request limit"
|
||||
}
|
||||
```
|
||||
|
||||
## HTTP 5xx Errors
|
||||
|
||||
All 500 errors hide your message from the end user. Your message is recorded in the server log.
|
||||
|
||||
### `Boom.badImplementation([message], [data])`
|
||||
|
||||
Returns a 500 Internal Server Error error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.badImplementation('terrible implementation');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 500,
|
||||
"error": "Internal Server Error",
|
||||
"message": "An internal server error occurred"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.notImplemented([message], [data])`
|
||||
|
||||
Returns a 501 Not Implemented error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.notImplemented('method not implemented');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 501,
|
||||
"error": "Not Implemented",
|
||||
"message": "method not implemented"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.badGateway([message], [data])`
|
||||
|
||||
Returns a 502 Bad Gateway error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.badGateway('that is a bad gateway');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 502,
|
||||
"error": "Bad Gateway",
|
||||
"message": "that is a bad gateway"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.serverTimeout([message], [data])`
|
||||
|
||||
Returns a 503 Service Unavailable error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.serverTimeout('unavailable');
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 503,
|
||||
"error": "Service Unavailable",
|
||||
"message": "unavailable"
|
||||
}
|
||||
```
|
||||
|
||||
### `Boom.gatewayTimeout([message], [data])`
|
||||
|
||||
Returns a 504 Gateway Time-out error where:
|
||||
- `message` - optional message.
|
||||
- `data` - optional additional error data.
|
||||
|
||||
```js
|
||||
Boom.gatewayTimeout();
|
||||
```
|
||||
|
||||
Generates the following response payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"statusCode": 504,
|
||||
"error": "Gateway Time-out"
|
||||
}
|
||||
```
|
||||
|
||||
## F.A.Q.
|
||||
|
||||
###### How do I include extra information in my responses? `output.payload` is missing `data`, what gives?
|
||||
|
||||
There is a reason the values passed back in the response payloads are pretty locked down. It's mostly for security and to not leak any important information back to the client. This means you will need to put in a little more effort to include extra information about your custom error. Check out the ["Error transformation"](https://github.com/hapijs/hapi/blob/master/API.md#error-transformation) section in the hapi documentation.
|
||||
BIN
static/js/ketcher2/node_modules/coveralls/node_modules/boom/images/boom.png
generated
vendored
Executable file
BIN
static/js/ketcher2/node_modules/coveralls/node_modules/boom/images/boom.png
generated
vendored
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
318
static/js/ketcher2/node_modules/coveralls/node_modules/boom/lib/index.js
generated
vendored
Executable file
318
static/js/ketcher2/node_modules/coveralls/node_modules/boom/lib/index.js
generated
vendored
Executable file
@ -0,0 +1,318 @@
|
||||
// Load modules
|
||||
|
||||
var Http = require('http');
|
||||
var Hoek = require('hoek');
|
||||
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
exports.wrap = function (error, statusCode, message) {
|
||||
|
||||
Hoek.assert(error instanceof Error, 'Cannot wrap non-Error object');
|
||||
return (error.isBoom ? error : internals.initialize(error, statusCode || 500, message));
|
||||
};
|
||||
|
||||
|
||||
exports.create = function (statusCode, message, data) {
|
||||
|
||||
return internals.create(statusCode, message, data, exports.create);
|
||||
};
|
||||
|
||||
internals.create = function (statusCode, message, data, ctor) {
|
||||
|
||||
var error = new Error(message ? message : undefined); // Avoids settings null message
|
||||
Error.captureStackTrace(error, ctor); // Filter the stack to our external API
|
||||
error.data = data || null;
|
||||
internals.initialize(error, statusCode);
|
||||
return error;
|
||||
};
|
||||
|
||||
internals.initialize = function (error, statusCode, message) {
|
||||
|
||||
var numberCode = parseInt(statusCode, 10);
|
||||
Hoek.assert(!isNaN(numberCode) && numberCode >= 400, 'First argument must be a number (400+):', statusCode);
|
||||
|
||||
error.isBoom = true;
|
||||
error.isServer = numberCode >= 500;
|
||||
|
||||
if (!error.hasOwnProperty('data')) {
|
||||
error.data = null;
|
||||
}
|
||||
|
||||
error.output = {
|
||||
statusCode: numberCode,
|
||||
payload: {},
|
||||
headers: {}
|
||||
};
|
||||
|
||||
error.reformat = internals.reformat;
|
||||
error.reformat();
|
||||
|
||||
if (!message &&
|
||||
!error.message) {
|
||||
|
||||
message = error.output.payload.error;
|
||||
}
|
||||
|
||||
if (message) {
|
||||
error.message = (message + (error.message ? ': ' + error.message : ''));
|
||||
}
|
||||
|
||||
return error;
|
||||
};
|
||||
|
||||
|
||||
internals.reformat = function () {
|
||||
|
||||
this.output.payload.statusCode = this.output.statusCode;
|
||||
this.output.payload.error = Http.STATUS_CODES[this.output.statusCode] || 'Unknown';
|
||||
|
||||
if (this.output.statusCode === 500) {
|
||||
this.output.payload.message = 'An internal server error occurred'; // Hide actual error from user
|
||||
}
|
||||
else if (this.message) {
|
||||
this.output.payload.message = this.message;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 4xx Client Errors
|
||||
|
||||
exports.badRequest = function (message, data) {
|
||||
|
||||
return internals.create(400, message, data, exports.badRequest);
|
||||
};
|
||||
|
||||
|
||||
exports.unauthorized = function (message, scheme, attributes) { // Or function (message, wwwAuthenticate[])
|
||||
|
||||
var err = internals.create(401, message, undefined, exports.unauthorized);
|
||||
|
||||
if (!scheme) {
|
||||
return err;
|
||||
}
|
||||
|
||||
var wwwAuthenticate = '';
|
||||
var i = 0;
|
||||
var il = 0;
|
||||
|
||||
if (typeof scheme === 'string') {
|
||||
|
||||
// function (message, scheme, attributes)
|
||||
|
||||
wwwAuthenticate = scheme;
|
||||
|
||||
if (attributes || message) {
|
||||
err.output.payload.attributes = {};
|
||||
}
|
||||
|
||||
if (attributes) {
|
||||
var names = Object.keys(attributes);
|
||||
for (i = 0, il = names.length; i < il; ++i) {
|
||||
var name = names[i];
|
||||
if (i) {
|
||||
wwwAuthenticate += ',';
|
||||
}
|
||||
|
||||
var value = attributes[name];
|
||||
if (value === null ||
|
||||
value === undefined) { // Value can be zero
|
||||
|
||||
value = '';
|
||||
}
|
||||
wwwAuthenticate += ' ' + name + '="' + Hoek.escapeHeaderAttribute(value.toString()) + '"';
|
||||
err.output.payload.attributes[name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (message) {
|
||||
if (attributes) {
|
||||
wwwAuthenticate += ',';
|
||||
}
|
||||
wwwAuthenticate += ' error="' + Hoek.escapeHeaderAttribute(message) + '"';
|
||||
err.output.payload.attributes.error = message;
|
||||
}
|
||||
else {
|
||||
err.isMissing = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
// function (message, wwwAuthenticate[])
|
||||
|
||||
var wwwArray = scheme;
|
||||
for (i = 0, il = wwwArray.length; i < il; ++i) {
|
||||
if (i) {
|
||||
wwwAuthenticate += ', ';
|
||||
}
|
||||
|
||||
wwwAuthenticate += wwwArray[i];
|
||||
}
|
||||
}
|
||||
|
||||
err.output.headers['WWW-Authenticate'] = wwwAuthenticate;
|
||||
|
||||
return err;
|
||||
};
|
||||
|
||||
|
||||
exports.forbidden = function (message, data) {
|
||||
|
||||
return internals.create(403, message, data, exports.forbidden);
|
||||
};
|
||||
|
||||
|
||||
exports.notFound = function (message, data) {
|
||||
|
||||
return internals.create(404, message, data, exports.notFound);
|
||||
};
|
||||
|
||||
|
||||
exports.methodNotAllowed = function (message, data) {
|
||||
|
||||
return internals.create(405, message, data, exports.methodNotAllowed);
|
||||
};
|
||||
|
||||
|
||||
exports.notAcceptable = function (message, data) {
|
||||
|
||||
return internals.create(406, message, data, exports.notAcceptable);
|
||||
};
|
||||
|
||||
|
||||
exports.proxyAuthRequired = function (message, data) {
|
||||
|
||||
return internals.create(407, message, data, exports.proxyAuthRequired);
|
||||
};
|
||||
|
||||
|
||||
exports.clientTimeout = function (message, data) {
|
||||
|
||||
return internals.create(408, message, data, exports.clientTimeout);
|
||||
};
|
||||
|
||||
|
||||
exports.conflict = function (message, data) {
|
||||
|
||||
return internals.create(409, message, data, exports.conflict);
|
||||
};
|
||||
|
||||
|
||||
exports.resourceGone = function (message, data) {
|
||||
|
||||
return internals.create(410, message, data, exports.resourceGone);
|
||||
};
|
||||
|
||||
|
||||
exports.lengthRequired = function (message, data) {
|
||||
|
||||
return internals.create(411, message, data, exports.lengthRequired);
|
||||
};
|
||||
|
||||
|
||||
exports.preconditionFailed = function (message, data) {
|
||||
|
||||
return internals.create(412, message, data, exports.preconditionFailed);
|
||||
};
|
||||
|
||||
|
||||
exports.entityTooLarge = function (message, data) {
|
||||
|
||||
return internals.create(413, message, data, exports.entityTooLarge);
|
||||
};
|
||||
|
||||
|
||||
exports.uriTooLong = function (message, data) {
|
||||
|
||||
return internals.create(414, message, data, exports.uriTooLong);
|
||||
};
|
||||
|
||||
|
||||
exports.unsupportedMediaType = function (message, data) {
|
||||
|
||||
return internals.create(415, message, data, exports.unsupportedMediaType);
|
||||
};
|
||||
|
||||
|
||||
exports.rangeNotSatisfiable = function (message, data) {
|
||||
|
||||
return internals.create(416, message, data, exports.rangeNotSatisfiable);
|
||||
};
|
||||
|
||||
|
||||
exports.expectationFailed = function (message, data) {
|
||||
|
||||
return internals.create(417, message, data, exports.expectationFailed);
|
||||
};
|
||||
|
||||
exports.badData = function (message, data) {
|
||||
|
||||
return internals.create(422, message, data, exports.badData);
|
||||
};
|
||||
|
||||
|
||||
exports.preconditionRequired = function (message, data) {
|
||||
|
||||
return internals.create(428, message, data, exports.preconditionRequired);
|
||||
};
|
||||
|
||||
|
||||
exports.tooManyRequests = function (message, data) {
|
||||
|
||||
return internals.create(429, message, data, exports.tooManyRequests);
|
||||
};
|
||||
|
||||
|
||||
// 5xx Server Errors
|
||||
|
||||
exports.internal = function (message, data, statusCode) {
|
||||
|
||||
return internals.serverError(message, data, statusCode, exports.internal);
|
||||
};
|
||||
|
||||
internals.serverError = function (message, data, statusCode, ctor) {
|
||||
|
||||
var error;
|
||||
if (data instanceof Error) {
|
||||
error = exports.wrap(data, statusCode, message);
|
||||
} else {
|
||||
error = internals.create(statusCode || 500, message, undefined, ctor);
|
||||
error.data = data;
|
||||
}
|
||||
|
||||
return error;
|
||||
};
|
||||
|
||||
|
||||
exports.notImplemented = function (message, data) {
|
||||
|
||||
return internals.serverError(message, data, 501, exports.notImplemented);
|
||||
};
|
||||
|
||||
|
||||
exports.badGateway = function (message, data) {
|
||||
|
||||
return internals.serverError(message, data, 502, exports.badGateway);
|
||||
};
|
||||
|
||||
|
||||
exports.serverTimeout = function (message, data) {
|
||||
|
||||
return internals.serverError(message, data, 503, exports.serverTimeout);
|
||||
};
|
||||
|
||||
|
||||
exports.gatewayTimeout = function (message, data) {
|
||||
|
||||
return internals.serverError(message, data, 504, exports.gatewayTimeout);
|
||||
};
|
||||
|
||||
|
||||
exports.badImplementation = function (message, data) {
|
||||
|
||||
var err = internals.serverError(message, data, 500, exports.badImplementation);
|
||||
err.isDeveloperError = true;
|
||||
return err;
|
||||
};
|
||||
59
static/js/ketcher2/node_modules/coveralls/node_modules/boom/package.json
generated
vendored
Normal file
59
static/js/ketcher2/node_modules/coveralls/node_modules/boom/package.json
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"_from": "boom@2.x.x",
|
||||
"_id": "boom@2.10.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
|
||||
"_location": "/coveralls/boom",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "boom@2.x.x",
|
||||
"name": "boom",
|
||||
"escapedName": "boom",
|
||||
"rawSpec": "2.x.x",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "2.x.x"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/coveralls/cryptiles",
|
||||
"/coveralls/hawk"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
|
||||
"_shasum": "39c8918ceff5799f83f9492a848f625add0c766f",
|
||||
"_spec": "boom@2.x.x",
|
||||
"_where": "/home/manfred/enviPath/ketcher2/ketcher/node_modules/coveralls/node_modules/hawk",
|
||||
"bugs": {
|
||||
"url": "https://github.com/hapijs/boom/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"hoek": "2.x.x"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "HTTP-friendly error objects",
|
||||
"devDependencies": {
|
||||
"code": "1.x.x",
|
||||
"lab": "7.x.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.40"
|
||||
},
|
||||
"homepage": "https://github.com/hapijs/boom#readme",
|
||||
"keywords": [
|
||||
"error",
|
||||
"http"
|
||||
],
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "lib/index.js",
|
||||
"name": "boom",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/hapijs/boom.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "lab -a code -t 100 -L",
|
||||
"test-cov-html": "lab -a code -r html -o coverage.html -L"
|
||||
},
|
||||
"version": "2.10.1"
|
||||
}
|
||||
654
static/js/ketcher2/node_modules/coveralls/node_modules/boom/test/index.js
generated
vendored
Executable file
654
static/js/ketcher2/node_modules/coveralls/node_modules/boom/test/index.js
generated
vendored
Executable file
@ -0,0 +1,654 @@
|
||||
// Load modules
|
||||
|
||||
var Code = require('code');
|
||||
var Boom = require('../lib');
|
||||
var Lab = require('lab');
|
||||
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
|
||||
// Test shortcuts
|
||||
|
||||
var lab = exports.lab = Lab.script();
|
||||
var describe = lab.describe;
|
||||
var it = lab.it;
|
||||
var expect = Code.expect;
|
||||
|
||||
|
||||
it('returns the same object when already boom', function (done) {
|
||||
|
||||
var error = Boom.badRequest();
|
||||
var wrapped = Boom.wrap(error);
|
||||
expect(error).to.equal(wrapped);
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns an error with info when constructed using another error', function (done) {
|
||||
|
||||
var error = new Error('ka-boom');
|
||||
error.xyz = 123;
|
||||
var err = Boom.wrap(error);
|
||||
expect(err.xyz).to.equal(123);
|
||||
expect(err.message).to.equal('ka-boom');
|
||||
expect(err.output).to.deep.equal({
|
||||
statusCode: 500,
|
||||
payload: {
|
||||
statusCode: 500,
|
||||
error: 'Internal Server Error',
|
||||
message: 'An internal server error occurred'
|
||||
},
|
||||
headers: {}
|
||||
});
|
||||
expect(err.data).to.equal(null);
|
||||
done();
|
||||
});
|
||||
|
||||
it('does not override data when constructed using another error', function (done) {
|
||||
|
||||
var error = new Error('ka-boom');
|
||||
error.data = { useful: 'data' };
|
||||
var err = Boom.wrap(error);
|
||||
expect(err.data).to.equal(error.data);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets new message when none exists', function (done) {
|
||||
|
||||
var error = new Error();
|
||||
var wrapped = Boom.wrap(error, 400, 'something bad');
|
||||
expect(wrapped.message).to.equal('something bad');
|
||||
done();
|
||||
});
|
||||
|
||||
it('throws when statusCode is not a number', function (done) {
|
||||
|
||||
expect(function () {
|
||||
|
||||
Boom.create('x');
|
||||
}).to.throw('First argument must be a number (400+): x');
|
||||
done();
|
||||
});
|
||||
|
||||
it('will cast a number-string to an integer', function (done) {
|
||||
|
||||
var codes = [
|
||||
{ input: '404', result: 404 },
|
||||
{ input: '404.1', result: 404 },
|
||||
{ input: 400, result: 400 },
|
||||
{ input: 400.123, result: 400 }];
|
||||
for (var i = 0, il = codes.length; i < il; ++i) {
|
||||
var code = codes[i];
|
||||
var err = Boom.create(code.input);
|
||||
expect(err.output.statusCode).to.equal(code.result);
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('throws when statusCode is not finite', function (done) {
|
||||
|
||||
expect(function () {
|
||||
|
||||
Boom.create(1 / 0);
|
||||
}).to.throw('First argument must be a number (400+): null');
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets error code to unknown', function (done) {
|
||||
|
||||
var err = Boom.create(999);
|
||||
expect(err.output.payload.error).to.equal('Unknown');
|
||||
done();
|
||||
});
|
||||
|
||||
describe('create()', function () {
|
||||
|
||||
it('does not sets null message', function (done) {
|
||||
|
||||
var error = Boom.unauthorized(null);
|
||||
expect(error.output.payload.message).to.not.exist();
|
||||
expect(error.isServer).to.be.false();
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets message and data', function (done) {
|
||||
|
||||
var error = Boom.badRequest('Missing data', { type: 'user' });
|
||||
expect(error.data.type).to.equal('user');
|
||||
expect(error.output.payload.message).to.equal('Missing data');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('isBoom()', function () {
|
||||
|
||||
it('returns true for Boom object', function (done) {
|
||||
|
||||
expect(Boom.badRequest().isBoom).to.equal(true);
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns false for Error object', function (done) {
|
||||
|
||||
expect((new Error()).isBoom).to.not.exist();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('badRequest()', function () {
|
||||
|
||||
it('returns a 400 error statusCode', function (done) {
|
||||
|
||||
var error = Boom.badRequest();
|
||||
|
||||
expect(error.output.statusCode).to.equal(400);
|
||||
expect(error.isServer).to.be.false();
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.badRequest('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message to HTTP status if none provided', function (done) {
|
||||
|
||||
expect(Boom.badRequest().message).to.equal('Bad Request');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('unauthorized()', function () {
|
||||
|
||||
it('returns a 401 error statusCode', function (done) {
|
||||
|
||||
var err = Boom.unauthorized();
|
||||
expect(err.output.statusCode).to.equal(401);
|
||||
expect(err.output.headers).to.deep.equal({});
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.unauthorized('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns a WWW-Authenticate header when passed a scheme', function (done) {
|
||||
|
||||
var err = Boom.unauthorized('boom', 'Test');
|
||||
expect(err.output.statusCode).to.equal(401);
|
||||
expect(err.output.headers['WWW-Authenticate']).to.equal('Test error="boom"');
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns a WWW-Authenticate header set to the schema array value', function (done) {
|
||||
|
||||
var err = Boom.unauthorized(null, ['Test','one','two']);
|
||||
expect(err.output.statusCode).to.equal(401);
|
||||
expect(err.output.headers['WWW-Authenticate']).to.equal('Test, one, two');
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns a WWW-Authenticate header when passed a scheme and attributes', function (done) {
|
||||
|
||||
var err = Boom.unauthorized('boom', 'Test', { a: 1, b: 'something', c: null, d: 0 });
|
||||
expect(err.output.statusCode).to.equal(401);
|
||||
expect(err.output.headers['WWW-Authenticate']).to.equal('Test a="1", b="something", c="", d="0", error="boom"');
|
||||
expect(err.output.payload.attributes).to.deep.equal({ a: 1, b: 'something', c: '', d: 0, error: 'boom' });
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns a WWW-Authenticate header when passed attributes, missing error', function (done) {
|
||||
|
||||
var err = Boom.unauthorized(null, 'Test', { a: 1, b: 'something', c: null, d: 0 });
|
||||
expect(err.output.statusCode).to.equal(401);
|
||||
expect(err.output.headers['WWW-Authenticate']).to.equal('Test a="1", b="something", c="", d="0"');
|
||||
expect(err.isMissing).to.equal(true);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the isMissing flag when error message is empty', function (done) {
|
||||
|
||||
var err = Boom.unauthorized('', 'Basic');
|
||||
expect(err.isMissing).to.equal(true);
|
||||
done();
|
||||
});
|
||||
|
||||
it('does not set the isMissing flag when error message is not empty', function (done) {
|
||||
|
||||
var err = Boom.unauthorized('message', 'Basic');
|
||||
expect(err.isMissing).to.equal(undefined);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets a WWW-Authenticate when passed as an array', function (done) {
|
||||
|
||||
var err = Boom.unauthorized('message', ['Basic', 'Example e="1"', 'Another x="3", y="4"']);
|
||||
expect(err.output.headers['WWW-Authenticate']).to.equal('Basic, Example e="1", Another x="3", y="4"');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('methodNotAllowed()', function () {
|
||||
|
||||
it('returns a 405 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.methodNotAllowed().output.statusCode).to.equal(405);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.methodNotAllowed('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('notAcceptable()', function () {
|
||||
|
||||
it('returns a 406 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.notAcceptable().output.statusCode).to.equal(406);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.notAcceptable('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('proxyAuthRequired()', function () {
|
||||
|
||||
it('returns a 407 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.proxyAuthRequired().output.statusCode).to.equal(407);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.proxyAuthRequired('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('clientTimeout()', function () {
|
||||
|
||||
it('returns a 408 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.clientTimeout().output.statusCode).to.equal(408);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.clientTimeout('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('conflict()', function () {
|
||||
|
||||
it('returns a 409 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.conflict().output.statusCode).to.equal(409);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.conflict('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('resourceGone()', function () {
|
||||
|
||||
it('returns a 410 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.resourceGone().output.statusCode).to.equal(410);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.resourceGone('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('lengthRequired()', function () {
|
||||
|
||||
it('returns a 411 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.lengthRequired().output.statusCode).to.equal(411);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.lengthRequired('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('preconditionFailed()', function () {
|
||||
|
||||
it('returns a 412 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.preconditionFailed().output.statusCode).to.equal(412);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.preconditionFailed('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('entityTooLarge()', function () {
|
||||
|
||||
it('returns a 413 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.entityTooLarge().output.statusCode).to.equal(413);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.entityTooLarge('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('uriTooLong()', function () {
|
||||
|
||||
it('returns a 414 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.uriTooLong().output.statusCode).to.equal(414);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.uriTooLong('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('unsupportedMediaType()', function () {
|
||||
|
||||
it('returns a 415 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.unsupportedMediaType().output.statusCode).to.equal(415);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.unsupportedMediaType('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('rangeNotSatisfiable()', function () {
|
||||
|
||||
it('returns a 416 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.rangeNotSatisfiable().output.statusCode).to.equal(416);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.rangeNotSatisfiable('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('expectationFailed()', function () {
|
||||
|
||||
it('returns a 417 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.expectationFailed().output.statusCode).to.equal(417);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.expectationFailed('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('badData()', function () {
|
||||
|
||||
it('returns a 422 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.badData().output.statusCode).to.equal(422);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.badData('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('preconditionRequired()', function () {
|
||||
|
||||
it('returns a 428 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.preconditionRequired().output.statusCode).to.equal(428);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.preconditionRequired('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('tooManyRequests()', function () {
|
||||
|
||||
it('returns a 429 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.tooManyRequests().output.statusCode).to.equal(429);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed-in message', function (done) {
|
||||
|
||||
expect(Boom.tooManyRequests('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('serverTimeout()', function () {
|
||||
|
||||
it('returns a 503 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.serverTimeout().output.statusCode).to.equal(503);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.serverTimeout('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('forbidden()', function () {
|
||||
|
||||
it('returns a 403 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.forbidden().output.statusCode).to.equal(403);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.forbidden('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('notFound()', function () {
|
||||
|
||||
it('returns a 404 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.notFound().output.statusCode).to.equal(404);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.notFound('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('internal()', function () {
|
||||
|
||||
it('returns a 500 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.internal().output.statusCode).to.equal(500);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
var err = Boom.internal('my message');
|
||||
expect(err.message).to.equal('my message');
|
||||
expect(err.isServer).to.true();
|
||||
expect(err.output.payload.message).to.equal('An internal server error occurred');
|
||||
done();
|
||||
});
|
||||
|
||||
it('passes data on the callback if its passed in', function (done) {
|
||||
|
||||
expect(Boom.internal('my message', { my: 'data' }).data.my).to.equal('data');
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns an error with composite message', function (done) {
|
||||
|
||||
try {
|
||||
JSON.parse('{');
|
||||
}
|
||||
catch (err) {
|
||||
var boom = Boom.internal('Someting bad', err);
|
||||
expect(boom.message).to.equal('Someting bad: Unexpected end of input');
|
||||
expect(boom.isServer).to.be.true();
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('notImplemented()', function () {
|
||||
|
||||
it('returns a 501 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.notImplemented().output.statusCode).to.equal(501);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.notImplemented('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('badGateway()', function () {
|
||||
|
||||
it('returns a 502 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.badGateway().output.statusCode).to.equal(502);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.badGateway('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('gatewayTimeout()', function () {
|
||||
|
||||
it('returns a 504 error statusCode', function (done) {
|
||||
|
||||
expect(Boom.gatewayTimeout().output.statusCode).to.equal(504);
|
||||
done();
|
||||
});
|
||||
|
||||
it('sets the message with the passed in message', function (done) {
|
||||
|
||||
expect(Boom.gatewayTimeout('my message').message).to.equal('my message');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('badImplementation()', function () {
|
||||
|
||||
it('returns a 500 error statusCode', function (done) {
|
||||
|
||||
var err = Boom.badImplementation();
|
||||
expect(err.output.statusCode).to.equal(500);
|
||||
expect(err.isDeveloperError).to.equal(true);
|
||||
expect(err.isServer).to.be.true();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('stack trace', function () {
|
||||
|
||||
it('should omit lib', function (done) {
|
||||
|
||||
['badRequest', 'unauthorized', 'forbidden', 'notFound', 'methodNotAllowed',
|
||||
'notAcceptable', 'proxyAuthRequired', 'clientTimeout', 'conflict',
|
||||
'resourceGone', 'lengthRequired', 'preconditionFailed', 'entityTooLarge',
|
||||
'uriTooLong', 'unsupportedMediaType', 'rangeNotSatisfiable', 'expectationFailed',
|
||||
'badData', 'preconditionRequired', 'tooManyRequests',
|
||||
|
||||
// 500s
|
||||
'internal', 'notImplemented', 'badGateway', 'serverTimeout', 'gatewayTimeout',
|
||||
'badImplementation'
|
||||
].forEach(function (name) {
|
||||
|
||||
var err = Boom[name]();
|
||||
expect(err.stack).to.not.match(/\/lib\/index\.js/);
|
||||
});
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
28
static/js/ketcher2/node_modules/coveralls/node_modules/caseless/LICENSE
generated
vendored
Normal file
28
static/js/ketcher2/node_modules/coveralls/node_modules/caseless/LICENSE
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
1. Definitions.
|
||||
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||
You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||
You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
||||
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
||||
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
||||
END OF TERMS AND CONDITIONS
|
||||
45
static/js/ketcher2/node_modules/coveralls/node_modules/caseless/README.md
generated
vendored
Normal file
45
static/js/ketcher2/node_modules/coveralls/node_modules/caseless/README.md
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
## Caseless -- wrap an object to set and get property with caseless semantics but also preserve caseing.
|
||||
|
||||
This library is incredibly useful when working with HTTP headers. It allows you to get/set/check for headers in a caseless manner while also preserving the caseing of headers the first time they are set.
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
var headers = {}
|
||||
, c = caseless(headers)
|
||||
;
|
||||
c.set('a-Header', 'asdf')
|
||||
c.get('a-header') === 'asdf'
|
||||
```
|
||||
|
||||
## has(key)
|
||||
|
||||
Has takes a name and if it finds a matching header will return that header name with the preserved caseing it was set with.
|
||||
|
||||
```javascript
|
||||
c.has('a-header') === 'a-Header'
|
||||
```
|
||||
|
||||
## set(key, value[, clobber=true])
|
||||
|
||||
Set is fairly straight forward except that if the header exists and clobber is disabled it will add `','+value` to the existing header.
|
||||
|
||||
```javascript
|
||||
c.set('a-Header', 'fdas')
|
||||
c.set('a-HEADER', 'more', false)
|
||||
c.get('a-header') === 'fdsa,more'
|
||||
```
|
||||
|
||||
## swap(key)
|
||||
|
||||
Swaps the casing of a header with the new one that is passed in.
|
||||
|
||||
```javascript
|
||||
var headers = {}
|
||||
, c = caseless(headers)
|
||||
;
|
||||
c.set('a-Header', 'fdas')
|
||||
c.swap('a-HEADER')
|
||||
c.has('a-header') === 'a-HEADER'
|
||||
headers === {'a-HEADER': 'fdas'}
|
||||
```
|
||||
66
static/js/ketcher2/node_modules/coveralls/node_modules/caseless/index.js
generated
vendored
Normal file
66
static/js/ketcher2/node_modules/coveralls/node_modules/caseless/index.js
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
function Caseless (dict) {
|
||||
this.dict = dict || {}
|
||||
}
|
||||
Caseless.prototype.set = function (name, value, clobber) {
|
||||
if (typeof name === 'object') {
|
||||
for (var i in name) {
|
||||
this.set(i, name[i], value)
|
||||
}
|
||||
} else {
|
||||
if (typeof clobber === 'undefined') clobber = true
|
||||
var has = this.has(name)
|
||||
|
||||
if (!clobber && has) this.dict[has] = this.dict[has] + ',' + value
|
||||
else this.dict[has || name] = value
|
||||
return has
|
||||
}
|
||||
}
|
||||
Caseless.prototype.has = function (name) {
|
||||
var keys = Object.keys(this.dict)
|
||||
, name = name.toLowerCase()
|
||||
;
|
||||
for (var i=0;i<keys.length;i++) {
|
||||
if (keys[i].toLowerCase() === name) return keys[i]
|
||||
}
|
||||
return false
|
||||
}
|
||||
Caseless.prototype.get = function (name) {
|
||||
name = name.toLowerCase()
|
||||
var result, _key
|
||||
var headers = this.dict
|
||||
Object.keys(headers).forEach(function (key) {
|
||||
_key = key.toLowerCase()
|
||||
if (name === _key) result = headers[key]
|
||||
})
|
||||
return result
|
||||
}
|
||||
Caseless.prototype.swap = function (name) {
|
||||
var has = this.has(name)
|
||||
if (!has) throw new Error('There is no header than matches "'+name+'"')
|
||||
this.dict[name] = this.dict[has]
|
||||
delete this.dict[has]
|
||||
}
|
||||
Caseless.prototype.del = function (name) {
|
||||
var has = this.has(name)
|
||||
return delete this.dict[has || name]
|
||||
}
|
||||
|
||||
module.exports = function (dict) {return new Caseless(dict)}
|
||||
module.exports.httpify = function (resp, headers) {
|
||||
var c = new Caseless(headers)
|
||||
resp.setHeader = function (key, value, clobber) {
|
||||
if (typeof value === 'undefined') return
|
||||
return c.set(key, value, clobber)
|
||||
}
|
||||
resp.hasHeader = function (key) {
|
||||
return c.has(key)
|
||||
}
|
||||
resp.getHeader = function (key) {
|
||||
return c.get(key)
|
||||
}
|
||||
resp.removeHeader = function (key) {
|
||||
return c.del(key)
|
||||
}
|
||||
resp.headers = c.dict
|
||||
return c
|
||||
}
|
||||
56
static/js/ketcher2/node_modules/coveralls/node_modules/caseless/package.json
generated
vendored
Normal file
56
static/js/ketcher2/node_modules/coveralls/node_modules/caseless/package.json
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
{
|
||||
"_from": "caseless@~0.11.0",
|
||||
"_id": "caseless@0.11.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=",
|
||||
"_location": "/coveralls/caseless",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "caseless@~0.11.0",
|
||||
"name": "caseless",
|
||||
"escapedName": "caseless",
|
||||
"rawSpec": "~0.11.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "~0.11.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/coveralls/request"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
|
||||
"_shasum": "715b96ea9841593cc33067923f5ec60ebda4f7d7",
|
||||
"_spec": "caseless@~0.11.0",
|
||||
"_where": "/home/manfred/enviPath/ketcher2/ketcher/node_modules/coveralls/node_modules/request",
|
||||
"author": {
|
||||
"name": "Mikeal Rogers",
|
||||
"email": "mikeal.rogers@gmail.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/mikeal/caseless/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"deprecated": false,
|
||||
"description": "Caseless object set/get/has, very useful when working with HTTP headers.",
|
||||
"devDependencies": {
|
||||
"tape": "^2.10.2"
|
||||
},
|
||||
"homepage": "https://github.com/mikeal/caseless#readme",
|
||||
"keywords": [
|
||||
"headers",
|
||||
"http",
|
||||
"caseless"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"main": "index.js",
|
||||
"name": "caseless",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/mikeal/caseless.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node test.js"
|
||||
},
|
||||
"test": "node test.js",
|
||||
"version": "0.11.0"
|
||||
}
|
||||
40
static/js/ketcher2/node_modules/coveralls/node_modules/caseless/test.js
generated
vendored
Normal file
40
static/js/ketcher2/node_modules/coveralls/node_modules/caseless/test.js
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
var tape = require('tape')
|
||||
, caseless = require('./')
|
||||
;
|
||||
|
||||
tape('set get has', function (t) {
|
||||
var headers = {}
|
||||
, c = caseless(headers)
|
||||
;
|
||||
t.plan(17)
|
||||
c.set('a-Header', 'asdf')
|
||||
t.equal(c.get('a-header'), 'asdf')
|
||||
t.equal(c.has('a-header'), 'a-Header')
|
||||
t.ok(!c.has('nothing'))
|
||||
// old bug where we used the wrong regex
|
||||
t.ok(!c.has('a-hea'))
|
||||
c.set('a-header', 'fdsa')
|
||||
t.equal(c.get('a-header'), 'fdsa')
|
||||
t.equal(c.get('a-Header'), 'fdsa')
|
||||
c.set('a-HEADER', 'more', false)
|
||||
t.equal(c.get('a-header'), 'fdsa,more')
|
||||
|
||||
t.deepEqual(headers, {'a-Header': 'fdsa,more'})
|
||||
c.swap('a-HEADER')
|
||||
t.deepEqual(headers, {'a-HEADER': 'fdsa,more'})
|
||||
|
||||
c.set('deleteme', 'foobar')
|
||||
t.ok(c.has('deleteme'))
|
||||
t.ok(c.del('deleteme'))
|
||||
t.notOk(c.has('deleteme'))
|
||||
t.notOk(c.has('idonotexist'))
|
||||
t.ok(c.del('idonotexist'))
|
||||
|
||||
c.set('tva', 'test1')
|
||||
c.set('tva-header', 'test2')
|
||||
t.equal(c.has('tva'), 'tva')
|
||||
t.notOk(c.has('header'))
|
||||
|
||||
t.equal(c.get('tva'), 'test1')
|
||||
|
||||
})
|
||||
28
static/js/ketcher2/node_modules/coveralls/node_modules/cryptiles/LICENSE
generated
vendored
Executable file
28
static/js/ketcher2/node_modules/coveralls/node_modules/cryptiles/LICENSE
generated
vendored
Executable file
@ -0,0 +1,28 @@
|
||||
Copyright (c) 2014, Eran Hammer and other contributors.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* The names of any contributors may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
* * *
|
||||
|
||||
The complete list of contributors can be found at: https://github.com/hueniverse/cryptiles/graphs/contributors
|
||||
16
static/js/ketcher2/node_modules/coveralls/node_modules/cryptiles/README.md
generated
vendored
Normal file
16
static/js/ketcher2/node_modules/coveralls/node_modules/cryptiles/README.md
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
cryptiles
|
||||
=========
|
||||
|
||||
General purpose crypto utilities
|
||||
|
||||
[](http://travis-ci.org/hapijs/cryptiles)
|
||||
|
||||
Lead Maintainer - [C J Silverio](https://github.com/ceejbot)
|
||||
|
||||
## Methods
|
||||
|
||||
### `randomString(<Number> size)`
|
||||
Returns a cryptographically strong pseudo-random data string. Takes a size argument for the length of the string.
|
||||
|
||||
### `fixedTimeComparison(<String> a, <String> b)`
|
||||
Compare two strings using fixed time algorithm (to prevent time-based analysis of MAC digest match). Returns `true` if the strings match, `false` if they differ.
|
||||
68
static/js/ketcher2/node_modules/coveralls/node_modules/cryptiles/lib/index.js
generated
vendored
Executable file
68
static/js/ketcher2/node_modules/coveralls/node_modules/cryptiles/lib/index.js
generated
vendored
Executable file
@ -0,0 +1,68 @@
|
||||
// Load modules
|
||||
|
||||
var Crypto = require('crypto');
|
||||
var Boom = require('boom');
|
||||
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
|
||||
// Generate a cryptographically strong pseudo-random data
|
||||
|
||||
exports.randomString = function (size) {
|
||||
|
||||
var buffer = exports.randomBits((size + 1) * 6);
|
||||
if (buffer instanceof Error) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
var string = buffer.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');
|
||||
return string.slice(0, size);
|
||||
};
|
||||
|
||||
|
||||
exports.randomBits = function (bits) {
|
||||
|
||||
if (!bits ||
|
||||
bits < 0) {
|
||||
|
||||
return Boom.internal('Invalid random bits count');
|
||||
}
|
||||
|
||||
var bytes = Math.ceil(bits / 8);
|
||||
try {
|
||||
return Crypto.randomBytes(bytes);
|
||||
}
|
||||
catch (err) {
|
||||
return Boom.internal('Failed generating random bits: ' + err.message);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Compare two strings using fixed time algorithm (to prevent time-based analysis of MAC digest match)
|
||||
|
||||
exports.fixedTimeComparison = function (a, b) {
|
||||
|
||||
if (typeof a !== 'string' ||
|
||||
typeof b !== 'string') {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var mismatch = (a.length === b.length ? 0 : 1);
|
||||
if (mismatch) {
|
||||
b = a;
|
||||
}
|
||||
|
||||
for (var i = 0, il = a.length; i < il; ++i) {
|
||||
var ac = a.charCodeAt(i);
|
||||
var bc = b.charCodeAt(i);
|
||||
mismatch |= (ac ^ bc);
|
||||
}
|
||||
|
||||
return (mismatch === 0);
|
||||
};
|
||||
|
||||
|
||||
59
static/js/ketcher2/node_modules/coveralls/node_modules/cryptiles/package.json
generated
vendored
Executable file
59
static/js/ketcher2/node_modules/coveralls/node_modules/cryptiles/package.json
generated
vendored
Executable file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"_from": "cryptiles@2.x.x",
|
||||
"_id": "cryptiles@2.0.5",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
|
||||
"_location": "/coveralls/cryptiles",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "cryptiles@2.x.x",
|
||||
"name": "cryptiles",
|
||||
"escapedName": "cryptiles",
|
||||
"rawSpec": "2.x.x",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "2.x.x"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/coveralls/hawk"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
|
||||
"_shasum": "3bdfecdc608147c1c67202fa291e7dca59eaa3b8",
|
||||
"_spec": "cryptiles@2.x.x",
|
||||
"_where": "/home/manfred/enviPath/ketcher2/ketcher/node_modules/coveralls/node_modules/hawk",
|
||||
"bugs": {
|
||||
"url": "https://github.com/hapijs/cryptiles/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"boom": "2.x.x"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "General purpose crypto utilities",
|
||||
"devDependencies": {
|
||||
"code": "1.x.x",
|
||||
"lab": "5.x.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.40"
|
||||
},
|
||||
"homepage": "https://github.com/hapijs/cryptiles#readme",
|
||||
"keywords": [
|
||||
"cryptography",
|
||||
"security",
|
||||
"utilites"
|
||||
],
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "lib/index.js",
|
||||
"name": "cryptiles",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/hapijs/cryptiles.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "lab -a code -t 100 -L",
|
||||
"test-cov-html": "lab -a code -r html -o coverage.html"
|
||||
},
|
||||
"version": "2.0.5"
|
||||
}
|
||||
102
static/js/ketcher2/node_modules/coveralls/node_modules/cryptiles/test/index.js
generated
vendored
Executable file
102
static/js/ketcher2/node_modules/coveralls/node_modules/cryptiles/test/index.js
generated
vendored
Executable file
@ -0,0 +1,102 @@
|
||||
// Load modules
|
||||
|
||||
var Code = require('code');
|
||||
var Cryptiles = require('..');
|
||||
var Lab = require('lab');
|
||||
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
|
||||
// Test shortcuts
|
||||
|
||||
var lab = exports.lab = Lab.script();
|
||||
var describe = lab.describe;
|
||||
var it = lab.it;
|
||||
var expect = Code.expect;
|
||||
|
||||
|
||||
describe('randomString()', function () {
|
||||
|
||||
it('should generate the right length string', function (done) {
|
||||
|
||||
for (var i = 1; i <= 1000; ++i) {
|
||||
expect(Cryptiles.randomString(i).length).to.equal(i);
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns an error on invalid bits size', function (done) {
|
||||
|
||||
expect(Cryptiles.randomString(99999999999999999999).message).to.match(/Failed generating random bits/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('randomBits()', function () {
|
||||
|
||||
it('returns an error on invalid input', function (done) {
|
||||
|
||||
expect(Cryptiles.randomBits(0).message).to.equal('Invalid random bits count');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('fixedTimeComparison()', function () {
|
||||
|
||||
var a = Cryptiles.randomString(50000);
|
||||
var b = Cryptiles.randomString(150000);
|
||||
|
||||
it('should take the same amount of time comparing different string sizes', function (done) {
|
||||
|
||||
var now = Date.now();
|
||||
Cryptiles.fixedTimeComparison(b, a);
|
||||
var t1 = Date.now() - now;
|
||||
|
||||
now = Date.now();
|
||||
Cryptiles.fixedTimeComparison(b, b);
|
||||
var t2 = Date.now() - now;
|
||||
|
||||
expect(t2 - t1).to.be.within(-20, 20);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should return true for equal strings', function (done) {
|
||||
|
||||
expect(Cryptiles.fixedTimeComparison(a, a)).to.equal(true);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should return false for different strings (size, a < b)', function (done) {
|
||||
|
||||
expect(Cryptiles.fixedTimeComparison(a, a + 'x')).to.equal(false);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should return false for different strings (size, a > b)', function (done) {
|
||||
|
||||
expect(Cryptiles.fixedTimeComparison(a + 'x', a)).to.equal(false);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should return false for different strings (size, a = b)', function (done) {
|
||||
|
||||
expect(Cryptiles.fixedTimeComparison(a + 'x', a + 'y')).to.equal(false);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should return false when not a string', function (done) {
|
||||
|
||||
expect(Cryptiles.fixedTimeComparison('x', null)).to.equal(false);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should return false when not a string (left)', function (done) {
|
||||
|
||||
expect(Cryptiles.fixedTimeComparison(null, 'x')).to.equal(false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
174
static/js/ketcher2/node_modules/coveralls/node_modules/esprima/ChangeLog
generated
vendored
Normal file
174
static/js/ketcher2/node_modules/coveralls/node_modules/esprima/ChangeLog
generated
vendored
Normal file
@ -0,0 +1,174 @@
|
||||
2016-08-23: Version 2.7.3
|
||||
|
||||
* Fix tokenizer confusion with a comment (issue 1493, 1516)
|
||||
|
||||
2016-02-02: Version 2.7.2
|
||||
|
||||
* Fix out-of-bound error location in an invalid string literal (issue 1457)
|
||||
* Fix shorthand object destructuring defaults in variable declarations (issue 1459)
|
||||
|
||||
2015-12-10: Version 2.7.1
|
||||
|
||||
* Do not allow trailing comma in a variable declaration (issue 1360)
|
||||
* Fix assignment to `let` in non-strict mode (issue 1376)
|
||||
* Fix missing delegate property in YieldExpression (issue 1407)
|
||||
|
||||
2015-10-22: Version 2.7.0
|
||||
|
||||
* Fix the handling of semicolon in a break statement (issue 1044)
|
||||
* Run the test suite with major web browsers (issue 1259, 1317)
|
||||
* Allow `let` as an identifier in non-strict mode (issue 1289)
|
||||
* Attach orphaned comments as `innerComments` (issue 1328)
|
||||
* Add the support for token delegator (issue 1332)
|
||||
|
||||
2015-09-01: Version 2.6.0
|
||||
|
||||
* Properly allow or prohibit `let` in a binding identifier/pattern (issue 1048, 1098)
|
||||
* Add sourceType field for Program node (issue 1159)
|
||||
* Ensure that strict mode reserved word binding throw an error (issue 1171)
|
||||
* Run the test suite with Node.js and IE 11 on Windows (issue 1294)
|
||||
* Allow binding pattern with no initializer in a for statement (issue 1301)
|
||||
|
||||
2015-07-31: Version 2.5.0
|
||||
|
||||
* Run the test suite in a browser environment (issue 1004)
|
||||
* Ensure a comma between imported default binding and named imports (issue 1046)
|
||||
* Distinguish `yield` as a keyword vs an identifier (issue 1186)
|
||||
* Support ES6 meta property `new.target` (issue 1203)
|
||||
* Fix the syntax node for yield with expression (issue 1223)
|
||||
* Fix the check of duplicated proto in property names (issue 1225)
|
||||
* Fix ES6 Unicode escape in identifier name (issue 1229)
|
||||
* Support ES6 IdentifierStart and IdentifierPart (issue 1232)
|
||||
* Treat await as a reserved word when parsing as a module (issue 1234)
|
||||
* Recognize identifier characters from Unicode SMP (issue 1244)
|
||||
* Ensure that export and import can be followed by a comma (issue 1250)
|
||||
* Fix yield operator precedence (issue 1262)
|
||||
|
||||
2015-07-01: Version 2.4.1
|
||||
|
||||
* Fix some cases of comment attachment (issue 1071, 1175)
|
||||
* Fix the handling of destructuring in function arguments (issue 1193)
|
||||
* Fix invalid ranges in assignment expression (issue 1201)
|
||||
|
||||
2015-06-26: Version 2.4.0
|
||||
|
||||
* Support ES6 for-of iteration (issue 1047)
|
||||
* Support ES6 spread arguments (issue 1169)
|
||||
* Minimize npm payload (issue 1191)
|
||||
|
||||
2015-06-16: Version 2.3.0
|
||||
|
||||
* Support ES6 generator (issue 1033)
|
||||
* Improve parsing of regular expressions with `u` flag (issue 1179)
|
||||
|
||||
2015-04-17: Version 2.2.0
|
||||
|
||||
* Support ES6 import and export declarations (issue 1000)
|
||||
* Fix line terminator before arrow not recognized as error (issue 1009)
|
||||
* Support ES6 destructuring (issue 1045)
|
||||
* Support ES6 template literal (issue 1074)
|
||||
* Fix the handling of invalid/incomplete string escape sequences (issue 1106)
|
||||
* Fix ES3 static member access restriction (issue 1120)
|
||||
* Support for `super` in ES6 class (issue 1147)
|
||||
|
||||
2015-03-09: Version 2.1.0
|
||||
|
||||
* Support ES6 class (issue 1001)
|
||||
* Support ES6 rest parameter (issue 1011)
|
||||
* Expand the location of property getter, setter, and methods (issue 1029)
|
||||
* Enable TryStatement transition to a single handler (issue 1031)
|
||||
* Support ES6 computed property name (issue 1037)
|
||||
* Tolerate unclosed block comment (issue 1041)
|
||||
* Support ES6 lexical declaration (issue 1065)
|
||||
|
||||
2015-02-06: Version 2.0.0
|
||||
|
||||
* Support ES6 arrow function (issue 517)
|
||||
* Support ES6 Unicode code point escape (issue 521)
|
||||
* Improve the speed and accuracy of comment attachment (issue 522)
|
||||
* Support ES6 default parameter (issue 519)
|
||||
* Support ES6 regular expression flags (issue 557)
|
||||
* Fix scanning of implicit octal literals (issue 565)
|
||||
* Fix the handling of automatic semicolon insertion (issue 574)
|
||||
* Support ES6 method definition (issue 620)
|
||||
* Support ES6 octal integer literal (issue 621)
|
||||
* Support ES6 binary integer literal (issue 622)
|
||||
* Support ES6 object literal property value shorthand (issue 624)
|
||||
|
||||
2015-03-03: Version 1.2.5
|
||||
|
||||
* Fix scanning of implicit octal literals (issue 565)
|
||||
|
||||
2015-02-05: Version 1.2.4
|
||||
|
||||
* Fix parsing of LeftHandSideExpression in ForInStatement (issue 560)
|
||||
* Fix the handling of automatic semicolon insertion (issue 574)
|
||||
|
||||
2015-01-18: Version 1.2.3
|
||||
|
||||
* Fix division by this (issue 616)
|
||||
|
||||
2014-05-18: Version 1.2.2
|
||||
|
||||
* Fix duplicated tokens when collecting comments (issue 537)
|
||||
|
||||
2014-05-04: Version 1.2.1
|
||||
|
||||
* Ensure that Program node may still have leading comments (issue 536)
|
||||
|
||||
2014-04-29: Version 1.2.0
|
||||
|
||||
* Fix semicolon handling for expression statement (issue 462, 533)
|
||||
* Disallow escaped characters in regular expression flags (issue 503)
|
||||
* Performance improvement for location tracking (issue 520)
|
||||
* Improve the speed of comment attachment (issue 522)
|
||||
|
||||
2014-03-26: Version 1.1.1
|
||||
|
||||
* Fix token handling of forward slash after an array literal (issue 512)
|
||||
|
||||
2014-03-23: Version 1.1.0
|
||||
|
||||
* Optionally attach comments to the owning syntax nodes (issue 197)
|
||||
* Simplify binary parsing with stack-based shift reduce (issue 352)
|
||||
* Always include the raw source of literals (issue 376)
|
||||
* Add optional input source information (issue 386)
|
||||
* Tokenizer API for pure lexical scanning (issue 398)
|
||||
* Improve the web site and its online demos (issue 337, 400, 404)
|
||||
* Performance improvement for location tracking (issue 417, 424)
|
||||
* Support HTML comment syntax (issue 451)
|
||||
* Drop support for legacy browsers (issue 474)
|
||||
|
||||
2013-08-27: Version 1.0.4
|
||||
|
||||
* Minimize the payload for packages (issue 362)
|
||||
* Fix missing cases on an empty switch statement (issue 436)
|
||||
* Support escaped ] in regexp literal character classes (issue 442)
|
||||
* Tolerate invalid left-hand side expression (issue 130)
|
||||
|
||||
2013-05-17: Version 1.0.3
|
||||
|
||||
* Variable declaration needs at least one declarator (issue 391)
|
||||
* Fix benchmark's variance unit conversion (issue 397)
|
||||
* IE < 9: \v should be treated as vertical tab (issue 405)
|
||||
* Unary expressions should always have prefix: true (issue 418)
|
||||
* Catch clause should only accept an identifier (issue 423)
|
||||
* Tolerate setters without parameter (issue 426)
|
||||
|
||||
2012-11-02: Version 1.0.2
|
||||
|
||||
Improvement:
|
||||
|
||||
* Fix esvalidate JUnit output upon a syntax error (issue 374)
|
||||
|
||||
2012-10-28: Version 1.0.1
|
||||
|
||||
Improvements:
|
||||
|
||||
* esvalidate understands shebang in a Unix shell script (issue 361)
|
||||
* esvalidate treats fatal parsing failure as an error (issue 361)
|
||||
* Reduce Node.js package via .npmignore (issue 362)
|
||||
|
||||
2012-10-22: Version 1.0.0
|
||||
|
||||
Initial release.
|
||||
21
static/js/ketcher2/node_modules/coveralls/node_modules/esprima/LICENSE.BSD
generated
vendored
Normal file
21
static/js/ketcher2/node_modules/coveralls/node_modules/esprima/LICENSE.BSD
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
Copyright (c) jQuery Foundation, Inc. and Contributors, All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
27
static/js/ketcher2/node_modules/coveralls/node_modules/esprima/README.md
generated
vendored
Normal file
27
static/js/ketcher2/node_modules/coveralls/node_modules/esprima/README.md
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
[](https://www.npmjs.com/package/esprima)
|
||||
[](https://www.npmjs.com/package/esprima)
|
||||
[](https://travis-ci.org/jquery/esprima)
|
||||
[](https://codecov.io/github/jquery/esprima)
|
||||
|
||||
**Esprima** ([esprima.org](http://esprima.org), BSD license) is a high performance,
|
||||
standard-compliant [ECMAScript](http://www.ecma-international.org/publications/standards/Ecma-262.htm)
|
||||
parser written in ECMAScript (also popularly known as
|
||||
[JavaScript](https://en.wikipedia.org/wiki/JavaScript)).
|
||||
Esprima is created and maintained by [Ariya Hidayat](https://twitter.com/ariyahidayat),
|
||||
with the help of [many contributors](https://github.com/jquery/esprima/contributors).
|
||||
|
||||
### Features
|
||||
|
||||
- Full support for ECMAScript 6 ([ECMA-262](http://www.ecma-international.org/publications/standards/Ecma-262.htm))
|
||||
- Sensible [syntax tree format](https://github.com/estree/estree/blob/master/spec.md) as standardized by [ESTree project](https://github.com/estree/estree)
|
||||
- Optional tracking of syntax node location (index-based and line-column)
|
||||
- [Heavily tested](http://esprima.org/test/ci.html) (~1250 [unit tests](https://github.com/jquery/esprima/tree/master/test/fixtures) with [full code coverage](https://codecov.io/github/jquery/esprima))
|
||||
|
||||
Esprima serves as a **building block** for some JavaScript
|
||||
language tools, from [code instrumentation](http://esprima.org/demo/functiontrace.html)
|
||||
to [editor autocompletion](http://esprima.org/demo/autocomplete.html).
|
||||
|
||||
Esprima runs on many popular web browsers, as well as other ECMAScript platforms such as
|
||||
[Rhino](http://www.mozilla.org/rhino), [Nashorn](http://openjdk.java.net/projects/nashorn/), and [Node.js](https://npmjs.org/package/esprima).
|
||||
|
||||
For more information, check the web site [esprima.org](http://esprima.org).
|
||||
126
static/js/ketcher2/node_modules/coveralls/node_modules/esprima/bin/esparse.js
generated
vendored
Executable file
126
static/js/ketcher2/node_modules/coveralls/node_modules/esprima/bin/esparse.js
generated
vendored
Executable file
@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env node
|
||||
/*
|
||||
Copyright (c) jQuery Foundation, Inc. and Contributors, All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*jslint sloppy:true node:true rhino:true */
|
||||
|
||||
var fs, esprima, fname, content, options, syntax;
|
||||
|
||||
if (typeof require === 'function') {
|
||||
fs = require('fs');
|
||||
esprima = require('esprima');
|
||||
} else if (typeof load === 'function') {
|
||||
try {
|
||||
load('esprima.js');
|
||||
} catch (e) {
|
||||
load('../esprima.js');
|
||||
}
|
||||
}
|
||||
|
||||
// Shims to Node.js objects when running under Rhino.
|
||||
if (typeof console === 'undefined' && typeof process === 'undefined') {
|
||||
console = { log: print };
|
||||
fs = { readFileSync: readFile };
|
||||
process = { argv: arguments, exit: quit };
|
||||
process.argv.unshift('esparse.js');
|
||||
process.argv.unshift('rhino');
|
||||
}
|
||||
|
||||
function showUsage() {
|
||||
console.log('Usage:');
|
||||
console.log(' esparse [options] file.js');
|
||||
console.log();
|
||||
console.log('Available options:');
|
||||
console.log();
|
||||
console.log(' --comment Gather all line and block comments in an array');
|
||||
console.log(' --loc Include line-column location info for each syntax node');
|
||||
console.log(' --range Include index-based range for each syntax node');
|
||||
console.log(' --raw Display the raw value of literals');
|
||||
console.log(' --tokens List all tokens in an array');
|
||||
console.log(' --tolerant Tolerate errors on a best-effort basis (experimental)');
|
||||
console.log(' -v, --version Shows program version');
|
||||
console.log();
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (process.argv.length <= 2) {
|
||||
showUsage();
|
||||
}
|
||||
|
||||
options = {};
|
||||
|
||||
process.argv.splice(2).forEach(function (entry) {
|
||||
|
||||
if (entry === '-h' || entry === '--help') {
|
||||
showUsage();
|
||||
} else if (entry === '-v' || entry === '--version') {
|
||||
console.log('ECMAScript Parser (using Esprima version', esprima.version, ')');
|
||||
console.log();
|
||||
process.exit(0);
|
||||
} else if (entry === '--comment') {
|
||||
options.comment = true;
|
||||
} else if (entry === '--loc') {
|
||||
options.loc = true;
|
||||
} else if (entry === '--range') {
|
||||
options.range = true;
|
||||
} else if (entry === '--raw') {
|
||||
options.raw = true;
|
||||
} else if (entry === '--tokens') {
|
||||
options.tokens = true;
|
||||
} else if (entry === '--tolerant') {
|
||||
options.tolerant = true;
|
||||
} else if (entry.slice(0, 2) === '--') {
|
||||
console.log('Error: unknown option ' + entry + '.');
|
||||
process.exit(1);
|
||||
} else if (typeof fname === 'string') {
|
||||
console.log('Error: more than one input file.');
|
||||
process.exit(1);
|
||||
} else {
|
||||
fname = entry;
|
||||
}
|
||||
});
|
||||
|
||||
if (typeof fname !== 'string') {
|
||||
console.log('Error: no input file.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Special handling for regular expression literal since we need to
|
||||
// convert it to a string literal, otherwise it will be decoded
|
||||
// as object "{}" and the regular expression would be lost.
|
||||
function adjustRegexLiteral(key, value) {
|
||||
if (key === 'value' && value instanceof RegExp) {
|
||||
value = value.toString();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
try {
|
||||
content = fs.readFileSync(fname, 'utf-8');
|
||||
syntax = esprima.parse(content, options);
|
||||
console.log(JSON.stringify(syntax, adjustRegexLiteral, 4));
|
||||
} catch (e) {
|
||||
console.log('Error: ' + e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
199
static/js/ketcher2/node_modules/coveralls/node_modules/esprima/bin/esvalidate.js
generated
vendored
Executable file
199
static/js/ketcher2/node_modules/coveralls/node_modules/esprima/bin/esvalidate.js
generated
vendored
Executable file
@ -0,0 +1,199 @@
|
||||
#!/usr/bin/env node
|
||||
/*
|
||||
Copyright (c) jQuery Foundation, Inc. and Contributors, All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*jslint sloppy:true plusplus:true node:true rhino:true */
|
||||
/*global phantom:true */
|
||||
|
||||
var fs, system, esprima, options, fnames, count;
|
||||
|
||||
if (typeof esprima === 'undefined') {
|
||||
// PhantomJS can only require() relative files
|
||||
if (typeof phantom === 'object') {
|
||||
fs = require('fs');
|
||||
system = require('system');
|
||||
esprima = require('./esprima');
|
||||
} else if (typeof require === 'function') {
|
||||
fs = require('fs');
|
||||
esprima = require('esprima');
|
||||
} else if (typeof load === 'function') {
|
||||
try {
|
||||
load('esprima.js');
|
||||
} catch (e) {
|
||||
load('../esprima.js');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shims to Node.js objects when running under PhantomJS 1.7+.
|
||||
if (typeof phantom === 'object') {
|
||||
fs.readFileSync = fs.read;
|
||||
process = {
|
||||
argv: [].slice.call(system.args),
|
||||
exit: phantom.exit
|
||||
};
|
||||
process.argv.unshift('phantomjs');
|
||||
}
|
||||
|
||||
// Shims to Node.js objects when running under Rhino.
|
||||
if (typeof console === 'undefined' && typeof process === 'undefined') {
|
||||
console = { log: print };
|
||||
fs = { readFileSync: readFile };
|
||||
process = { argv: arguments, exit: quit };
|
||||
process.argv.unshift('esvalidate.js');
|
||||
process.argv.unshift('rhino');
|
||||
}
|
||||
|
||||
function showUsage() {
|
||||
console.log('Usage:');
|
||||
console.log(' esvalidate [options] file.js');
|
||||
console.log();
|
||||
console.log('Available options:');
|
||||
console.log();
|
||||
console.log(' --format=type Set the report format, plain (default) or junit');
|
||||
console.log(' -v, --version Print program version');
|
||||
console.log();
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (process.argv.length <= 2) {
|
||||
showUsage();
|
||||
}
|
||||
|
||||
options = {
|
||||
format: 'plain'
|
||||
};
|
||||
|
||||
fnames = [];
|
||||
|
||||
process.argv.splice(2).forEach(function (entry) {
|
||||
|
||||
if (entry === '-h' || entry === '--help') {
|
||||
showUsage();
|
||||
} else if (entry === '-v' || entry === '--version') {
|
||||
console.log('ECMAScript Validator (using Esprima version', esprima.version, ')');
|
||||
console.log();
|
||||
process.exit(0);
|
||||
} else if (entry.slice(0, 9) === '--format=') {
|
||||
options.format = entry.slice(9);
|
||||
if (options.format !== 'plain' && options.format !== 'junit') {
|
||||
console.log('Error: unknown report format ' + options.format + '.');
|
||||
process.exit(1);
|
||||
}
|
||||
} else if (entry.slice(0, 2) === '--') {
|
||||
console.log('Error: unknown option ' + entry + '.');
|
||||
process.exit(1);
|
||||
} else {
|
||||
fnames.push(entry);
|
||||
}
|
||||
});
|
||||
|
||||
if (fnames.length === 0) {
|
||||
console.log('Error: no input file.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (options.format === 'junit') {
|
||||
console.log('<?xml version="1.0" encoding="UTF-8"?>');
|
||||
console.log('<testsuites>');
|
||||
}
|
||||
|
||||
count = 0;
|
||||
fnames.forEach(function (fname) {
|
||||
var content, timestamp, syntax, name;
|
||||
try {
|
||||
content = fs.readFileSync(fname, 'utf-8');
|
||||
|
||||
if (content[0] === '#' && content[1] === '!') {
|
||||
content = '//' + content.substr(2, content.length);
|
||||
}
|
||||
|
||||
timestamp = Date.now();
|
||||
syntax = esprima.parse(content, { tolerant: true });
|
||||
|
||||
if (options.format === 'junit') {
|
||||
|
||||
name = fname;
|
||||
if (name.lastIndexOf('/') >= 0) {
|
||||
name = name.slice(name.lastIndexOf('/') + 1);
|
||||
}
|
||||
|
||||
console.log('<testsuite name="' + fname + '" errors="0" ' +
|
||||
' failures="' + syntax.errors.length + '" ' +
|
||||
' tests="' + syntax.errors.length + '" ' +
|
||||
' time="' + Math.round((Date.now() - timestamp) / 1000) +
|
||||
'">');
|
||||
|
||||
syntax.errors.forEach(function (error) {
|
||||
var msg = error.message;
|
||||
msg = msg.replace(/^Line\ [0-9]*\:\ /, '');
|
||||
console.log(' <testcase name="Line ' + error.lineNumber + ': ' + msg + '" ' +
|
||||
' time="0">');
|
||||
console.log(' <error type="SyntaxError" message="' + error.message + '">' +
|
||||
error.message + '(' + name + ':' + error.lineNumber + ')' +
|
||||
'</error>');
|
||||
console.log(' </testcase>');
|
||||
});
|
||||
|
||||
console.log('</testsuite>');
|
||||
|
||||
} else if (options.format === 'plain') {
|
||||
|
||||
syntax.errors.forEach(function (error) {
|
||||
var msg = error.message;
|
||||
msg = msg.replace(/^Line\ [0-9]*\:\ /, '');
|
||||
msg = fname + ':' + error.lineNumber + ': ' + msg;
|
||||
console.log(msg);
|
||||
++count;
|
||||
});
|
||||
|
||||
}
|
||||
} catch (e) {
|
||||
++count;
|
||||
if (options.format === 'junit') {
|
||||
console.log('<testsuite name="' + fname + '" errors="1" failures="0" tests="1" ' +
|
||||
' time="' + Math.round((Date.now() - timestamp) / 1000) + '">');
|
||||
console.log(' <testcase name="' + e.message + '" ' + ' time="0">');
|
||||
console.log(' <error type="ParseError" message="' + e.message + '">' +
|
||||
e.message + '(' + fname + ((e.lineNumber) ? ':' + e.lineNumber : '') +
|
||||
')</error>');
|
||||
console.log(' </testcase>');
|
||||
console.log('</testsuite>');
|
||||
} else {
|
||||
console.log('Error: ' + e.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (options.format === 'junit') {
|
||||
console.log('</testsuites>');
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (count === 0 && typeof phantom === 'object') {
|
||||
process.exit(0);
|
||||
}
|
||||
5740
static/js/ketcher2/node_modules/coveralls/node_modules/esprima/esprima.js
generated
vendored
Normal file
5740
static/js/ketcher2/node_modules/coveralls/node_modules/esprima/esprima.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
124
static/js/ketcher2/node_modules/coveralls/node_modules/esprima/package.json
generated
vendored
Normal file
124
static/js/ketcher2/node_modules/coveralls/node_modules/esprima/package.json
generated
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
{
|
||||
"_from": "esprima@^2.6.0",
|
||||
"_id": "esprima@2.7.3",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
|
||||
"_location": "/coveralls/esprima",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "esprima@^2.6.0",
|
||||
"name": "esprima",
|
||||
"escapedName": "esprima",
|
||||
"rawSpec": "^2.6.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^2.6.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/coveralls/js-yaml"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
|
||||
"_shasum": "96e3b70d5779f6ad49cd032673d1c312767ba581",
|
||||
"_spec": "esprima@^2.6.0",
|
||||
"_where": "/home/manfred/enviPath/ketcher2/ketcher/node_modules/coveralls/node_modules/js-yaml",
|
||||
"author": {
|
||||
"name": "Ariya Hidayat",
|
||||
"email": "ariya.hidayat@gmail.com"
|
||||
},
|
||||
"bin": {
|
||||
"esparse": "./bin/esparse.js",
|
||||
"esvalidate": "./bin/esvalidate.js"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jquery/esprima/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"deprecated": false,
|
||||
"description": "ECMAScript parsing infrastructure for multipurpose analysis",
|
||||
"devDependencies": {
|
||||
"codecov.io": "~0.1.6",
|
||||
"escomplex-js": "1.2.0",
|
||||
"eslint": "~1.7.2",
|
||||
"everything.js": "~1.0.3",
|
||||
"glob": "^5.0.15",
|
||||
"istanbul": "~0.4.0",
|
||||
"jscs": "~2.3.5",
|
||||
"json-diff": "~0.3.1",
|
||||
"karma": "^0.13.11",
|
||||
"karma-chrome-launcher": "^0.2.1",
|
||||
"karma-detect-browsers": "^2.0.2",
|
||||
"karma-firefox-launcher": "^0.1.6",
|
||||
"karma-ie-launcher": "^0.2.0",
|
||||
"karma-mocha": "^0.2.0",
|
||||
"karma-safari-launcher": "^0.1.1",
|
||||
"karma-sauce-launcher": "^0.2.14",
|
||||
"lodash": "^3.10.0",
|
||||
"mocha": "^2.3.3",
|
||||
"node-tick-processor": "~0.0.2",
|
||||
"regenerate": "~1.2.1",
|
||||
"temp": "~0.8.3",
|
||||
"unicode-7.0.0": "~0.1.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"bin",
|
||||
"unit-tests.js",
|
||||
"esprima.js"
|
||||
],
|
||||
"homepage": "http://esprima.org",
|
||||
"keywords": [
|
||||
"ast",
|
||||
"ecmascript",
|
||||
"javascript",
|
||||
"parser",
|
||||
"syntax"
|
||||
],
|
||||
"license": "BSD-2-Clause",
|
||||
"main": "esprima.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Ariya Hidayat",
|
||||
"email": "ariya.hidayat@gmail.com",
|
||||
"url": "http://ariya.ofilabs.com"
|
||||
}
|
||||
],
|
||||
"name": "esprima",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jquery/esprima.git"
|
||||
},
|
||||
"scripts": {
|
||||
"all-tests": "npm run generate-fixtures && npm run unit-tests && npm run grammar-tests && npm run regression-tests",
|
||||
"analyze-coverage": "istanbul cover test/unit-tests.js",
|
||||
"appveyor": "npm run all-tests && npm run browser-tests && npm run dynamic-analysis",
|
||||
"benchmark": "node test/benchmarks.js",
|
||||
"benchmark-quick": "node test/benchmarks.js quick",
|
||||
"browser-tests": "npm run generate-fixtures && cd test && karma start --single-run",
|
||||
"check-coverage": "istanbul check-coverage --statement 100 --branch 100 --function 100",
|
||||
"check-version": "node test/check-version.js",
|
||||
"circleci": "npm test && npm run codecov && npm run downstream",
|
||||
"codecov": "istanbul report cobertura && codecov < ./coverage/cobertura-coverage.xml",
|
||||
"complexity": "node test/check-complexity.js",
|
||||
"downstream": "node test/downstream.js",
|
||||
"droneio": "npm test && npm run saucelabs-evergreen && npm run saucelabs-ie && npm run saucelabs-safari",
|
||||
"dynamic-analysis": "npm run analyze-coverage && npm run check-coverage",
|
||||
"eslint": "node node_modules/eslint/bin/eslint.js -c .lintrc esprima.js",
|
||||
"generate-fixtures": "node tools/generate-fixtures.js",
|
||||
"generate-regex": "node tools/generate-identifier-regex.js",
|
||||
"grammar-tests": "node test/grammar-tests.js",
|
||||
"jscs": "jscs -p crockford esprima.js && jscs -p crockford test/*.js",
|
||||
"profile": "node --prof test/profile.js && mv isolate*.log v8.log && node-tick-processor",
|
||||
"regression-tests": "node test/regression-tests.js",
|
||||
"saucelabs-evergreen": "cd test && karma start saucelabs-evergreen.conf.js",
|
||||
"saucelabs-ie": "cd test && karma start saucelabs-ie.conf.js",
|
||||
"saucelabs-safari": "cd test && karma start saucelabs-safari.conf.js",
|
||||
"static-analysis": "npm run check-version && npm run jscs && npm run eslint && npm run complexity",
|
||||
"test": "npm run all-tests && npm run static-analysis && npm run dynamic-analysis",
|
||||
"travis": "npm test",
|
||||
"unit-tests": "node test/unit-tests.js"
|
||||
},
|
||||
"version": "2.7.3"
|
||||
}
|
||||
19
static/js/ketcher2/node_modules/coveralls/node_modules/form-data/License
generated
vendored
Normal file
19
static/js/ketcher2/node_modules/coveralls/node_modules/form-data/License
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
217
static/js/ketcher2/node_modules/coveralls/node_modules/form-data/README.md
generated
vendored
Normal file
217
static/js/ketcher2/node_modules/coveralls/node_modules/form-data/README.md
generated
vendored
Normal file
@ -0,0 +1,217 @@
|
||||
# Form-Data [](https://www.npmjs.com/package/form-data) [](https://gitter.im/form-data/form-data)
|
||||
|
||||
A library to create readable ```"multipart/form-data"``` streams. Can be used to submit forms and file uploads to other web applications.
|
||||
|
||||
The API of this library is inspired by the [XMLHttpRequest-2 FormData Interface][xhr2-fd].
|
||||
|
||||
[xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface
|
||||
|
||||
[](https://travis-ci.org/form-data/form-data)
|
||||
[](https://travis-ci.org/form-data/form-data)
|
||||
[](https://ci.appveyor.com/project/alexindigo/form-data)
|
||||
|
||||
[](https://coveralls.io/github/form-data/form-data?branch=master)
|
||||
[](https://david-dm.org/form-data/form-data)
|
||||
[](https://www.bithound.io/github/form-data/form-data)
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
npm install --save form-data
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
In this example we are constructing a form with 3 fields that contain a string,
|
||||
a buffer and a file stream.
|
||||
|
||||
``` javascript
|
||||
var FormData = require('form-data');
|
||||
var fs = require('fs');
|
||||
|
||||
var form = new FormData();
|
||||
form.append('my_field', 'my value');
|
||||
form.append('my_buffer', new Buffer(10));
|
||||
form.append('my_file', fs.createReadStream('/foo/bar.jpg'));
|
||||
```
|
||||
|
||||
Also you can use http-response stream:
|
||||
|
||||
``` javascript
|
||||
var FormData = require('form-data');
|
||||
var http = require('http');
|
||||
|
||||
var form = new FormData();
|
||||
|
||||
http.request('http://nodejs.org/images/logo.png', function(response) {
|
||||
form.append('my_field', 'my value');
|
||||
form.append('my_buffer', new Buffer(10));
|
||||
form.append('my_logo', response);
|
||||
});
|
||||
```
|
||||
|
||||
Or @mikeal's [request](https://github.com/request/request) stream:
|
||||
|
||||
``` javascript
|
||||
var FormData = require('form-data');
|
||||
var request = require('request');
|
||||
|
||||
var form = new FormData();
|
||||
|
||||
form.append('my_field', 'my value');
|
||||
form.append('my_buffer', new Buffer(10));
|
||||
form.append('my_logo', request('http://nodejs.org/images/logo.png'));
|
||||
```
|
||||
|
||||
In order to submit this form to a web application, call ```submit(url, [callback])``` method:
|
||||
|
||||
``` javascript
|
||||
form.submit('http://example.org/', function(err, res) {
|
||||
// res – response object (http.IncomingMessage) //
|
||||
res.resume();
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
For more advanced request manipulations ```submit()``` method returns ```http.ClientRequest``` object, or you can choose from one of the alternative submission methods.
|
||||
|
||||
### Alternative submission methods
|
||||
|
||||
You can use node's http client interface:
|
||||
|
||||
``` javascript
|
||||
var http = require('http');
|
||||
|
||||
var request = http.request({
|
||||
method: 'post',
|
||||
host: 'example.org',
|
||||
path: '/upload',
|
||||
headers: form.getHeaders()
|
||||
});
|
||||
|
||||
form.pipe(request);
|
||||
|
||||
request.on('response', function(res) {
|
||||
console.log(res.statusCode);
|
||||
});
|
||||
```
|
||||
|
||||
Or if you would prefer the `'Content-Length'` header to be set for you:
|
||||
|
||||
``` javascript
|
||||
form.submit('example.org/upload', function(err, res) {
|
||||
console.log(res.statusCode);
|
||||
});
|
||||
```
|
||||
|
||||
To use custom headers and pre-known length in parts:
|
||||
|
||||
``` javascript
|
||||
var CRLF = '\r\n';
|
||||
var form = new FormData();
|
||||
|
||||
var options = {
|
||||
header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF,
|
||||
knownLength: 1
|
||||
};
|
||||
|
||||
form.append('my_buffer', buffer, options);
|
||||
|
||||
form.submit('http://example.com/', function(err, res) {
|
||||
if (err) throw err;
|
||||
console.log('Done');
|
||||
});
|
||||
```
|
||||
|
||||
Form-Data can recognize and fetch all the required information from common types of streams (```fs.readStream```, ```http.response``` and ```mikeal's request```), for some other types of streams you'd need to provide "file"-related information manually:
|
||||
|
||||
``` javascript
|
||||
someModule.stream(function(err, stdout, stderr) {
|
||||
if (err) throw err;
|
||||
|
||||
var form = new FormData();
|
||||
|
||||
form.append('file', stdout, {
|
||||
filename: 'unicycle.jpg',
|
||||
contentType: 'image/jpg',
|
||||
knownLength: 19806
|
||||
});
|
||||
|
||||
form.submit('http://example.com/', function(err, res) {
|
||||
if (err) throw err;
|
||||
console.log('Done');
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
For edge cases, like POST request to URL with query string or to pass HTTP auth credentials, object can be passed to `form.submit()` as first parameter:
|
||||
|
||||
``` javascript
|
||||
form.submit({
|
||||
host: 'example.com',
|
||||
path: '/probably.php?extra=params',
|
||||
auth: 'username:password'
|
||||
}, function(err, res) {
|
||||
console.log(res.statusCode);
|
||||
});
|
||||
```
|
||||
|
||||
In case you need to also send custom HTTP headers with the POST request, you can use the `headers` key in first parameter of `form.submit()`:
|
||||
|
||||
``` javascript
|
||||
form.submit({
|
||||
host: 'example.com',
|
||||
path: '/surelynot.php',
|
||||
headers: {'x-test-header': 'test-header-value'}
|
||||
}, function(err, res) {
|
||||
console.log(res.statusCode);
|
||||
});
|
||||
```
|
||||
|
||||
### Integration with other libraries
|
||||
|
||||
#### Request
|
||||
|
||||
Form submission using [request](https://github.com/request/request):
|
||||
|
||||
```javascript
|
||||
var formData = {
|
||||
my_field: 'my_value',
|
||||
my_file: fs.createReadStream(__dirname + '/unicycle.jpg'),
|
||||
};
|
||||
|
||||
request.post({url:'http://service.com/upload', formData: formData}, function(err, httpResponse, body) {
|
||||
if (err) {
|
||||
return console.error('upload failed:', err);
|
||||
}
|
||||
console.log('Upload successful! Server responded with:', body);
|
||||
});
|
||||
```
|
||||
|
||||
For more details see [request readme](https://github.com/request/request#multipartform-data-multipart-form-uploads).
|
||||
|
||||
#### node-fetch
|
||||
|
||||
You can also submit a form using [node-fetch](https://github.com/bitinn/node-fetch):
|
||||
|
||||
```javascript
|
||||
var form = new FormData();
|
||||
|
||||
form.append('a', 1);
|
||||
|
||||
fetch('http://example.com', { method: 'POST', body: form })
|
||||
.then(function(res) {
|
||||
return res.json();
|
||||
}).then(function(json) {
|
||||
console.log(json);
|
||||
});
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- ```getLengthSync()``` method DOESN'T calculate length for streams, use ```knownLength``` options as workaround.
|
||||
- Starting version `2.x` FormData has dropped support for `node@0.10.x`.
|
||||
|
||||
## License
|
||||
|
||||
Form-Data is released under the [MIT](License) license.
|
||||
2
static/js/ketcher2/node_modules/coveralls/node_modules/form-data/lib/browser.js
generated
vendored
Normal file
2
static/js/ketcher2/node_modules/coveralls/node_modules/form-data/lib/browser.js
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/* eslint-env browser */
|
||||
module.exports = typeof self == 'object' ? self.FormData : window.FormData;
|
||||
444
static/js/ketcher2/node_modules/coveralls/node_modules/form-data/lib/form_data.js
generated
vendored
Normal file
444
static/js/ketcher2/node_modules/coveralls/node_modules/form-data/lib/form_data.js
generated
vendored
Normal file
@ -0,0 +1,444 @@
|
||||
var CombinedStream = require('combined-stream');
|
||||
var util = require('util');
|
||||
var path = require('path');
|
||||
var http = require('http');
|
||||
var https = require('https');
|
||||
var parseUrl = require('url').parse;
|
||||
var fs = require('fs');
|
||||
var mime = require('mime-types');
|
||||
var asynckit = require('asynckit');
|
||||
var populate = require('./populate.js');
|
||||
|
||||
// Public API
|
||||
module.exports = FormData;
|
||||
|
||||
// make it a Stream
|
||||
util.inherits(FormData, CombinedStream);
|
||||
|
||||
/**
|
||||
* Create readable "multipart/form-data" streams.
|
||||
* Can be used to submit forms
|
||||
* and file uploads to other web applications.
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
function FormData() {
|
||||
if (!(this instanceof FormData)) {
|
||||
return new FormData();
|
||||
}
|
||||
|
||||
this._overheadLength = 0;
|
||||
this._valueLength = 0;
|
||||
this._valuesToMeasure = [];
|
||||
|
||||
CombinedStream.call(this);
|
||||
}
|
||||
|
||||
FormData.LINE_BREAK = '\r\n';
|
||||
FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream';
|
||||
|
||||
FormData.prototype.append = function(field, value, options) {
|
||||
|
||||
options = options || {};
|
||||
|
||||
// allow filename as single option
|
||||
if (typeof options == 'string') {
|
||||
options = {filename: options};
|
||||
}
|
||||
|
||||
var append = CombinedStream.prototype.append.bind(this);
|
||||
|
||||
// all that streamy business can't handle numbers
|
||||
if (typeof value == 'number') {
|
||||
value = '' + value;
|
||||
}
|
||||
|
||||
// https://github.com/felixge/node-form-data/issues/38
|
||||
if (util.isArray(value)) {
|
||||
// Please convert your array into string
|
||||
// the way web server expects it
|
||||
this._error(new Error('Arrays are not supported.'));
|
||||
return;
|
||||
}
|
||||
|
||||
var header = this._multiPartHeader(field, value, options);
|
||||
var footer = this._multiPartFooter();
|
||||
|
||||
append(header);
|
||||
append(value);
|
||||
append(footer);
|
||||
|
||||
// pass along options.knownLength
|
||||
this._trackLength(header, value, options);
|
||||
};
|
||||
|
||||
FormData.prototype._trackLength = function(header, value, options) {
|
||||
var valueLength = 0;
|
||||
|
||||
// used w/ getLengthSync(), when length is known.
|
||||
// e.g. for streaming directly from a remote server,
|
||||
// w/ a known file a size, and not wanting to wait for
|
||||
// incoming file to finish to get its size.
|
||||
if (options.knownLength != null) {
|
||||
valueLength += +options.knownLength;
|
||||
} else if (Buffer.isBuffer(value)) {
|
||||
valueLength = value.length;
|
||||
} else if (typeof value === 'string') {
|
||||
valueLength = Buffer.byteLength(value);
|
||||
}
|
||||
|
||||
this._valueLength += valueLength;
|
||||
|
||||
// @check why add CRLF? does this account for custom/multiple CRLFs?
|
||||
this._overheadLength +=
|
||||
Buffer.byteLength(header) +
|
||||
FormData.LINE_BREAK.length;
|
||||
|
||||
// empty or either doesn't have path or not an http response
|
||||
if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) )) {
|
||||
return;
|
||||
}
|
||||
|
||||
// no need to bother with the length
|
||||
if (!options.knownLength) {
|
||||
this._valuesToMeasure.push(value);
|
||||
}
|
||||
};
|
||||
|
||||
FormData.prototype._lengthRetriever = function(value, callback) {
|
||||
|
||||
if (value.hasOwnProperty('fd')) {
|
||||
|
||||
// take read range into a account
|
||||
// `end` = Infinity –> read file till the end
|
||||
//
|
||||
// TODO: Looks like there is bug in Node fs.createReadStream
|
||||
// it doesn't respect `end` options without `start` options
|
||||
// Fix it when node fixes it.
|
||||
// https://github.com/joyent/node/issues/7819
|
||||
if (value.end != undefined && value.end != Infinity && value.start != undefined) {
|
||||
|
||||
// when end specified
|
||||
// no need to calculate range
|
||||
// inclusive, starts with 0
|
||||
callback(null, value.end + 1 - (value.start ? value.start : 0));
|
||||
|
||||
// not that fast snoopy
|
||||
} else {
|
||||
// still need to fetch file size from fs
|
||||
fs.stat(value.path, function(err, stat) {
|
||||
|
||||
var fileSize;
|
||||
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// update final size based on the range options
|
||||
fileSize = stat.size - (value.start ? value.start : 0);
|
||||
callback(null, fileSize);
|
||||
});
|
||||
}
|
||||
|
||||
// or http response
|
||||
} else if (value.hasOwnProperty('httpVersion')) {
|
||||
callback(null, +value.headers['content-length']);
|
||||
|
||||
// or request stream http://github.com/mikeal/request
|
||||
} else if (value.hasOwnProperty('httpModule')) {
|
||||
// wait till response come back
|
||||
value.on('response', function(response) {
|
||||
value.pause();
|
||||
callback(null, +response.headers['content-length']);
|
||||
});
|
||||
value.resume();
|
||||
|
||||
// something else
|
||||
} else {
|
||||
callback('Unknown stream');
|
||||
}
|
||||
};
|
||||
|
||||
FormData.prototype._multiPartHeader = function(field, value, options) {
|
||||
// custom header specified (as string)?
|
||||
// it becomes responsible for boundary
|
||||
// (e.g. to handle extra CRLFs on .NET servers)
|
||||
if (typeof options.header == 'string') {
|
||||
return options.header;
|
||||
}
|
||||
|
||||
var contentDisposition = this._getContentDisposition(value, options);
|
||||
var contentType = this._getContentType(value, options);
|
||||
|
||||
var contents = '';
|
||||
var headers = {
|
||||
// add custom disposition as third element or keep it two elements if not
|
||||
'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []),
|
||||
// if no content type. allow it to be empty array
|
||||
'Content-Type': [].concat(contentType || [])
|
||||
};
|
||||
|
||||
// allow custom headers.
|
||||
if (typeof options.header == 'object') {
|
||||
populate(headers, options.header);
|
||||
}
|
||||
|
||||
var header;
|
||||
for (var prop in headers) {
|
||||
header = headers[prop];
|
||||
|
||||
// skip nullish headers.
|
||||
if (header == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// convert all headers to arrays.
|
||||
if (!Array.isArray(header)) {
|
||||
header = [header];
|
||||
}
|
||||
|
||||
// add non-empty headers.
|
||||
if (header.length) {
|
||||
contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK;
|
||||
}
|
||||
}
|
||||
|
||||
return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK;
|
||||
};
|
||||
|
||||
FormData.prototype._getContentDisposition = function(value, options) {
|
||||
|
||||
var contentDisposition;
|
||||
|
||||
// custom filename takes precedence
|
||||
// fs- and request- streams have path property
|
||||
// formidable and the browser add a name property.
|
||||
var filename = options.filename || value.name || value.path;
|
||||
|
||||
// or try http response
|
||||
if (!filename && value.readable && value.hasOwnProperty('httpVersion')) {
|
||||
filename = value.client._httpMessage.path;
|
||||
}
|
||||
|
||||
if (filename) {
|
||||
contentDisposition = 'filename="' + path.basename(filename) + '"';
|
||||
}
|
||||
|
||||
return contentDisposition;
|
||||
};
|
||||
|
||||
FormData.prototype._getContentType = function(value, options) {
|
||||
|
||||
// use custom content-type above all
|
||||
var contentType = options.contentType;
|
||||
|
||||
// or try `name` from formidable, browser
|
||||
if (!contentType && value.name) {
|
||||
contentType = mime.lookup(value.name);
|
||||
}
|
||||
|
||||
// or try `path` from fs-, request- streams
|
||||
if (!contentType && value.path) {
|
||||
contentType = mime.lookup(value.path);
|
||||
}
|
||||
|
||||
// or if it's http-reponse
|
||||
if (!contentType && value.readable && value.hasOwnProperty('httpVersion')) {
|
||||
contentType = value.headers['content-type'];
|
||||
}
|
||||
|
||||
// or guess it from the filename
|
||||
if (!contentType && options.filename) {
|
||||
contentType = mime.lookup(options.filename);
|
||||
}
|
||||
|
||||
// fallback to the default content type if `value` is not simple value
|
||||
if (!contentType && typeof value == 'object') {
|
||||
contentType = FormData.DEFAULT_CONTENT_TYPE;
|
||||
}
|
||||
|
||||
return contentType;
|
||||
};
|
||||
|
||||
FormData.prototype._multiPartFooter = function() {
|
||||
return function(next) {
|
||||
var footer = FormData.LINE_BREAK;
|
||||
|
||||
var lastPart = (this._streams.length === 0);
|
||||
if (lastPart) {
|
||||
footer += this._lastBoundary();
|
||||
}
|
||||
|
||||
next(footer);
|
||||
}.bind(this);
|
||||
};
|
||||
|
||||
FormData.prototype._lastBoundary = function() {
|
||||
return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK;
|
||||
};
|
||||
|
||||
FormData.prototype.getHeaders = function(userHeaders) {
|
||||
var header;
|
||||
var formHeaders = {
|
||||
'content-type': 'multipart/form-data; boundary=' + this.getBoundary()
|
||||
};
|
||||
|
||||
for (header in userHeaders) {
|
||||
if (userHeaders.hasOwnProperty(header)) {
|
||||
formHeaders[header.toLowerCase()] = userHeaders[header];
|
||||
}
|
||||
}
|
||||
|
||||
return formHeaders;
|
||||
};
|
||||
|
||||
FormData.prototype.getBoundary = function() {
|
||||
if (!this._boundary) {
|
||||
this._generateBoundary();
|
||||
}
|
||||
|
||||
return this._boundary;
|
||||
};
|
||||
|
||||
FormData.prototype._generateBoundary = function() {
|
||||
// This generates a 50 character boundary similar to those used by Firefox.
|
||||
// They are optimized for boyer-moore parsing.
|
||||
var boundary = '--------------------------';
|
||||
for (var i = 0; i < 24; i++) {
|
||||
boundary += Math.floor(Math.random() * 10).toString(16);
|
||||
}
|
||||
|
||||
this._boundary = boundary;
|
||||
};
|
||||
|
||||
// Note: getLengthSync DOESN'T calculate streams length
|
||||
// As workaround one can calculate file size manually
|
||||
// and add it as knownLength option
|
||||
FormData.prototype.getLengthSync = function() {
|
||||
var knownLength = this._overheadLength + this._valueLength;
|
||||
|
||||
// Don't get confused, there are 3 "internal" streams for each keyval pair
|
||||
// so it basically checks if there is any value added to the form
|
||||
if (this._streams.length) {
|
||||
knownLength += this._lastBoundary().length;
|
||||
}
|
||||
|
||||
// https://github.com/form-data/form-data/issues/40
|
||||
if (!this.hasKnownLength()) {
|
||||
// Some async length retrievers are present
|
||||
// therefore synchronous length calculation is false.
|
||||
// Please use getLength(callback) to get proper length
|
||||
this._error(new Error('Cannot calculate proper length in synchronous way.'));
|
||||
}
|
||||
|
||||
return knownLength;
|
||||
};
|
||||
|
||||
// Public API to check if length of added values is known
|
||||
// https://github.com/form-data/form-data/issues/196
|
||||
// https://github.com/form-data/form-data/issues/262
|
||||
FormData.prototype.hasKnownLength = function() {
|
||||
var hasKnownLength = true;
|
||||
|
||||
if (this._valuesToMeasure.length) {
|
||||
hasKnownLength = false;
|
||||
}
|
||||
|
||||
return hasKnownLength;
|
||||
};
|
||||
|
||||
FormData.prototype.getLength = function(cb) {
|
||||
var knownLength = this._overheadLength + this._valueLength;
|
||||
|
||||
if (this._streams.length) {
|
||||
knownLength += this._lastBoundary().length;
|
||||
}
|
||||
|
||||
if (!this._valuesToMeasure.length) {
|
||||
process.nextTick(cb.bind(this, null, knownLength));
|
||||
return;
|
||||
}
|
||||
|
||||
asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function(err, values) {
|
||||
if (err) {
|
||||
cb(err);
|
||||
return;
|
||||
}
|
||||
|
||||
values.forEach(function(length) {
|
||||
knownLength += length;
|
||||
});
|
||||
|
||||
cb(null, knownLength);
|
||||
});
|
||||
};
|
||||
|
||||
FormData.prototype.submit = function(params, cb) {
|
||||
var request
|
||||
, options
|
||||
, defaults = {method: 'post'}
|
||||
;
|
||||
|
||||
// parse provided url if it's string
|
||||
// or treat it as options object
|
||||
if (typeof params == 'string') {
|
||||
|
||||
params = parseUrl(params);
|
||||
options = populate({
|
||||
port: params.port,
|
||||
path: params.pathname,
|
||||
host: params.hostname
|
||||
}, defaults);
|
||||
|
||||
// use custom params
|
||||
} else {
|
||||
|
||||
options = populate(params, defaults);
|
||||
// if no port provided use default one
|
||||
if (!options.port) {
|
||||
options.port = options.protocol == 'https:' ? 443 : 80;
|
||||
}
|
||||
}
|
||||
|
||||
// put that good code in getHeaders to some use
|
||||
options.headers = this.getHeaders(params.headers);
|
||||
|
||||
// https if specified, fallback to http in any other case
|
||||
if (options.protocol == 'https:') {
|
||||
request = https.request(options);
|
||||
} else {
|
||||
request = http.request(options);
|
||||
}
|
||||
|
||||
// get content length and fire away
|
||||
this.getLength(function(err, length) {
|
||||
if (err) {
|
||||
this._error(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// add content length
|
||||
request.setHeader('Content-Length', length);
|
||||
|
||||
this.pipe(request);
|
||||
if (cb) {
|
||||
request.on('error', cb);
|
||||
request.on('response', cb.bind(this, null));
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
return request;
|
||||
};
|
||||
|
||||
FormData.prototype._error = function(err) {
|
||||
if (!this.error) {
|
||||
this.error = err;
|
||||
this.pause();
|
||||
this.emit('error', err);
|
||||
}
|
||||
};
|
||||
|
||||
FormData.prototype.toString = function () {
|
||||
return '[object FormData]';
|
||||
};
|
||||
10
static/js/ketcher2/node_modules/coveralls/node_modules/form-data/lib/populate.js
generated
vendored
Normal file
10
static/js/ketcher2/node_modules/coveralls/node_modules/form-data/lib/populate.js
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
// populates missing values
|
||||
module.exports = function(dst, src) {
|
||||
|
||||
Object.keys(src).forEach(function(prop)
|
||||
{
|
||||
dst[prop] = dst[prop] || src[prop];
|
||||
});
|
||||
|
||||
return dst;
|
||||
};
|
||||
98
static/js/ketcher2/node_modules/coveralls/node_modules/form-data/package.json
generated
vendored
Normal file
98
static/js/ketcher2/node_modules/coveralls/node_modules/form-data/package.json
generated
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
{
|
||||
"_from": "form-data@~2.1.1",
|
||||
"_id": "form-data@2.1.4",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
|
||||
"_location": "/coveralls/form-data",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "form-data@~2.1.1",
|
||||
"name": "form-data",
|
||||
"escapedName": "form-data",
|
||||
"rawSpec": "~2.1.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "~2.1.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/coveralls/request"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
|
||||
"_shasum": "33c183acf193276ecaa98143a69e94bfee1750d1",
|
||||
"_spec": "form-data@~2.1.1",
|
||||
"_where": "/home/manfred/enviPath/ketcher2/ketcher/node_modules/coveralls/node_modules/request",
|
||||
"author": {
|
||||
"name": "Felix Geisendörfer",
|
||||
"email": "felix@debuggable.com",
|
||||
"url": "http://debuggable.com/"
|
||||
},
|
||||
"browser": "./lib/browser",
|
||||
"bugs": {
|
||||
"url": "https://github.com/form-data/form-data/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.5",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "A library to create readable \"multipart/form-data\" streams. Can be used to submit forms and file uploads to other web applications.",
|
||||
"devDependencies": {
|
||||
"browserify": "^13.1.1",
|
||||
"browserify-istanbul": "^2.0.0",
|
||||
"coveralls": "^2.11.14",
|
||||
"cross-spawn": "^4.0.2",
|
||||
"eslint": "^3.9.1",
|
||||
"fake": "^0.2.2",
|
||||
"far": "^0.0.7",
|
||||
"formidable": "^1.0.17",
|
||||
"in-publish": "^2.0.0",
|
||||
"is-node-modern": "^1.0.0",
|
||||
"istanbul": "^0.4.5",
|
||||
"obake": "^0.1.2",
|
||||
"phantomjs-prebuilt": "^2.1.13",
|
||||
"pkgfiles": "^2.3.0",
|
||||
"pre-commit": "^1.1.3",
|
||||
"request": "2.76.0",
|
||||
"rimraf": "^2.5.4",
|
||||
"tape": "^4.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.12"
|
||||
},
|
||||
"homepage": "https://github.com/form-data/form-data#readme",
|
||||
"license": "MIT",
|
||||
"main": "./lib/form_data",
|
||||
"name": "form-data",
|
||||
"pre-commit": [
|
||||
"lint",
|
||||
"ci-test",
|
||||
"check"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/form-data/form-data.git"
|
||||
},
|
||||
"scripts": {
|
||||
"browser": "browserify -t browserify-istanbul test/run-browser.js | obake --coverage",
|
||||
"check": "istanbul check-coverage coverage/coverage*.json",
|
||||
"ci-lint": "is-node-modern 6 && npm run lint || is-node-not-modern 6",
|
||||
"ci-test": "npm run test && npm run browser && npm run report",
|
||||
"debug": "verbose=1 ./test/run.js",
|
||||
"files": "pkgfiles --sort=name",
|
||||
"get-version": "node -e \"console.log(require('./package.json').version)\"",
|
||||
"lint": "eslint lib/*.js test/*.js test/integration/*.js",
|
||||
"postpublish": "npm run restore-readme",
|
||||
"posttest": "istanbul report lcov text",
|
||||
"predebug": "rimraf coverage test/tmp",
|
||||
"prepublish": "in-publish && npm run update-readme || not-in-publish",
|
||||
"pretest": "rimraf coverage test/tmp",
|
||||
"report": "istanbul report lcov text",
|
||||
"restore-readme": "mv README.md.bak README.md",
|
||||
"test": "istanbul cover test/run.js",
|
||||
"update-readme": "sed -i.bak 's/\\/master\\.svg/\\/v'$(npm --silent run get-version)'.svg/g' README.md"
|
||||
},
|
||||
"version": "2.1.4"
|
||||
}
|
||||
13
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/LICENSE
generated
vendored
Normal file
13
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/LICENSE
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
Copyright (c) 2015, Ahmad Nassri <ahmad@ahmadnassri.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
309
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/README.md
generated
vendored
Normal file
309
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/README.md
generated
vendored
Normal file
@ -0,0 +1,309 @@
|
||||
# HAR Validator [![version][npm-version]][npm-url] [![License][npm-license]][license-url]
|
||||
|
||||
Extremely fast HTTP Archive ([HAR](http://www.softwareishard.com/blog/har-12-spec/)) validator using JSON Schema.
|
||||
|
||||
[![Build Status][travis-image]][travis-url]
|
||||
[![Downloads][npm-downloads]][npm-url]
|
||||
[![Code Climate][codeclimate-quality]][codeclimate-url]
|
||||
[![Coverage Status][codeclimate-coverage]][codeclimate-url]
|
||||
[![Dependencies][david-image]][david-url]
|
||||
|
||||
## Install
|
||||
|
||||
```shell
|
||||
# to use in cli
|
||||
npm install --global har-validator
|
||||
|
||||
# to use as a module
|
||||
npm install --save har-validator
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
|
||||
Usage: har-validator [options] <files ...>
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help output usage information
|
||||
-V, --version output the version number
|
||||
-s, --schema [name] validate schema name (log, request, response, etc ...)
|
||||
|
||||
```
|
||||
|
||||
###### Example
|
||||
|
||||
```shell
|
||||
har-validator har.json
|
||||
|
||||
har-validator --schema request request.json
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
**Note**: as of [`v2.0.0`](https://github.com/ahmadnassri/har-validator/releases/tag/v2.0.0) this module defaults to Promise based API. *For backward comptability with `v1.x` an [async/callback API](#callback-api) is provided*
|
||||
|
||||
### Validate(data)
|
||||
|
||||
> Returns a promise that resolves to the valid object.
|
||||
|
||||
- **data**: `Object` *(Required)*
|
||||
a full [HAR](http://www.softwareishard.com/blog/har-12-spec/) object
|
||||
|
||||
```js
|
||||
validate(data)
|
||||
.then(data => console.log('horray!'))
|
||||
.catch(console.error)
|
||||
```
|
||||
|
||||
### Validate.log(data)
|
||||
|
||||
> Returns a promise that resolves to the valid object.
|
||||
|
||||
- **data**: `Object` *(Required)*
|
||||
a [log](http://www.softwareishard.com/blog/har-12-spec/#log) object
|
||||
|
||||
```js
|
||||
validate.log(data)
|
||||
.then(data => console.log('horray!'))
|
||||
.catch(console.error)
|
||||
```
|
||||
|
||||
### Validate.cache(data)
|
||||
|
||||
> Returns a promise that resolves to the valid object.
|
||||
|
||||
- **data**: `Object` *(Required)*
|
||||
a [cache](http://www.softwareishard.com/blog/har-12-spec/#cache) object
|
||||
|
||||
```js
|
||||
validate.cache(data)
|
||||
.then(data => console.log('horray!'))
|
||||
.catch(console.error)
|
||||
```
|
||||
|
||||
### Validate.cacheEntry(data)
|
||||
|
||||
> Returns a promise that resolves to the valid object.
|
||||
|
||||
- **data**: `Object` *(Required)*
|
||||
a ["beforeRequest" or "afterRequest"](http://www.softwareishard.com/blog/har-12-spec/#cache) objects
|
||||
|
||||
```js
|
||||
validate.cacheEntry(data)
|
||||
.then(data => console.log('horray!'))
|
||||
.catch(console.error)
|
||||
```
|
||||
|
||||
### Validate.content(data)
|
||||
|
||||
> Returns a promise that resolves to the valid object.
|
||||
|
||||
- **data**: `Object` *(Required)*
|
||||
a [content](http://www.softwareishard.com/blog/har-12-spec/#content) object
|
||||
|
||||
```js
|
||||
validate.content(data)
|
||||
.then(data => console.log('horray!'))
|
||||
.catch(console.error)
|
||||
```
|
||||
|
||||
### Validate.cookie(data)
|
||||
|
||||
> Returns a promise that resolves to the valid object.
|
||||
|
||||
- **data**: `Object` *(Required)*
|
||||
a [cookie](http://www.softwareishard.com/blog/har-12-spec/#cookies) object
|
||||
|
||||
```js
|
||||
validate.cookie(data)
|
||||
.then(data => console.log('horray!'))
|
||||
.catch(console.error)
|
||||
```
|
||||
|
||||
### Validate.creator(data)
|
||||
|
||||
> Returns a promise that resolves to the valid object.
|
||||
|
||||
- **data**: `Object` *(Required)*
|
||||
a [creator](http://www.softwareishard.com/blog/har-12-spec/#creator) object
|
||||
|
||||
```js
|
||||
validate.creator(data)
|
||||
.then(data => console.log('horray!'))
|
||||
.catch(console.error)
|
||||
```
|
||||
|
||||
### Validate.entry(data)
|
||||
|
||||
> Returns a promise that resolves to the valid object.
|
||||
|
||||
- **data**: `Object` *(Required)*
|
||||
an [entry](http://www.softwareishard.com/blog/har-12-spec/#entries) object
|
||||
|
||||
```js
|
||||
validate.entry(data)
|
||||
.then(data => console.log('horray!'))
|
||||
.catch(console.error)
|
||||
```
|
||||
|
||||
### Validate.log(data)
|
||||
|
||||
alias of [`Validate(data)`](#validate-data-callback-)
|
||||
|
||||
### Validate.page(data)
|
||||
|
||||
> Returns a promise that resolves to the valid object.
|
||||
|
||||
- **data**: `Object` *(Required)*
|
||||
a [page](http://www.softwareishard.com/blog/har-12-spec/#pages) object
|
||||
|
||||
```js
|
||||
validate.page(data)
|
||||
.then(data => console.log('horray!'))
|
||||
.catch(console.error)
|
||||
```
|
||||
|
||||
### Validate.pageTimings(data)
|
||||
|
||||
> Returns a promise that resolves to the valid object.
|
||||
|
||||
- **data**: `Object` *(Required)*
|
||||
a [pageTimings](http://www.softwareishard.com/blog/har-12-spec/#pageTimings) object
|
||||
|
||||
```js
|
||||
validate.pageTimings(data)
|
||||
.then(data => console.log('horray!'))
|
||||
.catch(console.error)
|
||||
```
|
||||
|
||||
### Validate.postData(data)
|
||||
|
||||
> Returns a promise that resolves to the valid object.
|
||||
|
||||
- **data**: `Object` *(Required)*
|
||||
a [postData](http://www.softwareishard.com/blog/har-12-spec/#postData) object
|
||||
|
||||
```js
|
||||
validate.postData(data)
|
||||
.then(data => console.log('horray!'))
|
||||
.catch(console.error)
|
||||
```
|
||||
|
||||
### Validate.record(data)
|
||||
|
||||
> Returns a promise that resolves to the valid object.
|
||||
|
||||
- **data**: `Object` *(Required)*
|
||||
a [record](http://www.softwareishard.com/blog/har-12-spec/#headers) object
|
||||
|
||||
```js
|
||||
validate.record(data)
|
||||
.then(data => console.log('horray!'))
|
||||
.catch(console.error)
|
||||
```
|
||||
|
||||
### Validate.request(data)
|
||||
|
||||
> Returns a promise that resolves to the valid object.
|
||||
|
||||
- **data**: `Object` *(Required)*
|
||||
a [request](http://www.softwareishard.com/blog/har-12-spec/#request) object
|
||||
|
||||
```js
|
||||
validate.request(data)
|
||||
.then(data => console.log('horray!'))
|
||||
.catch(console.error)
|
||||
```
|
||||
|
||||
### Validate.response(data)
|
||||
|
||||
> Returns a promise that resolves to the valid object.
|
||||
|
||||
- **data**: `Object` *(Required)*
|
||||
a [response](http://www.softwareishard.com/blog/har-12-spec/#response) object
|
||||
|
||||
```js
|
||||
validate.cacheEntry(data)
|
||||
.then(data => console.log('horray!'))
|
||||
.catch(console.error)
|
||||
```
|
||||
|
||||
### Validate.timings(data)
|
||||
|
||||
> Returns a promise that resolves to the valid object.
|
||||
|
||||
- **data**: `Object` *(Required)*
|
||||
a [timings](http://www.softwareishard.com/blog/har-12-spec/#timings) object
|
||||
|
||||
```js
|
||||
validate.timings(data)
|
||||
.then(data => console.log('horray!'))
|
||||
.catch(console.error)
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
## Callback API
|
||||
|
||||
### Validate(data [, callback])
|
||||
|
||||
> Returns `true` or `false`.
|
||||
|
||||
```js
|
||||
var HAR = require('./har.json');
|
||||
var validate = require('har-validator/lib/async');
|
||||
|
||||
validate(HAR, function (e, valid) {
|
||||
if (e) console.log(e.errors)
|
||||
|
||||
if (valid) console.log('horray!');
|
||||
});
|
||||
|
||||
```
|
||||
The async API provides exactly the same methods as the [Promise API](#promise-api)
|
||||
|
||||
----
|
||||
|
||||
## Support
|
||||
|
||||
Donations are welcome to help support the continuous development of this project.
|
||||
|
||||
[![Gratipay][gratipay-image]][gratipay-url]
|
||||
[![PayPal][paypal-image]][paypal-url]
|
||||
[![Flattr][flattr-image]][flattr-url]
|
||||
[![Bitcoin][bitcoin-image]][bitcoin-url]
|
||||
|
||||
## License
|
||||
|
||||
[ISC License](LICENSE) © [Ahmad Nassri](https://www.ahmadnassri.com/)
|
||||
|
||||
[license-url]: https://github.com/ahmadnassri/har-validator/blob/master/LICENSE
|
||||
|
||||
[travis-url]: https://travis-ci.org/ahmadnassri/har-validator
|
||||
[travis-image]: https://img.shields.io/travis/ahmadnassri/har-validator.svg?style=flat-square
|
||||
|
||||
[npm-url]: https://www.npmjs.com/package/har-validator
|
||||
[npm-license]: https://img.shields.io/npm/l/har-validator.svg?style=flat-square
|
||||
[npm-version]: https://img.shields.io/npm/v/har-validator.svg?style=flat-square
|
||||
[npm-downloads]: https://img.shields.io/npm/dm/har-validator.svg?style=flat-square
|
||||
|
||||
[codeclimate-url]: https://codeclimate.com/github/ahmadnassri/har-validator
|
||||
[codeclimate-quality]: https://img.shields.io/codeclimate/github/ahmadnassri/har-validator.svg?style=flat-square
|
||||
[codeclimate-coverage]: https://img.shields.io/codeclimate/coverage/github/ahmadnassri/har-validator.svg?style=flat-square
|
||||
|
||||
[david-url]: https://david-dm.org/ahmadnassri/har-validator
|
||||
[david-image]: https://img.shields.io/david/ahmadnassri/har-validator.svg?style=flat-square
|
||||
|
||||
[gratipay-url]: https://www.gratipay.com/ahmadnassri/
|
||||
[gratipay-image]: https://img.shields.io/gratipay/ahmadnassri.svg?style=flat-square
|
||||
|
||||
[paypal-url]: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UJ2B2BTK9VLRS&on0=project&os0=har-validator
|
||||
[paypal-image]: http://img.shields.io/badge/paypal-donate-green.svg?style=flat-square
|
||||
|
||||
[flattr-url]: https://flattr.com/submit/auto?user_id=ahmadnassri&url=https://github.com/ahmadnassri/har-validator&title=har-validator&language=&tags=github&category=software
|
||||
[flattr-image]: http://img.shields.io/badge/flattr-donate-green.svg?style=flat-square
|
||||
|
||||
[bitcoin-image]: http://img.shields.io/badge/bitcoin-1Nb46sZRVG3or7pNaDjthcGJpWhvoPpCxy-green.svg?style=flat-square
|
||||
[bitcoin-url]: https://www.coinbase.com/checkouts/ae383ae6bb931a2fa5ad11cec115191e?name=har-validator
|
||||
56
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/bin/har-validator
generated
vendored
Executable file
56
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/bin/har-validator
generated
vendored
Executable file
@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict'
|
||||
|
||||
var chalk = require('chalk')
|
||||
var cmd = require('commander')
|
||||
var fs = require('fs')
|
||||
var path = require('path')
|
||||
var pkg = require('../package.json')
|
||||
var Promise = require('pinkie-promise')
|
||||
var validate = require('..')
|
||||
var ValidationError = require('../lib/error')
|
||||
|
||||
cmd
|
||||
.version(pkg.version)
|
||||
.usage('[options] <files ...>')
|
||||
.option('-s, --schema [name]', 'validate schema name (log, request, response, etc ...)')
|
||||
.parse(process.argv)
|
||||
|
||||
if (!cmd.args.length) {
|
||||
cmd.help()
|
||||
}
|
||||
|
||||
cmd.args.map(function (fileName) {
|
||||
var file = chalk.yellow.italic(path.basename(fileName))
|
||||
|
||||
new Promise(function (resolve, reject) {
|
||||
fs.readFile(fileName, function (err, data) {
|
||||
return err === null ? resolve(data) : reject(err)
|
||||
})
|
||||
})
|
||||
|
||||
.then(JSON.parse)
|
||||
|
||||
.then(cmd.schema ? validate[cmd.schema] : validate)
|
||||
|
||||
.then(function (data) {
|
||||
console.log('%s [%s] is valid', chalk.green('✓'), file)
|
||||
})
|
||||
|
||||
.catch(function (err) {
|
||||
if (err instanceof SyntaxError) {
|
||||
return console.error('%s [%s] failed to read JSON: %s', chalk.red('✖'), file, chalk.red(err.message))
|
||||
}
|
||||
|
||||
if (err instanceof ValidationError) {
|
||||
err.errors.forEach(function (details) {
|
||||
console.error('%s [%s] failed validation: (%s: %s) %s', chalk.red('✖'), file, chalk.cyan.italic(details.field), chalk.magenta.italic(details.value), chalk.red(details.message))
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
console.error('%s [%s] an unknown error has occured: %s', chalk.red('✖'), file, chalk.red(err.message))
|
||||
})
|
||||
})
|
||||
14
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/async.js
generated
vendored
Normal file
14
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/async.js
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
'use strict'
|
||||
|
||||
var runner = require('./runner')
|
||||
var schemas = require('./schemas')
|
||||
|
||||
module.exports = function (data, cb) {
|
||||
return runner(schemas.har, data, cb)
|
||||
}
|
||||
|
||||
Object.keys(schemas).map(function (name) {
|
||||
module.exports[name] = function (data, cb) {
|
||||
return runner(schemas[name], data, cb)
|
||||
}
|
||||
})
|
||||
10
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/error.js
generated
vendored
Normal file
10
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/error.js
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
'use strict'
|
||||
|
||||
function ValidationError (errors) {
|
||||
this.name = 'ValidationError'
|
||||
this.errors = errors
|
||||
}
|
||||
|
||||
ValidationError.prototype = Error.prototype
|
||||
|
||||
module.exports = ValidationError
|
||||
22
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/index.js
generated
vendored
Normal file
22
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/index.js
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
'use strict'
|
||||
|
||||
var Promise = require('pinkie-promise')
|
||||
var runner = require('./runner')
|
||||
var schemas = require('./schemas')
|
||||
|
||||
var promisify = function (schema) {
|
||||
return function (data) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
runner(schema, data, function (err, valid) {
|
||||
return err === null ? resolve(data) : reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = promisify(schemas.har)
|
||||
|
||||
// utility methods for all parts of the schema
|
||||
Object.keys(schemas).map(function (name) {
|
||||
module.exports[name] = promisify(schemas[name])
|
||||
})
|
||||
29
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/runner.js
generated
vendored
Normal file
29
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/runner.js
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
'use strict'
|
||||
|
||||
var schemas = require('./schemas')
|
||||
var ValidationError = require('./error')
|
||||
var validator = require('is-my-json-valid')
|
||||
|
||||
module.exports = function (schema, data, cb) {
|
||||
// default value
|
||||
var valid = false
|
||||
|
||||
// validator config
|
||||
var validate = validator(schema, {
|
||||
greedy: true,
|
||||
verbose: true,
|
||||
schemas: schemas
|
||||
})
|
||||
|
||||
// execute is-my-json-valid
|
||||
if (data !== undefined) {
|
||||
valid = validate(data)
|
||||
}
|
||||
|
||||
// callback?
|
||||
if (typeof cb === 'function') {
|
||||
return cb(validate.errors ? new ValidationError(validate.errors) : null, valid)
|
||||
}
|
||||
|
||||
return valid
|
||||
}
|
||||
13
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/cache.json
generated
vendored
Normal file
13
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/cache.json
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"properties": {
|
||||
"beforeRequest": {
|
||||
"$ref": "#cacheEntry"
|
||||
},
|
||||
"afterRequest": {
|
||||
"$ref": "#cacheEntry"
|
||||
},
|
||||
"comment": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
31
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/cacheEntry.json
generated
vendored
Normal file
31
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/cacheEntry.json
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"oneOf": [{
|
||||
"type": "object",
|
||||
"optional": true,
|
||||
"required": [
|
||||
"lastAccess",
|
||||
"eTag",
|
||||
"hitCount"
|
||||
],
|
||||
"properties": {
|
||||
"expires": {
|
||||
"type": "string"
|
||||
},
|
||||
"lastAccess": {
|
||||
"type": "string"
|
||||
},
|
||||
"eTag": {
|
||||
"type": "string"
|
||||
},
|
||||
"hitCount": {
|
||||
"type": "integer"
|
||||
},
|
||||
"comment": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"type": null,
|
||||
"additionalProperties": false
|
||||
}]
|
||||
}
|
||||
27
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/content.json
generated
vendored
Normal file
27
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/content.json
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"size",
|
||||
"mimeType"
|
||||
],
|
||||
"properties": {
|
||||
"size": {
|
||||
"type": "integer"
|
||||
},
|
||||
"compression": {
|
||||
"type": "integer"
|
||||
},
|
||||
"mimeType": {
|
||||
"type": "string"
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"encoding": {
|
||||
"type": "string"
|
||||
},
|
||||
"comment": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
34
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/cookie.json
generated
vendored
Normal file
34
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/cookie.json
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"domain": {
|
||||
"type": "string"
|
||||
},
|
||||
"expires": {
|
||||
"type": ["string", "null"],
|
||||
"format": "date-time"
|
||||
},
|
||||
"httpOnly": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"secure": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"comment": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
18
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/creator.json
generated
vendored
Normal file
18
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/creator.json
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
},
|
||||
"comment": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
51
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/entry.json
generated
vendored
Normal file
51
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/entry.json
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
{
|
||||
"type": "object",
|
||||
"optional": true,
|
||||
"required": [
|
||||
"startedDateTime",
|
||||
"time",
|
||||
"request",
|
||||
"response",
|
||||
"cache",
|
||||
"timings"
|
||||
],
|
||||
"properties": {
|
||||
"pageref": {
|
||||
"type": "string"
|
||||
},
|
||||
"startedDateTime": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"pattern": "^(\\d{4})(-)?(\\d\\d)(-)?(\\d\\d)(T)?(\\d\\d)(:)?(\\d\\d)(:)?(\\d\\d)(\\.\\d+)?(Z|([+-])(\\d\\d)(:)?(\\d\\d))"
|
||||
},
|
||||
"time": {
|
||||
"type": "number",
|
||||
"min": 0
|
||||
},
|
||||
"request": {
|
||||
"$ref": "#request"
|
||||
},
|
||||
"response": {
|
||||
"$ref": "#response"
|
||||
},
|
||||
"cache": {
|
||||
"$ref": "#cache"
|
||||
},
|
||||
"timings": {
|
||||
"$ref": "#timings"
|
||||
},
|
||||
"serverIPAddress": {
|
||||
"type": "string",
|
||||
"oneOf": [
|
||||
{ "format": "ipv4" },
|
||||
{ "format": "ipv6" }
|
||||
]
|
||||
},
|
||||
"connection": {
|
||||
"type": "string"
|
||||
},
|
||||
"comment": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
11
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/har.json
generated
vendored
Normal file
11
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/har.json
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"log"
|
||||
],
|
||||
"properties": {
|
||||
"log": {
|
||||
"$ref": "#log"
|
||||
}
|
||||
}
|
||||
}
|
||||
49
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/index.js
generated
vendored
Normal file
49
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/index.js
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
'use strict'
|
||||
|
||||
var schemas = {
|
||||
cache: require('./cache.json'),
|
||||
cacheEntry: require('./cacheEntry.json'),
|
||||
content: require('./content.json'),
|
||||
cookie: require('./cookie.json'),
|
||||
creator: require('./creator.json'),
|
||||
entry: require('./entry.json'),
|
||||
har: require('./har.json'),
|
||||
log: require('./log.json'),
|
||||
page: require('./page.json'),
|
||||
pageTimings: require('./pageTimings.json'),
|
||||
postData: require('./postData.json'),
|
||||
record: require('./record.json'),
|
||||
request: require('./request.json'),
|
||||
response: require('./response.json'),
|
||||
timings: require('./timings.json')
|
||||
}
|
||||
|
||||
// is-my-json-valid does not provide meaningful error messages for external schemas
|
||||
// this is a workaround
|
||||
schemas.cache.properties.beforeRequest = schemas.cacheEntry
|
||||
schemas.cache.properties.afterRequest = schemas.cacheEntry
|
||||
|
||||
schemas.page.properties.pageTimings = schemas.pageTimings
|
||||
|
||||
schemas.request.properties.cookies.items = schemas.cookie
|
||||
schemas.request.properties.headers.items = schemas.record
|
||||
schemas.request.properties.queryString.items = schemas.record
|
||||
schemas.request.properties.postData = schemas.postData
|
||||
|
||||
schemas.response.properties.cookies.items = schemas.cookie
|
||||
schemas.response.properties.headers.items = schemas.record
|
||||
schemas.response.properties.content = schemas.content
|
||||
|
||||
schemas.entry.properties.request = schemas.request
|
||||
schemas.entry.properties.response = schemas.response
|
||||
schemas.entry.properties.cache = schemas.cache
|
||||
schemas.entry.properties.timings = schemas.timings
|
||||
|
||||
schemas.log.properties.creator = schemas.creator
|
||||
schemas.log.properties.browser = schemas.creator
|
||||
schemas.log.properties.pages.items = schemas.page
|
||||
schemas.log.properties.entries.items = schemas.entry
|
||||
|
||||
schemas.har.properties.log = schemas.log
|
||||
|
||||
module.exports = schemas
|
||||
34
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/log.json
generated
vendored
Normal file
34
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/log.json
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"version",
|
||||
"creator",
|
||||
"entries"
|
||||
],
|
||||
"properties": {
|
||||
"version": {
|
||||
"type": "string"
|
||||
},
|
||||
"creator": {
|
||||
"$ref": "#creator"
|
||||
},
|
||||
"browser": {
|
||||
"$ref": "#creator"
|
||||
},
|
||||
"pages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#page"
|
||||
}
|
||||
},
|
||||
"entries": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#entry"
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
30
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/page.json
generated
vendored
Normal file
30
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/page.json
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"type": "object",
|
||||
"optional": true,
|
||||
"required": [
|
||||
"startedDateTime",
|
||||
"id",
|
||||
"title",
|
||||
"pageTimings"
|
||||
],
|
||||
"properties": {
|
||||
"startedDateTime": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"pattern": "^(\\d{4})(-)?(\\d\\d)(-)?(\\d\\d)(T)?(\\d\\d)(:)?(\\d\\d)(:)?(\\d\\d)(\\.\\d+)?(Z|([+-])(\\d\\d)(:)?(\\d\\d))"
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"unique": true
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"pageTimings": {
|
||||
"$ref": "#pageTimings"
|
||||
},
|
||||
"comment": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
16
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/pageTimings.json
generated
vendored
Normal file
16
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/pageTimings.json
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"onContentLoad": {
|
||||
"type": "number",
|
||||
"min": -1
|
||||
},
|
||||
"onLoad": {
|
||||
"type": "number",
|
||||
"min": -1
|
||||
},
|
||||
"comment": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
41
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/postData.json
generated
vendored
Normal file
41
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/postData.json
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"type": "object",
|
||||
"optional": true,
|
||||
"required": [
|
||||
"mimeType"
|
||||
],
|
||||
"properties": {
|
||||
"mimeType": {
|
||||
"type": "string"
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"type": "array",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"fileName": {
|
||||
"type": "string"
|
||||
},
|
||||
"contentType": {
|
||||
"type": "string"
|
||||
},
|
||||
"comment": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"comment": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
18
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/record.json
generated
vendored
Normal file
18
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/record.json
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"comment": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
55
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/request.json
generated
vendored
Normal file
55
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/request.json
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"method",
|
||||
"url",
|
||||
"httpVersion",
|
||||
"cookies",
|
||||
"headers",
|
||||
"queryString",
|
||||
"headersSize",
|
||||
"bodySize"
|
||||
],
|
||||
"properties": {
|
||||
"method": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"httpVersion": {
|
||||
"type": "string"
|
||||
},
|
||||
"cookies": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#cookie"
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#record"
|
||||
}
|
||||
},
|
||||
"queryString": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#record"
|
||||
}
|
||||
},
|
||||
"postData": {
|
||||
"$ref": "#postData"
|
||||
},
|
||||
"headersSize": {
|
||||
"type": "integer"
|
||||
},
|
||||
"bodySize": {
|
||||
"type": "integer"
|
||||
},
|
||||
"comment": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
52
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/response.json
generated
vendored
Normal file
52
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/response.json
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"status",
|
||||
"statusText",
|
||||
"httpVersion",
|
||||
"cookies",
|
||||
"headers",
|
||||
"content",
|
||||
"redirectURL",
|
||||
"headersSize",
|
||||
"bodySize"
|
||||
],
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "integer"
|
||||
},
|
||||
"statusText": {
|
||||
"type": "string"
|
||||
},
|
||||
"httpVersion": {
|
||||
"type": "string"
|
||||
},
|
||||
"cookies": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#cookie"
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#record"
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"$ref": "#content"
|
||||
},
|
||||
"redirectURL": {
|
||||
"type": "string"
|
||||
},
|
||||
"headersSize": {
|
||||
"type": "integer"
|
||||
},
|
||||
"bodySize": {
|
||||
"type": "integer"
|
||||
},
|
||||
"comment": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
40
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/timings.json
generated
vendored
Normal file
40
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/lib/schemas/timings.json
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"required": [
|
||||
"send",
|
||||
"wait",
|
||||
"receive"
|
||||
],
|
||||
"properties": {
|
||||
"dns": {
|
||||
"type": "number",
|
||||
"min": -1
|
||||
},
|
||||
"connect": {
|
||||
"type": "number",
|
||||
"min": -1
|
||||
},
|
||||
"blocked": {
|
||||
"type": "number",
|
||||
"min": -1
|
||||
},
|
||||
"send": {
|
||||
"type": "number",
|
||||
"min": -1
|
||||
},
|
||||
"wait": {
|
||||
"type": "number",
|
||||
"min": -1
|
||||
},
|
||||
"receive": {
|
||||
"type": "number",
|
||||
"min": -1
|
||||
},
|
||||
"ssl": {
|
||||
"type": "number",
|
||||
"min": -1
|
||||
},
|
||||
"comment": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
89
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/package.json
generated
vendored
Normal file
89
static/js/ketcher2/node_modules/coveralls/node_modules/har-validator/package.json
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
{
|
||||
"_from": "har-validator@~2.0.6",
|
||||
"_id": "har-validator@2.0.6",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
|
||||
"_location": "/coveralls/har-validator",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "har-validator@~2.0.6",
|
||||
"name": "har-validator",
|
||||
"escapedName": "har-validator",
|
||||
"rawSpec": "~2.0.6",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "~2.0.6"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/coveralls/request"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
|
||||
"_shasum": "cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d",
|
||||
"_spec": "har-validator@~2.0.6",
|
||||
"_where": "/home/manfred/enviPath/ketcher2/ketcher/node_modules/coveralls/node_modules/request",
|
||||
"author": {
|
||||
"name": "Ahmad Nassri",
|
||||
"email": "ahmad@ahmadnassri.com",
|
||||
"url": "https://www.ahmadnassri.com/"
|
||||
},
|
||||
"bin": {
|
||||
"har-validator": "bin/har-validator"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/ahmadnassri/har-validator/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"chalk": "^1.1.1",
|
||||
"commander": "^2.9.0",
|
||||
"is-my-json-valid": "^2.12.4",
|
||||
"pinkie-promise": "^2.0.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Extremely fast HTTP Archive (HAR) validator using JSON Schema",
|
||||
"devDependencies": {
|
||||
"codeclimate-test-reporter": "0.2.1",
|
||||
"echint": "^1.5.1",
|
||||
"istanbul": "^0.4.2",
|
||||
"mocha": "^2.3.4",
|
||||
"require-directory": "^2.1.1",
|
||||
"should": "^8.1.1",
|
||||
"standard": "^5.4.1"
|
||||
},
|
||||
"echint": {
|
||||
"ignore": [
|
||||
"coverage/**"
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
},
|
||||
"files": [
|
||||
"bin",
|
||||
"lib"
|
||||
],
|
||||
"homepage": "https://github.com/ahmadnassri/har-validator",
|
||||
"keywords": [
|
||||
"har",
|
||||
"http",
|
||||
"archive",
|
||||
"validate",
|
||||
"validator"
|
||||
],
|
||||
"license": "ISC",
|
||||
"main": "lib/index",
|
||||
"name": "har-validator",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/ahmadnassri/har-validator.git"
|
||||
},
|
||||
"scripts": {
|
||||
"codeclimate": "codeclimate < coverage/lcov.info",
|
||||
"coverage": "istanbul cover --dir coverage _mocha -- -R dot",
|
||||
"posttest": "npm run coverage",
|
||||
"pretest": "standard && echint",
|
||||
"test": "mocha"
|
||||
},
|
||||
"version": "2.0.6"
|
||||
}
|
||||
28
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/LICENSE
generated
vendored
Executable file
28
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/LICENSE
generated
vendored
Executable file
@ -0,0 +1,28 @@
|
||||
Copyright (c) 2012-2014, Eran Hammer and other contributors.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* The names of any contributors may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
* * *
|
||||
|
||||
The complete list of contributors can be found at: https://github.com/hueniverse/hawk/graphs/contributors
|
||||
634
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/README.md
generated
vendored
Executable file
634
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/README.md
generated
vendored
Executable file
@ -0,0 +1,634 @@
|
||||

|
||||
|
||||
<img align="right" src="https://raw.github.com/hueniverse/hawk/master/images/logo.png" /> **Hawk** is an HTTP authentication scheme using a message authentication code (MAC) algorithm to provide partial
|
||||
HTTP request cryptographic verification. For more complex use cases such as access delegation, see [Oz](https://github.com/hueniverse/oz).
|
||||
|
||||
Current version: **3.x**
|
||||
|
||||
Note: 3.x and 2.x are the same exact protocol as 1.1. The version increments reflect changes in the node API.
|
||||
|
||||
[](http://travis-ci.org/hueniverse/hawk)
|
||||
|
||||
# Table of Content
|
||||
|
||||
- [**Introduction**](#introduction)
|
||||
- [Replay Protection](#replay-protection)
|
||||
- [Usage Example](#usage-example)
|
||||
- [Protocol Example](#protocol-example)
|
||||
- [Payload Validation](#payload-validation)
|
||||
- [Response Payload Validation](#response-payload-validation)
|
||||
- [Browser Support and Considerations](#browser-support-and-considerations)
|
||||
<p></p>
|
||||
- [**Single URI Authorization**](#single-uri-authorization)
|
||||
- [Usage Example](#bewit-usage-example)
|
||||
<p></p>
|
||||
- [**Security Considerations**](#security-considerations)
|
||||
- [MAC Keys Transmission](#mac-keys-transmission)
|
||||
- [Confidentiality of Requests](#confidentiality-of-requests)
|
||||
- [Spoofing by Counterfeit Servers](#spoofing-by-counterfeit-servers)
|
||||
- [Plaintext Storage of Credentials](#plaintext-storage-of-credentials)
|
||||
- [Entropy of Keys](#entropy-of-keys)
|
||||
- [Coverage Limitations](#coverage-limitations)
|
||||
- [Future Time Manipulation](#future-time-manipulation)
|
||||
- [Client Clock Poisoning](#client-clock-poisoning)
|
||||
- [Bewit Limitations](#bewit-limitations)
|
||||
- [Host Header Forgery](#host-header-forgery)
|
||||
<p></p>
|
||||
- [**Frequently Asked Questions**](#frequently-asked-questions)
|
||||
<p></p>
|
||||
- [**Implementations**](#implementations)
|
||||
- [**Acknowledgements**](#acknowledgements)
|
||||
|
||||
# Introduction
|
||||
|
||||
**Hawk** is an HTTP authentication scheme providing mechanisms for making authenticated HTTP requests with
|
||||
partial cryptographic verification of the request and response, covering the HTTP method, request URI, host,
|
||||
and optionally the request payload.
|
||||
|
||||
Similar to the HTTP [Digest access authentication schemes](http://www.ietf.org/rfc/rfc2617.txt), **Hawk** uses a set of
|
||||
client credentials which include an identifier (e.g. username) and key (e.g. password). Likewise, just as with the Digest scheme,
|
||||
the key is never included in authenticated requests. Instead, it is used to calculate a request MAC value which is
|
||||
included in its place.
|
||||
|
||||
However, **Hawk** has several differences from Digest. In particular, while both use a nonce to limit the possibility of
|
||||
replay attacks, in **Hawk** the client generates the nonce and uses it in combination with a timestamp, leading to less
|
||||
"chattiness" (interaction with the server).
|
||||
|
||||
Also unlike Digest, this scheme is not intended to protect the key itself (the password in Digest) because
|
||||
the client and server must both have access to the key material in the clear.
|
||||
|
||||
The primary design goals of this scheme are to:
|
||||
* simplify and improve HTTP authentication for services that are unwilling or unable to deploy TLS for all resources,
|
||||
* secure credentials against leakage (e.g., when the client uses some form of dynamic configuration to determine where
|
||||
to send an authenticated request), and
|
||||
* avoid the exposure of credentials sent to a malicious server over an unauthenticated secure channel due to client
|
||||
failure to validate the server's identity as part of its TLS handshake.
|
||||
|
||||
In addition, **Hawk** supports a method for granting third-parties temporary access to individual resources using
|
||||
a query parameter called _bewit_ (in falconry, a leather strap used to attach a tracking device to the leg of a hawk).
|
||||
|
||||
The **Hawk** scheme requires the establishment of a shared symmetric key between the client and the server,
|
||||
which is beyond the scope of this module. Typically, the shared credentials are established via an initial
|
||||
TLS-protected phase or derived from some other shared confidential information available to both the client
|
||||
and the server.
|
||||
|
||||
|
||||
## Replay Protection
|
||||
|
||||
Without replay protection, an attacker can use a compromised (but otherwise valid and authenticated) request more
|
||||
than once, gaining access to a protected resource. To mitigate this, clients include both a nonce and a timestamp when
|
||||
making requests. This gives the server enough information to prevent replay attacks.
|
||||
|
||||
The nonce is generated by the client, and is a string unique across all requests with the same timestamp and
|
||||
key identifier combination.
|
||||
|
||||
The timestamp enables the server to restrict the validity period of the credentials where requests occuring afterwards
|
||||
are rejected. It also removes the need for the server to retain an unbounded number of nonce values for future checks.
|
||||
By default, **Hawk** uses a time window of 1 minute to allow for time skew between the client and server (which in
|
||||
practice translates to a maximum of 2 minutes as the skew can be positive or negative).
|
||||
|
||||
Using a timestamp requires the client's clock to be in sync with the server's clock. **Hawk** requires both the client
|
||||
clock and the server clock to use NTP to ensure synchronization. However, given the limitations of some client types
|
||||
(e.g. browsers) to deploy NTP, the server provides the client with its current time (in seconds precision) in response
|
||||
to a bad timestamp.
|
||||
|
||||
There is no expectation that the client will adjust its system clock to match the server (in fact, this would be a
|
||||
potential attack vector). Instead, the client only uses the server's time to calculate an offset used only
|
||||
for communications with that particular server. The protocol rewards clients with synchronized clocks by reducing
|
||||
the number of round trips required to authenticate the first request.
|
||||
|
||||
|
||||
## Usage Example
|
||||
|
||||
Server code:
|
||||
|
||||
```javascript
|
||||
var Http = require('http');
|
||||
var Hawk = require('hawk');
|
||||
|
||||
|
||||
// Credentials lookup function
|
||||
|
||||
var credentialsFunc = function (id, callback) {
|
||||
|
||||
var credentials = {
|
||||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
|
||||
algorithm: 'sha256',
|
||||
user: 'Steve'
|
||||
};
|
||||
|
||||
return callback(null, credentials);
|
||||
};
|
||||
|
||||
// Create HTTP server
|
||||
|
||||
var handler = function (req, res) {
|
||||
|
||||
// Authenticate incoming request
|
||||
|
||||
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
|
||||
|
||||
// Prepare response
|
||||
|
||||
var payload = (!err ? 'Hello ' + credentials.user + ' ' + artifacts.ext : 'Shoosh!');
|
||||
var headers = { 'Content-Type': 'text/plain' };
|
||||
|
||||
// Generate Server-Authorization response header
|
||||
|
||||
var header = Hawk.server.header(credentials, artifacts, { payload: payload, contentType: headers['Content-Type'] });
|
||||
headers['Server-Authorization'] = header;
|
||||
|
||||
// Send the response back
|
||||
|
||||
res.writeHead(!err ? 200 : 401, headers);
|
||||
res.end(payload);
|
||||
});
|
||||
};
|
||||
|
||||
// Start server
|
||||
|
||||
Http.createServer(handler).listen(8000, 'example.com');
|
||||
```
|
||||
|
||||
Client code:
|
||||
|
||||
```javascript
|
||||
var Request = require('request');
|
||||
var Hawk = require('hawk');
|
||||
|
||||
|
||||
// Client credentials
|
||||
|
||||
var credentials = {
|
||||
id: 'dh37fgj492je',
|
||||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
|
||||
algorithm: 'sha256'
|
||||
}
|
||||
|
||||
// Request options
|
||||
|
||||
var requestOptions = {
|
||||
uri: 'http://example.com:8000/resource/1?b=1&a=2',
|
||||
method: 'GET',
|
||||
headers: {}
|
||||
};
|
||||
|
||||
// Generate Authorization request header
|
||||
|
||||
var header = Hawk.client.header('http://example.com:8000/resource/1?b=1&a=2', 'GET', { credentials: credentials, ext: 'some-app-data' });
|
||||
requestOptions.headers.Authorization = header.field;
|
||||
|
||||
// Send authenticated request
|
||||
|
||||
Request(requestOptions, function (error, response, body) {
|
||||
|
||||
// Authenticate the server's response
|
||||
|
||||
var isValid = Hawk.client.authenticate(response, credentials, header.artifacts, { payload: body });
|
||||
|
||||
// Output results
|
||||
|
||||
console.log(response.statusCode + ': ' + body + (isValid ? ' (valid)' : ' (invalid)'));
|
||||
});
|
||||
```
|
||||
|
||||
**Hawk** utilized the [**SNTP**](https://github.com/hueniverse/sntp) module for time sync management. By default, the local
|
||||
machine time is used. To automatically retrieve and synchronice the clock within the application, use the SNTP 'start()' method.
|
||||
|
||||
```javascript
|
||||
Hawk.sntp.start();
|
||||
```
|
||||
|
||||
|
||||
## Protocol Example
|
||||
|
||||
The client attempts to access a protected resource without authentication, sending the following HTTP request to
|
||||
the resource server:
|
||||
|
||||
```
|
||||
GET /resource/1?b=1&a=2 HTTP/1.1
|
||||
Host: example.com:8000
|
||||
```
|
||||
|
||||
The resource server returns an authentication challenge.
|
||||
|
||||
```
|
||||
HTTP/1.1 401 Unauthorized
|
||||
WWW-Authenticate: Hawk
|
||||
```
|
||||
|
||||
The client has previously obtained a set of **Hawk** credentials for accessing resources on the "http://example.com/"
|
||||
server. The **Hawk** credentials issued to the client include the following attributes:
|
||||
|
||||
* Key identifier: dh37fgj492je
|
||||
* Key: werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn
|
||||
* Algorithm: sha256
|
||||
|
||||
The client generates the authentication header by calculating a timestamp (e.g. the number of seconds since January 1,
|
||||
1970 00:00:00 GMT), generating a nonce, and constructing the normalized request string (each value followed by a newline
|
||||
character):
|
||||
|
||||
```
|
||||
hawk.1.header
|
||||
1353832234
|
||||
j4h3g2
|
||||
GET
|
||||
/resource/1?b=1&a=2
|
||||
example.com
|
||||
8000
|
||||
|
||||
some-app-ext-data
|
||||
|
||||
```
|
||||
|
||||
The request MAC is calculated using HMAC with the specified hash algorithm "sha256" and the key over the normalized request string.
|
||||
The result is base64-encoded to produce the request MAC:
|
||||
|
||||
```
|
||||
6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE=
|
||||
```
|
||||
|
||||
The client includes the **Hawk** key identifier, timestamp, nonce, application specific data, and request MAC with the request using
|
||||
the HTTP `Authorization` request header field:
|
||||
|
||||
```
|
||||
GET /resource/1?b=1&a=2 HTTP/1.1
|
||||
Host: example.com:8000
|
||||
Authorization: Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", ext="some-app-ext-data", mac="6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE="
|
||||
```
|
||||
|
||||
The server validates the request by calculating the request MAC again based on the request received and verifies the validity
|
||||
and scope of the **Hawk** credentials. If valid, the server responds with the requested resource.
|
||||
|
||||
|
||||
### Payload Validation
|
||||
|
||||
**Hawk** provides optional payload validation. When generating the authentication header, the client calculates a payload hash
|
||||
using the specified hash algorithm. The hash is calculated over the concatenated value of (each followed by a newline character):
|
||||
* `hawk.1.payload`
|
||||
* the content-type in lowercase, without any parameters (e.g. `application/json`)
|
||||
* the request payload prior to any content encoding (the exact representation requirements should be specified by the server for payloads other than simple single-part ascii to ensure interoperability)
|
||||
|
||||
For example:
|
||||
|
||||
* Payload: `Thank you for flying Hawk`
|
||||
* Content Type: `text/plain`
|
||||
* Hash (sha256): `Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=`
|
||||
|
||||
Results in the following input to the payload hash function (newline terminated values):
|
||||
|
||||
```
|
||||
hawk.1.payload
|
||||
text/plain
|
||||
Thank you for flying Hawk
|
||||
|
||||
```
|
||||
|
||||
Which produces the following hash value:
|
||||
|
||||
```
|
||||
Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=
|
||||
```
|
||||
|
||||
The client constructs the normalized request string (newline terminated values):
|
||||
|
||||
```
|
||||
hawk.1.header
|
||||
1353832234
|
||||
j4h3g2
|
||||
POST
|
||||
/resource/1?a=1&b=2
|
||||
example.com
|
||||
8000
|
||||
Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=
|
||||
some-app-ext-data
|
||||
|
||||
```
|
||||
|
||||
Then calculates the request MAC and includes the **Hawk** key identifier, timestamp, nonce, payload hash, application specific data,
|
||||
and request MAC, with the request using the HTTP `Authorization` request header field:
|
||||
|
||||
```
|
||||
POST /resource/1?a=1&b=2 HTTP/1.1
|
||||
Host: example.com:8000
|
||||
Authorization: Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", hash="Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=", ext="some-app-ext-data", mac="aSe1DERmZuRl3pI36/9BdZmnErTw3sNzOOAUlfeKjVw="
|
||||
```
|
||||
|
||||
It is up to the server if and when it validates the payload for any given request, based solely on it's security policy
|
||||
and the nature of the data included.
|
||||
|
||||
If the payload is available at the time of authentication, the server uses the hash value provided by the client to construct
|
||||
the normalized string and validates the MAC. If the MAC is valid, the server calculates the payload hash and compares the value
|
||||
with the provided payload hash in the header. In many cases, checking the MAC first is faster than calculating the payload hash.
|
||||
|
||||
However, if the payload is not available at authentication time (e.g. too large to fit in memory, streamed elsewhere, or processed
|
||||
at a different stage in the application), the server may choose to defer payload validation for later by retaining the hash value
|
||||
provided by the client after validating the MAC.
|
||||
|
||||
It is important to note that MAC validation does not mean the hash value provided by the client is valid, only that the value
|
||||
included in the header was not modified. Without calculating the payload hash on the server and comparing it to the value provided
|
||||
by the client, the payload may be modified by an attacker.
|
||||
|
||||
|
||||
## Response Payload Validation
|
||||
|
||||
**Hawk** provides partial response payload validation. The server includes the `Server-Authorization` response header which enables the
|
||||
client to authenticate the response and ensure it is talking to the right server. **Hawk** defines the HTTP `Server-Authorization` header
|
||||
as a response header using the exact same syntax as the `Authorization` request header field.
|
||||
|
||||
The header is contructed using the same process as the client's request header. The server uses the same credentials and other
|
||||
artifacts provided by the client to constructs the normalized request string. The `ext` and `hash` values are replaced with
|
||||
new values based on the server response. The rest as identical to those used by the client.
|
||||
|
||||
The result MAC digest is included with the optional `hash` and `ext` values:
|
||||
|
||||
```
|
||||
Server-Authorization: Hawk mac="XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"
|
||||
```
|
||||
|
||||
|
||||
## Browser Support and Considerations
|
||||
|
||||
A browser script is provided for including using a `<script>` tag in [lib/browser.js](/lib/browser.js). It's also a [component](http://component.io/hueniverse/hawk).
|
||||
|
||||
**Hawk** relies on the _Server-Authorization_ and _WWW-Authenticate_ headers in its response to communicate with the client.
|
||||
Therefore, in case of CORS requests, it is important to consider sending _Access-Control-Expose-Headers_ with the value
|
||||
_"WWW-Authenticate, Server-Authorization"_ on each response from your server. As explained in the
|
||||
[specifications](http://www.w3.org/TR/cors/#access-control-expose-headers-response-header), it will indicate that these headers
|
||||
can safely be accessed by the client (using getResponseHeader() on the XmlHttpRequest object). Otherwise you will be met with a
|
||||
["simple response header"](http://www.w3.org/TR/cors/#simple-response-header) which excludes these fields and would prevent the
|
||||
Hawk client from authenticating the requests.You can read more about the why and how in this
|
||||
[article](http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server)
|
||||
|
||||
|
||||
# Single URI Authorization
|
||||
|
||||
There are cases in which limited and short-term access to a protected resource is granted to a third party which does not
|
||||
have access to the shared credentials. For example, displaying a protected image on a web page accessed by anyone. **Hawk**
|
||||
provides limited support for such URIs in the form of a _bewit_ - a URI query parameter appended to the request URI which contains
|
||||
the necessary credentials to authenticate the request.
|
||||
|
||||
Because of the significant security risks involved in issuing such access, bewit usage is purposely limited only to GET requests
|
||||
and for a finite period of time. Both the client and server can issue bewit credentials, however, the server should not use the same
|
||||
credentials as the client to maintain clear traceability as to who issued which credentials.
|
||||
|
||||
In order to simplify implementation, bewit credentials do not support single-use policy and can be replayed multiple times within
|
||||
the granted access timeframe.
|
||||
|
||||
|
||||
## Bewit Usage Example
|
||||
|
||||
Server code:
|
||||
|
||||
```javascript
|
||||
var Http = require('http');
|
||||
var Hawk = require('hawk');
|
||||
|
||||
|
||||
// Credentials lookup function
|
||||
|
||||
var credentialsFunc = function (id, callback) {
|
||||
|
||||
var credentials = {
|
||||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
|
||||
algorithm: 'sha256'
|
||||
};
|
||||
|
||||
return callback(null, credentials);
|
||||
};
|
||||
|
||||
// Create HTTP server
|
||||
|
||||
var handler = function (req, res) {
|
||||
|
||||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
|
||||
|
||||
res.writeHead(!err ? 200 : 401, { 'Content-Type': 'text/plain' });
|
||||
res.end(!err ? 'Access granted' : 'Shoosh!');
|
||||
});
|
||||
};
|
||||
|
||||
Http.createServer(handler).listen(8000, 'example.com');
|
||||
```
|
||||
|
||||
Bewit code generation:
|
||||
|
||||
```javascript
|
||||
var Request = require('request');
|
||||
var Hawk = require('hawk');
|
||||
|
||||
|
||||
// Client credentials
|
||||
|
||||
var credentials = {
|
||||
id: 'dh37fgj492je',
|
||||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
|
||||
algorithm: 'sha256'
|
||||
}
|
||||
|
||||
// Generate bewit
|
||||
|
||||
var duration = 60 * 5; // 5 Minutes
|
||||
var bewit = Hawk.uri.getBewit('http://example.com:8080/resource/1?b=1&a=2', { credentials: credentials, ttlSec: duration, ext: 'some-app-data' });
|
||||
var uri = 'http://example.com:8000/resource/1?b=1&a=2' + '&bewit=' + bewit;
|
||||
```
|
||||
|
||||
|
||||
# Security Considerations
|
||||
|
||||
The greatest sources of security risks are usually found not in **Hawk** but in the policies and procedures surrounding its use.
|
||||
Implementers are strongly encouraged to assess how this module addresses their security requirements. This section includes
|
||||
an incomplete list of security considerations that must be reviewed and understood before deploying **Hawk** on the server.
|
||||
Many of the protections provided in **Hawk** depends on whether and how they are used.
|
||||
|
||||
### MAC Keys Transmission
|
||||
|
||||
**Hawk** does not provide any mechanism for obtaining or transmitting the set of shared credentials required. Any mechanism used
|
||||
to obtain **Hawk** credentials must ensure that these transmissions are protected using transport-layer mechanisms such as TLS.
|
||||
|
||||
### Confidentiality of Requests
|
||||
|
||||
While **Hawk** provides a mechanism for verifying the integrity of HTTP requests, it provides no guarantee of request
|
||||
confidentiality. Unless other precautions are taken, eavesdroppers will have full access to the request content. Servers should
|
||||
carefully consider the types of data likely to be sent as part of such requests, and employ transport-layer security mechanisms
|
||||
to protect sensitive resources.
|
||||
|
||||
### Spoofing by Counterfeit Servers
|
||||
|
||||
**Hawk** provides limited verification of the server authenticity. When receiving a response back from the server, the server
|
||||
may choose to include a response `Server-Authorization` header which the client can use to verify the response. However, it is up to
|
||||
the server to determine when such measure is included, to up to the client to enforce that policy.
|
||||
|
||||
A hostile party could take advantage of this by intercepting the client's requests and returning misleading or otherwise
|
||||
incorrect responses. Service providers should consider such attacks when developing services using this protocol, and should
|
||||
require transport-layer security for any requests where the authenticity of the resource server or of server responses is an issue.
|
||||
|
||||
### Plaintext Storage of Credentials
|
||||
|
||||
The **Hawk** key functions the same way passwords do in traditional authentication systems. In order to compute the request MAC,
|
||||
the server must have access to the key in plaintext form. This is in contrast, for example, to modern operating systems, which
|
||||
store only a one-way hash of user credentials.
|
||||
|
||||
If an attacker were to gain access to these keys - or worse, to the server's database of all such keys - he or she would be able
|
||||
to perform any action on behalf of any resource owner. Accordingly, it is critical that servers protect these keys from unauthorized
|
||||
access.
|
||||
|
||||
### Entropy of Keys
|
||||
|
||||
Unless a transport-layer security protocol is used, eavesdroppers will have full access to authenticated requests and request
|
||||
MAC values, and will thus be able to mount offline brute-force attacks to recover the key used. Servers should be careful to
|
||||
assign keys which are long enough, and random enough, to resist such attacks for at least the length of time that the **Hawk**
|
||||
credentials are valid.
|
||||
|
||||
For example, if the credentials are valid for two weeks, servers should ensure that it is not possible to mount a brute force
|
||||
attack that recovers the key in less than two weeks. Of course, servers are urged to err on the side of caution, and use the
|
||||
longest key reasonable.
|
||||
|
||||
It is equally important that the pseudo-random number generator (PRNG) used to generate these keys be of sufficiently high
|
||||
quality. Many PRNG implementations generate number sequences that may appear to be random, but which nevertheless exhibit
|
||||
patterns or other weaknesses which make cryptanalysis or brute force attacks easier. Implementers should be careful to use
|
||||
cryptographically secure PRNGs to avoid these problems.
|
||||
|
||||
### Coverage Limitations
|
||||
|
||||
The request MAC only covers the HTTP `Host` header and optionally the `Content-Type` header. It does not cover any other headers
|
||||
which can often affect how the request body is interpreted by the server. If the server behavior is influenced by the presence
|
||||
or value of such headers, an attacker can manipulate the request headers without being detected. Implementers should use the
|
||||
`ext` feature to pass application-specific information via the `Authorization` header which is protected by the request MAC.
|
||||
|
||||
The response authentication, when performed, only covers the response payload, content-type, and the request information
|
||||
provided by the client in it's request (method, resource, timestamp, nonce, etc.). It does not cover the HTTP status code or
|
||||
any other response header field (e.g. Location) which can affect the client's behaviour.
|
||||
|
||||
### Future Time Manipulation
|
||||
|
||||
The protocol relies on a clock sync between the client and server. To accomplish this, the server informs the client of its
|
||||
current time when an invalid timestamp is received.
|
||||
|
||||
If an attacker is able to manipulate this information and cause the client to use an incorrect time, it would be able to cause
|
||||
the client to generate authenticated requests using time in the future. Such requests will fail when sent by the client, and will
|
||||
not likely leave a trace on the server (given the common implementation of nonce, if at all enforced). The attacker will then
|
||||
be able to replay the request at the correct time without detection.
|
||||
|
||||
The client must only use the time information provided by the server if:
|
||||
* it was delivered over a TLS connection and the server identity has been verified, or
|
||||
* the `tsm` MAC digest calculated using the same client credentials over the timestamp has been verified.
|
||||
|
||||
### Client Clock Poisoning
|
||||
|
||||
When receiving a request with a bad timestamp, the server provides the client with its current time. The client must never use
|
||||
the time received from the server to adjust its own clock, and must only use it to calculate an offset for communicating with
|
||||
that particular server.
|
||||
|
||||
### Bewit Limitations
|
||||
|
||||
Special care must be taken when issuing bewit credentials to third parties. Bewit credentials are valid until expiration and cannot
|
||||
be revoked or limited without using other means. Whatever resource they grant access to will be completely exposed to anyone with
|
||||
access to the bewit credentials which act as bearer credentials for that particular resource. While bewit usage is limited to GET
|
||||
requests only and therefore cannot be used to perform transactions or change server state, it can still be used to expose private
|
||||
and sensitive information.
|
||||
|
||||
### Host Header Forgery
|
||||
|
||||
Hawk validates the incoming request MAC against the incoming HTTP Host header. However, unless the optional `host` and `port`
|
||||
options are used with `server.authenticate()`, a malicous client can mint new host names pointing to the server's IP address and
|
||||
use that to craft an attack by sending a valid request that's meant for another hostname than the one used by the server. Server
|
||||
implementors must manually verify that the host header received matches their expectation (or use the options mentioned above).
|
||||
|
||||
# Frequently Asked Questions
|
||||
|
||||
### Where is the protocol specification?
|
||||
|
||||
If you are looking for some prose explaining how all this works, **this is it**. **Hawk** is being developed as an open source
|
||||
project instead of a standard. In other words, the [code](/hueniverse/hawk/tree/master/lib) is the specification. Not sure about
|
||||
something? Open an issue!
|
||||
|
||||
### Is it done?
|
||||
|
||||
As of version 0.10.0, **Hawk** is feature-complete. However, until this module reaches version 1.0.0 it is considered experimental
|
||||
and is likely to change. This also means your feedback and contribution are very welcome. Feel free to open issues with questions
|
||||
and suggestions.
|
||||
|
||||
### Where can I find **Hawk** implementations in other languages?
|
||||
|
||||
**Hawk**'s only reference implementation is provided in JavaScript as a node.js module. However, it has been ported to other languages.
|
||||
The full list is maintained [here](https://github.com/hueniverse/hawk/issues?labels=port&state=closed). Please add an issue if you are
|
||||
working on another port. A cross-platform test-suite is in the works.
|
||||
|
||||
### Why isn't the algorithm part of the challenge or dynamically negotiated?
|
||||
|
||||
The algorithm used is closely related to the key issued as different algorithms require different key sizes (and other
|
||||
requirements). While some keys can be used for multiple algorithm, the protocol is designed to closely bind the key and algorithm
|
||||
together as part of the issued credentials.
|
||||
|
||||
### Why is Host and Content-Type the only headers covered by the request MAC?
|
||||
|
||||
It is really hard to include other headers. Headers can be changed by proxies and other intermediaries and there is no
|
||||
well-established way to normalize them. Many platforms change the case of header field names and values. The only
|
||||
straight-forward solution is to include the headers in some blob (say, base64 encoded JSON) and include that with the request,
|
||||
an approach taken by JWT and other such formats. However, that design violates the HTTP header boundaries, repeats information,
|
||||
and introduces other security issues because firewalls will not be aware of these "hidden" headers. In addition, any information
|
||||
repeated must be compared to the duplicated information in the header and therefore only moves the problem elsewhere.
|
||||
|
||||
### Why not just use HTTP Digest?
|
||||
|
||||
Digest requires pre-negotiation to establish a nonce. This means you can't just make a request - you must first send
|
||||
a protocol handshake to the server. This pattern has become unacceptable for most web services, especially mobile
|
||||
where extra round-trip are costly.
|
||||
|
||||
### Why bother with all this nonce and timestamp business?
|
||||
|
||||
**Hawk** is an attempt to find a reasonable, practical compromise between security and usability. OAuth 1.0 got timestamp
|
||||
and nonces halfway right but failed when it came to scalability and consistent developer experience. **Hawk** addresses
|
||||
it by requiring the client to sync its clock, but provides it with tools to accomplish it.
|
||||
|
||||
In general, replay protection is a matter of application-specific threat model. It is less of an issue on a TLS-protected
|
||||
system where the clients are implemented using best practices and are under the control of the server. Instead of dropping
|
||||
replay protection, **Hawk** offers a required time window and an optional nonce verification. Together, it provides developers
|
||||
with the ability to decide how to enforce their security policy without impacting the client's implementation.
|
||||
|
||||
### What are `app` and `dlg` in the authorization header and normalized mac string?
|
||||
|
||||
The original motivation for **Hawk** was to replace the OAuth 1.0 use cases. This included both a simple client-server mode which
|
||||
this module is specifically designed for, and a delegated access mode which is being developed separately in
|
||||
[Oz](https://github.com/hueniverse/oz). In addition to the **Hawk** use cases, Oz requires another attribute: the application id `app`.
|
||||
This provides binding between the credentials and the application in a way that prevents an attacker from tricking an application
|
||||
to use credentials issued to someone else. It also has an optional 'delegated-by' attribute `dlg` which is the application id of the
|
||||
application the credentials were directly issued to. The goal of these two additions is to allow Oz to utilize **Hawk** directly,
|
||||
but with the additional security of delegated credentials.
|
||||
|
||||
### What is the purpose of the static strings used in each normalized MAC input?
|
||||
|
||||
When calculating a hash or MAC, a static prefix (tag) is added. The prefix is used to prevent MAC values from being
|
||||
used or reused for a purpose other than what they were created for (i.e. prevents switching MAC values between a request,
|
||||
response, and a bewit use cases). It also protects against exploits created after a potential change in how the protocol
|
||||
creates the normalized string. For example, if a future version would switch the order of nonce and timestamp, it
|
||||
can create an exploit opportunity for cases where the nonce is similar in format to a timestamp.
|
||||
|
||||
### Does **Hawk** have anything to do with OAuth?
|
||||
|
||||
Short answer: no.
|
||||
|
||||
**Hawk** was originally proposed as the OAuth MAC Token specification. However, the OAuth working group in its consistent
|
||||
incompetence failed to produce a final, usable solution to address one of the most popular use cases of OAuth 1.0 - using it
|
||||
to authenticate simple client-server transactions (i.e. two-legged). As you can guess, the OAuth working group is still hard
|
||||
at work to produce more garbage.
|
||||
|
||||
**Hawk** provides a simple HTTP authentication scheme for making client-server requests. It does not address the OAuth use case
|
||||
of delegating access to a third party. If you are looking for an OAuth alternative, check out [Oz](https://github.com/hueniverse/oz).
|
||||
|
||||
# Implementations
|
||||
|
||||
- [Logibit Hawk in F#/.Net](https://github.com/logibit/logibit.hawk/)
|
||||
- [Tent Hawk in Ruby](https://github.com/tent/hawk-ruby)
|
||||
- [Wealdtech in Java](https://github.com/wealdtech/hawk)
|
||||
- [Kumar's Mohawk in Python](https://github.com/kumar303/mohawk/)
|
||||
|
||||
# Acknowledgements
|
||||
|
||||
**Hawk** is a derivative work of the [HTTP MAC Authentication Scheme](http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-05) proposal
|
||||
co-authored by Ben Adida, Adam Barth, and Eran Hammer, which in turn was based on the OAuth 1.0 community specification.
|
||||
|
||||
Special thanks to Ben Laurie for his always insightful feedback and advice.
|
||||
|
||||
The **Hawk** logo was created by [Chris Carrasco](http://chriscarrasco.com).
|
||||
24
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/bower.json
generated
vendored
Normal file
24
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/bower.json
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "hawk",
|
||||
"main": "lib/browser.js",
|
||||
"license": "./LICENSE",
|
||||
"ignore": [
|
||||
"!lib",
|
||||
"lib/*",
|
||||
"!lib/browser.js",
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"http",
|
||||
"authentication",
|
||||
"scheme",
|
||||
"hawk"
|
||||
],
|
||||
"authors": [
|
||||
"Eran Hammer <eran@hammer.io>"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/hueniverse/hawk.git"
|
||||
}
|
||||
}
|
||||
19
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/component.json
generated
vendored
Normal file
19
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/component.json
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "hawk",
|
||||
"repo": "hueniverse/hawk",
|
||||
"description": "HTTP Hawk Authentication Scheme",
|
||||
"version": "1.0.0",
|
||||
"keywords": [
|
||||
"http",
|
||||
"authentication",
|
||||
"scheme",
|
||||
"hawk"
|
||||
],
|
||||
"dependencies": {},
|
||||
"development": {},
|
||||
"license": "BSD",
|
||||
"main": "lib/browser.js",
|
||||
"scripts": [
|
||||
"lib/browser.js"
|
||||
]
|
||||
}
|
||||
343
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/dist/client.js
generated
vendored
Normal file
343
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/dist/client.js
generated
vendored
Normal file
@ -0,0 +1,343 @@
|
||||
'use strict'
|
||||
|
||||
// Load modules
|
||||
|
||||
;
|
||||
|
||||
var _typeof = function (obj) {
|
||||
|
||||
return obj && typeof Symbol !== 'undefined' && obj.constructor === Symbol ? 'symbol' : typeof obj;
|
||||
};
|
||||
|
||||
var Url = require('url');
|
||||
var Hoek = require('hoek');
|
||||
var Cryptiles = require('cryptiles');
|
||||
var Crypto = require('./crypto');
|
||||
var Utils = require('./utils');
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
// Generate an Authorization header for a given request
|
||||
|
||||
/*
|
||||
uri: 'http://example.com/resource?a=b' or object from Url.parse()
|
||||
method: HTTP verb (e.g. 'GET', 'POST')
|
||||
options: {
|
||||
|
||||
// Required
|
||||
|
||||
credentials: {
|
||||
id: 'dh37fgj492je',
|
||||
key: 'aoijedoaijsdlaksjdl',
|
||||
algorithm: 'sha256' // 'sha1', 'sha256'
|
||||
},
|
||||
|
||||
// Optional
|
||||
|
||||
ext: 'application-specific', // Application specific data sent via the ext attribute
|
||||
timestamp: Date.now(), // A pre-calculated timestamp
|
||||
nonce: '2334f34f', // A pre-generated nonce
|
||||
localtimeOffsetMsec: 400, // Time offset to sync with server time (ignored if timestamp provided)
|
||||
payload: '{"some":"payload"}', // UTF-8 encoded string for body hash generation (ignored if hash provided)
|
||||
contentType: 'application/json', // Payload content-type (ignored if hash provided)
|
||||
hash: 'U4MKKSmiVxk37JCCrAVIjV=', // Pre-calculated payload hash
|
||||
app: '24s23423f34dx', // Oz application id
|
||||
dlg: '234sz34tww3sd' // Oz delegated-by application id
|
||||
}
|
||||
*/
|
||||
|
||||
exports.header = function (uri, method, options) {
|
||||
|
||||
var result = {
|
||||
field: '',
|
||||
artifacts: {}
|
||||
};
|
||||
|
||||
// Validate inputs
|
||||
|
||||
if (!uri || typeof uri !== 'string' && (typeof uri === 'undefined' ? 'undefined' : _typeof(uri)) !== 'object' || !method || typeof method !== 'string' || !options || (typeof options === 'undefined' ? 'undefined' : _typeof(options)) !== 'object') {
|
||||
|
||||
result.err = 'Invalid argument type';
|
||||
return result;
|
||||
}
|
||||
|
||||
// Application time
|
||||
|
||||
var timestamp = options.timestamp || Utils.nowSecs(options.localtimeOffsetMsec);
|
||||
|
||||
// Validate credentials
|
||||
|
||||
var credentials = options.credentials;
|
||||
if (!credentials || !credentials.id || !credentials.key || !credentials.algorithm) {
|
||||
|
||||
result.err = 'Invalid credential object';
|
||||
return result;
|
||||
}
|
||||
|
||||
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
|
||||
result.err = 'Unknown algorithm';
|
||||
return result;
|
||||
}
|
||||
|
||||
// Parse URI
|
||||
|
||||
if (typeof uri === 'string') {
|
||||
uri = Url.parse(uri);
|
||||
}
|
||||
|
||||
// Calculate signature
|
||||
|
||||
var artifacts = {
|
||||
ts: timestamp,
|
||||
nonce: options.nonce || Cryptiles.randomString(6),
|
||||
method: method,
|
||||
resource: uri.pathname + (uri.search || ''), // Maintain trailing '?'
|
||||
host: uri.hostname,
|
||||
port: uri.port || (uri.protocol === 'http:' ? 80 : 443),
|
||||
hash: options.hash,
|
||||
ext: options.ext,
|
||||
app: options.app,
|
||||
dlg: options.dlg
|
||||
};
|
||||
|
||||
result.artifacts = artifacts;
|
||||
|
||||
// Calculate payload hash
|
||||
|
||||
if (!artifacts.hash && (options.payload || options.payload === '')) {
|
||||
|
||||
artifacts.hash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType);
|
||||
}
|
||||
|
||||
var mac = Crypto.calculateMac('header', credentials, artifacts);
|
||||
|
||||
// Construct header
|
||||
|
||||
var hasExt = artifacts.ext !== null && artifacts.ext !== undefined && artifacts.ext !== ''; // Other falsey values allowed
|
||||
var header = 'Hawk id="' + credentials.id + '", ts="' + artifacts.ts + '", nonce="' + artifacts.nonce + (artifacts.hash ? '", hash="' + artifacts.hash : '') + (hasExt ? '", ext="' + Hoek.escapeHeaderAttribute(artifacts.ext) : '') + '", mac="' + mac + '"';
|
||||
|
||||
if (artifacts.app) {
|
||||
header = header + ', app="' + artifacts.app + (artifacts.dlg ? '", dlg="' + artifacts.dlg : '') + '"';
|
||||
}
|
||||
|
||||
result.field = header;
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// Validate server response
|
||||
|
||||
/*
|
||||
res: node's response object
|
||||
artifacts: object received from header().artifacts
|
||||
options: {
|
||||
payload: optional payload received
|
||||
required: specifies if a Server-Authorization header is required. Defaults to 'false'
|
||||
}
|
||||
*/
|
||||
|
||||
exports.authenticate = function (res, credentials, artifacts, options) {
|
||||
|
||||
artifacts = Hoek.clone(artifacts);
|
||||
options = options || {};
|
||||
|
||||
if (res.headers['www-authenticate']) {
|
||||
|
||||
// Parse HTTP WWW-Authenticate header
|
||||
|
||||
var wwwAttributes = Utils.parseAuthorizationHeader(res.headers['www-authenticate'], ['ts', 'tsm', 'error']);
|
||||
if (wwwAttributes instanceof Error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate server timestamp (not used to update clock since it is done via the SNPT client)
|
||||
|
||||
if (wwwAttributes.ts) {
|
||||
var tsm = Crypto.calculateTsMac(wwwAttributes.ts, credentials);
|
||||
if (tsm !== wwwAttributes.tsm) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse HTTP Server-Authorization header
|
||||
|
||||
if (!res.headers['server-authorization'] && !options.required) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
var attributes = Utils.parseAuthorizationHeader(res.headers['server-authorization'], ['mac', 'ext', 'hash']);
|
||||
if (attributes instanceof Error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
artifacts.ext = attributes.ext;
|
||||
artifacts.hash = attributes.hash;
|
||||
|
||||
var mac = Crypto.calculateMac('response', credentials, artifacts);
|
||||
if (mac !== attributes.mac) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!options.payload && options.payload !== '') {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!attributes.hash) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var calculatedHash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, res.headers['content-type']);
|
||||
return calculatedHash === attributes.hash;
|
||||
};
|
||||
|
||||
// Generate a bewit value for a given URI
|
||||
|
||||
/*
|
||||
uri: 'http://example.com/resource?a=b' or object from Url.parse()
|
||||
options: {
|
||||
|
||||
// Required
|
||||
|
||||
credentials: {
|
||||
id: 'dh37fgj492je',
|
||||
key: 'aoijedoaijsdlaksjdl',
|
||||
algorithm: 'sha256' // 'sha1', 'sha256'
|
||||
},
|
||||
ttlSec: 60 * 60, // TTL in seconds
|
||||
|
||||
// Optional
|
||||
|
||||
ext: 'application-specific', // Application specific data sent via the ext attribute
|
||||
localtimeOffsetMsec: 400 // Time offset to sync with server time
|
||||
};
|
||||
*/
|
||||
|
||||
exports.getBewit = function (uri, options) {
|
||||
|
||||
// Validate inputs
|
||||
|
||||
if (!uri || typeof uri !== 'string' && (typeof uri === 'undefined' ? 'undefined' : _typeof(uri)) !== 'object' || !options || (typeof options === 'undefined' ? 'undefined' : _typeof(options)) !== 'object' || !options.ttlSec) {
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
options.ext = options.ext === null || options.ext === undefined ? '' : options.ext; // Zero is valid value
|
||||
|
||||
// Application time
|
||||
|
||||
var now = Utils.now(options.localtimeOffsetMsec);
|
||||
|
||||
// Validate credentials
|
||||
|
||||
var credentials = options.credentials;
|
||||
if (!credentials || !credentials.id || !credentials.key || !credentials.algorithm) {
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Parse URI
|
||||
|
||||
if (typeof uri === 'string') {
|
||||
uri = Url.parse(uri);
|
||||
}
|
||||
|
||||
// Calculate signature
|
||||
|
||||
var exp = Math.floor(now / 1000) + options.ttlSec;
|
||||
var mac = Crypto.calculateMac('bewit', credentials, {
|
||||
ts: exp,
|
||||
nonce: '',
|
||||
method: 'GET',
|
||||
resource: uri.pathname + (uri.search || ''), // Maintain trailing '?'
|
||||
host: uri.hostname,
|
||||
port: uri.port || (uri.protocol === 'http:' ? 80 : 443),
|
||||
ext: options.ext
|
||||
});
|
||||
|
||||
// Construct bewit: id\exp\mac\ext
|
||||
|
||||
var bewit = credentials.id + '\\' + exp + '\\' + mac + '\\' + options.ext;
|
||||
return Hoek.base64urlEncode(bewit);
|
||||
};
|
||||
|
||||
// Generate an authorization string for a message
|
||||
|
||||
/*
|
||||
host: 'example.com',
|
||||
port: 8000,
|
||||
message: '{"some":"payload"}', // UTF-8 encoded string for body hash generation
|
||||
options: {
|
||||
|
||||
// Required
|
||||
|
||||
credentials: {
|
||||
id: 'dh37fgj492je',
|
||||
key: 'aoijedoaijsdlaksjdl',
|
||||
algorithm: 'sha256' // 'sha1', 'sha256'
|
||||
},
|
||||
|
||||
// Optional
|
||||
|
||||
timestamp: Date.now(), // A pre-calculated timestamp
|
||||
nonce: '2334f34f', // A pre-generated nonce
|
||||
localtimeOffsetMsec: 400, // Time offset to sync with server time (ignored if timestamp provided)
|
||||
}
|
||||
*/
|
||||
|
||||
exports.message = function (host, port, message, options) {
|
||||
|
||||
// Validate inputs
|
||||
|
||||
if (!host || typeof host !== 'string' || !port || typeof port !== 'number' || message === null || message === undefined || typeof message !== 'string' || !options || (typeof options === 'undefined' ? 'undefined' : _typeof(options)) !== 'object') {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Application time
|
||||
|
||||
var timestamp = options.timestamp || Utils.nowSecs(options.localtimeOffsetMsec);
|
||||
|
||||
// Validate credentials
|
||||
|
||||
var credentials = options.credentials;
|
||||
if (!credentials || !credentials.id || !credentials.key || !credentials.algorithm) {
|
||||
|
||||
// Invalid credential object
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Calculate signature
|
||||
|
||||
var artifacts = {
|
||||
ts: timestamp,
|
||||
nonce: options.nonce || Cryptiles.randomString(6),
|
||||
host: host,
|
||||
port: port,
|
||||
hash: Crypto.calculatePayloadHash(message, credentials.algorithm)
|
||||
};
|
||||
|
||||
// Construct authorization
|
||||
|
||||
var result = {
|
||||
id: credentials.id,
|
||||
ts: artifacts.ts,
|
||||
nonce: artifacts.nonce,
|
||||
hash: artifacts.hash,
|
||||
mac: Crypto.calculateMac('message', credentials, artifacts)
|
||||
};
|
||||
|
||||
return result;
|
||||
};
|
||||
78
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/example/usage.js
generated
vendored
Executable file
78
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/example/usage.js
generated
vendored
Executable file
@ -0,0 +1,78 @@
|
||||
// Load modules
|
||||
|
||||
var Http = require('http');
|
||||
var Request = require('request');
|
||||
var Hawk = require('../lib');
|
||||
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {
|
||||
credentials: {
|
||||
dh37fgj492je: {
|
||||
id: 'dh37fgj492je', // Required by Hawk.client.header
|
||||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
|
||||
algorithm: 'sha256',
|
||||
user: 'Steve'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Credentials lookup function
|
||||
|
||||
var credentialsFunc = function (id, callback) {
|
||||
|
||||
return callback(null, internals.credentials[id]);
|
||||
};
|
||||
|
||||
|
||||
// Create HTTP server
|
||||
|
||||
var handler = function (req, res) {
|
||||
|
||||
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) {
|
||||
|
||||
var payload = (!err ? 'Hello ' + credentials.user + ' ' + artifacts.ext : 'Shoosh!');
|
||||
var headers = {
|
||||
'Content-Type': 'text/plain',
|
||||
'Server-Authorization': Hawk.server.header(credentials, artifacts, { payload: payload, contentType: 'text/plain' })
|
||||
};
|
||||
|
||||
res.writeHead(!err ? 200 : 401, headers);
|
||||
res.end(payload);
|
||||
});
|
||||
};
|
||||
|
||||
Http.createServer(handler).listen(8000, '127.0.0.1');
|
||||
|
||||
|
||||
// Send unauthenticated request
|
||||
|
||||
Request('http://127.0.0.1:8000/resource/1?b=1&a=2', function (error, response, body) {
|
||||
|
||||
console.log(response.statusCode + ': ' + body);
|
||||
});
|
||||
|
||||
|
||||
// Send authenticated request
|
||||
|
||||
credentialsFunc('dh37fgj492je', function (err, credentials) {
|
||||
|
||||
var header = Hawk.client.header('http://127.0.0.1:8000/resource/1?b=1&a=2', 'GET', { credentials: credentials, ext: 'and welcome!' });
|
||||
var options = {
|
||||
uri: 'http://127.0.0.1:8000/resource/1?b=1&a=2',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
authorization: header.field
|
||||
}
|
||||
};
|
||||
|
||||
Request(options, function (error, response, body) {
|
||||
|
||||
var isValid = Hawk.client.authenticate(response, credentials, header.artifacts, { payload: body });
|
||||
console.log(response.statusCode + ': ' + body + (isValid ? ' (valid)' : ' (invalid)'));
|
||||
process.exit(0);
|
||||
});
|
||||
});
|
||||
|
||||
BIN
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/images/hawk.png
generated
vendored
Executable file
BIN
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/images/hawk.png
generated
vendored
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 6.8 KiB |
BIN
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/images/logo.png
generated
vendored
Executable file
BIN
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/images/logo.png
generated
vendored
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
637
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/lib/browser.js
generated
vendored
Executable file
637
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/lib/browser.js
generated
vendored
Executable file
@ -0,0 +1,637 @@
|
||||
/*
|
||||
HTTP Hawk Authentication Scheme
|
||||
Copyright (c) 2012-2014, Eran Hammer <eran@hammer.io>
|
||||
BSD Licensed
|
||||
*/
|
||||
|
||||
|
||||
// Declare namespace
|
||||
|
||||
var hawk = {
|
||||
internals: {}
|
||||
};
|
||||
|
||||
|
||||
hawk.client = {
|
||||
|
||||
// Generate an Authorization header for a given request
|
||||
|
||||
/*
|
||||
uri: 'http://example.com/resource?a=b' or object generated by hawk.utils.parseUri()
|
||||
method: HTTP verb (e.g. 'GET', 'POST')
|
||||
options: {
|
||||
|
||||
// Required
|
||||
|
||||
credentials: {
|
||||
id: 'dh37fgj492je',
|
||||
key: 'aoijedoaijsdlaksjdl',
|
||||
algorithm: 'sha256' // 'sha1', 'sha256'
|
||||
},
|
||||
|
||||
// Optional
|
||||
|
||||
ext: 'application-specific', // Application specific data sent via the ext attribute
|
||||
timestamp: Date.now() / 1000, // A pre-calculated timestamp in seconds
|
||||
nonce: '2334f34f', // A pre-generated nonce
|
||||
localtimeOffsetMsec: 400, // Time offset to sync with server time (ignored if timestamp provided)
|
||||
payload: '{"some":"payload"}', // UTF-8 encoded string for body hash generation (ignored if hash provided)
|
||||
contentType: 'application/json', // Payload content-type (ignored if hash provided)
|
||||
hash: 'U4MKKSmiVxk37JCCrAVIjV=', // Pre-calculated payload hash
|
||||
app: '24s23423f34dx', // Oz application id
|
||||
dlg: '234sz34tww3sd' // Oz delegated-by application id
|
||||
}
|
||||
*/
|
||||
|
||||
header: function (uri, method, options) {
|
||||
|
||||
var result = {
|
||||
field: '',
|
||||
artifacts: {}
|
||||
};
|
||||
|
||||
// Validate inputs
|
||||
|
||||
if (!uri || (typeof uri !== 'string' && typeof uri !== 'object') ||
|
||||
!method || typeof method !== 'string' ||
|
||||
!options || typeof options !== 'object') {
|
||||
|
||||
result.err = 'Invalid argument type';
|
||||
return result;
|
||||
}
|
||||
|
||||
// Application time
|
||||
|
||||
var timestamp = options.timestamp || hawk.utils.now(options.localtimeOffsetMsec);
|
||||
|
||||
// Validate credentials
|
||||
|
||||
var credentials = options.credentials;
|
||||
if (!credentials ||
|
||||
!credentials.id ||
|
||||
!credentials.key ||
|
||||
!credentials.algorithm) {
|
||||
|
||||
result.err = 'Invalid credentials object';
|
||||
return result;
|
||||
}
|
||||
|
||||
if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) {
|
||||
result.err = 'Unknown algorithm';
|
||||
return result;
|
||||
}
|
||||
|
||||
// Parse URI
|
||||
|
||||
if (typeof uri === 'string') {
|
||||
uri = hawk.utils.parseUri(uri);
|
||||
}
|
||||
|
||||
// Calculate signature
|
||||
|
||||
var artifacts = {
|
||||
ts: timestamp,
|
||||
nonce: options.nonce || hawk.utils.randomString(6),
|
||||
method: method,
|
||||
resource: uri.resource,
|
||||
host: uri.host,
|
||||
port: uri.port,
|
||||
hash: options.hash,
|
||||
ext: options.ext,
|
||||
app: options.app,
|
||||
dlg: options.dlg
|
||||
};
|
||||
|
||||
result.artifacts = artifacts;
|
||||
|
||||
// Calculate payload hash
|
||||
|
||||
if (!artifacts.hash &&
|
||||
(options.payload || options.payload === '')) {
|
||||
|
||||
artifacts.hash = hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType);
|
||||
}
|
||||
|
||||
var mac = hawk.crypto.calculateMac('header', credentials, artifacts);
|
||||
|
||||
// Construct header
|
||||
|
||||
var hasExt = artifacts.ext !== null && artifacts.ext !== undefined && artifacts.ext !== ''; // Other falsey values allowed
|
||||
var header = 'Hawk id="' + credentials.id +
|
||||
'", ts="' + artifacts.ts +
|
||||
'", nonce="' + artifacts.nonce +
|
||||
(artifacts.hash ? '", hash="' + artifacts.hash : '') +
|
||||
(hasExt ? '", ext="' + hawk.utils.escapeHeaderAttribute(artifacts.ext) : '') +
|
||||
'", mac="' + mac + '"';
|
||||
|
||||
if (artifacts.app) {
|
||||
header += ', app="' + artifacts.app +
|
||||
(artifacts.dlg ? '", dlg="' + artifacts.dlg : '') + '"';
|
||||
}
|
||||
|
||||
result.field = header;
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
// Generate a bewit value for a given URI
|
||||
|
||||
/*
|
||||
uri: 'http://example.com/resource?a=b'
|
||||
options: {
|
||||
|
||||
// Required
|
||||
|
||||
credentials: {
|
||||
id: 'dh37fgj492je',
|
||||
key: 'aoijedoaijsdlaksjdl',
|
||||
algorithm: 'sha256' // 'sha1', 'sha256'
|
||||
},
|
||||
ttlSec: 60 * 60, // TTL in seconds
|
||||
|
||||
// Optional
|
||||
|
||||
ext: 'application-specific', // Application specific data sent via the ext attribute
|
||||
localtimeOffsetMsec: 400 // Time offset to sync with server time
|
||||
};
|
||||
*/
|
||||
|
||||
bewit: function (uri, options) {
|
||||
|
||||
// Validate inputs
|
||||
|
||||
if (!uri ||
|
||||
(typeof uri !== 'string') ||
|
||||
!options ||
|
||||
typeof options !== 'object' ||
|
||||
!options.ttlSec) {
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
options.ext = (options.ext === null || options.ext === undefined ? '' : options.ext); // Zero is valid value
|
||||
|
||||
// Application time
|
||||
|
||||
var now = hawk.utils.now(options.localtimeOffsetMsec);
|
||||
|
||||
// Validate credentials
|
||||
|
||||
var credentials = options.credentials;
|
||||
if (!credentials ||
|
||||
!credentials.id ||
|
||||
!credentials.key ||
|
||||
!credentials.algorithm) {
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Parse URI
|
||||
|
||||
uri = hawk.utils.parseUri(uri);
|
||||
|
||||
// Calculate signature
|
||||
|
||||
var exp = now + options.ttlSec;
|
||||
var mac = hawk.crypto.calculateMac('bewit', credentials, {
|
||||
ts: exp,
|
||||
nonce: '',
|
||||
method: 'GET',
|
||||
resource: uri.resource, // Maintain trailing '?' and query params
|
||||
host: uri.host,
|
||||
port: uri.port,
|
||||
ext: options.ext
|
||||
});
|
||||
|
||||
// Construct bewit: id\exp\mac\ext
|
||||
|
||||
var bewit = credentials.id + '\\' + exp + '\\' + mac + '\\' + options.ext;
|
||||
return hawk.utils.base64urlEncode(bewit);
|
||||
},
|
||||
|
||||
// Validate server response
|
||||
|
||||
/*
|
||||
request: object created via 'new XMLHttpRequest()' after response received
|
||||
artifacts: object received from header().artifacts
|
||||
options: {
|
||||
payload: optional payload received
|
||||
required: specifies if a Server-Authorization header is required. Defaults to 'false'
|
||||
}
|
||||
*/
|
||||
|
||||
authenticate: function (request, credentials, artifacts, options) {
|
||||
|
||||
options = options || {};
|
||||
|
||||
var getHeader = function (name) {
|
||||
|
||||
return request.getResponseHeader ? request.getResponseHeader(name) : request.getHeader(name);
|
||||
};
|
||||
|
||||
var wwwAuthenticate = getHeader('www-authenticate');
|
||||
if (wwwAuthenticate) {
|
||||
|
||||
// Parse HTTP WWW-Authenticate header
|
||||
|
||||
var wwwAttributes = hawk.utils.parseAuthorizationHeader(wwwAuthenticate, ['ts', 'tsm', 'error']);
|
||||
if (!wwwAttributes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (wwwAttributes.ts) {
|
||||
var tsm = hawk.crypto.calculateTsMac(wwwAttributes.ts, credentials);
|
||||
if (tsm !== wwwAttributes.tsm) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hawk.utils.setNtpOffset(wwwAttributes.ts - Math.floor((new Date()).getTime() / 1000)); // Keep offset at 1 second precision
|
||||
}
|
||||
}
|
||||
|
||||
// Parse HTTP Server-Authorization header
|
||||
|
||||
var serverAuthorization = getHeader('server-authorization');
|
||||
if (!serverAuthorization &&
|
||||
!options.required) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
var attributes = hawk.utils.parseAuthorizationHeader(serverAuthorization, ['mac', 'ext', 'hash']);
|
||||
if (!attributes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var modArtifacts = {
|
||||
ts: artifacts.ts,
|
||||
nonce: artifacts.nonce,
|
||||
method: artifacts.method,
|
||||
resource: artifacts.resource,
|
||||
host: artifacts.host,
|
||||
port: artifacts.port,
|
||||
hash: attributes.hash,
|
||||
ext: attributes.ext,
|
||||
app: artifacts.app,
|
||||
dlg: artifacts.dlg
|
||||
};
|
||||
|
||||
var mac = hawk.crypto.calculateMac('response', credentials, modArtifacts);
|
||||
if (mac !== attributes.mac) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!options.payload &&
|
||||
options.payload !== '') {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!attributes.hash) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var calculatedHash = hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, getHeader('content-type'));
|
||||
return (calculatedHash === attributes.hash);
|
||||
},
|
||||
|
||||
message: function (host, port, message, options) {
|
||||
|
||||
// Validate inputs
|
||||
|
||||
if (!host || typeof host !== 'string' ||
|
||||
!port || typeof port !== 'number' ||
|
||||
message === null || message === undefined || typeof message !== 'string' ||
|
||||
!options || typeof options !== 'object') {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Application time
|
||||
|
||||
var timestamp = options.timestamp || hawk.utils.now(options.localtimeOffsetMsec);
|
||||
|
||||
// Validate credentials
|
||||
|
||||
var credentials = options.credentials;
|
||||
if (!credentials ||
|
||||
!credentials.id ||
|
||||
!credentials.key ||
|
||||
!credentials.algorithm) {
|
||||
|
||||
// Invalid credential object
|
||||
return null;
|
||||
}
|
||||
|
||||
if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Calculate signature
|
||||
|
||||
var artifacts = {
|
||||
ts: timestamp,
|
||||
nonce: options.nonce || hawk.utils.randomString(6),
|
||||
host: host,
|
||||
port: port,
|
||||
hash: hawk.crypto.calculatePayloadHash(message, credentials.algorithm)
|
||||
};
|
||||
|
||||
// Construct authorization
|
||||
|
||||
var result = {
|
||||
id: credentials.id,
|
||||
ts: artifacts.ts,
|
||||
nonce: artifacts.nonce,
|
||||
hash: artifacts.hash,
|
||||
mac: hawk.crypto.calculateMac('message', credentials, artifacts)
|
||||
};
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
authenticateTimestamp: function (message, credentials, updateClock) { // updateClock defaults to true
|
||||
|
||||
var tsm = hawk.crypto.calculateTsMac(message.ts, credentials);
|
||||
if (tsm !== message.tsm) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (updateClock !== false) {
|
||||
hawk.utils.setNtpOffset(message.ts - Math.floor((new Date()).getTime() / 1000)); // Keep offset at 1 second precision
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
hawk.crypto = {
|
||||
|
||||
headerVersion: '1',
|
||||
|
||||
algorithms: ['sha1', 'sha256'],
|
||||
|
||||
calculateMac: function (type, credentials, options) {
|
||||
|
||||
var normalized = hawk.crypto.generateNormalizedString(type, options);
|
||||
|
||||
var hmac = CryptoJS['Hmac' + credentials.algorithm.toUpperCase()](normalized, credentials.key);
|
||||
return hmac.toString(CryptoJS.enc.Base64);
|
||||
},
|
||||
|
||||
generateNormalizedString: function (type, options) {
|
||||
|
||||
var normalized = 'hawk.' + hawk.crypto.headerVersion + '.' + type + '\n' +
|
||||
options.ts + '\n' +
|
||||
options.nonce + '\n' +
|
||||
(options.method || '').toUpperCase() + '\n' +
|
||||
(options.resource || '') + '\n' +
|
||||
options.host.toLowerCase() + '\n' +
|
||||
options.port + '\n' +
|
||||
(options.hash || '') + '\n';
|
||||
|
||||
if (options.ext) {
|
||||
normalized += options.ext.replace('\\', '\\\\').replace('\n', '\\n');
|
||||
}
|
||||
|
||||
normalized += '\n';
|
||||
|
||||
if (options.app) {
|
||||
normalized += options.app + '\n' +
|
||||
(options.dlg || '') + '\n';
|
||||
}
|
||||
|
||||
return normalized;
|
||||
},
|
||||
|
||||
calculatePayloadHash: function (payload, algorithm, contentType) {
|
||||
|
||||
var hash = CryptoJS.algo[algorithm.toUpperCase()].create();
|
||||
hash.update('hawk.' + hawk.crypto.headerVersion + '.payload\n');
|
||||
hash.update(hawk.utils.parseContentType(contentType) + '\n');
|
||||
hash.update(payload);
|
||||
hash.update('\n');
|
||||
return hash.finalize().toString(CryptoJS.enc.Base64);
|
||||
},
|
||||
|
||||
calculateTsMac: function (ts, credentials) {
|
||||
|
||||
var hash = CryptoJS['Hmac' + credentials.algorithm.toUpperCase()]('hawk.' + hawk.crypto.headerVersion + '.ts\n' + ts + '\n', credentials.key);
|
||||
return hash.toString(CryptoJS.enc.Base64);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// localStorage compatible interface
|
||||
|
||||
hawk.internals.LocalStorage = function () {
|
||||
|
||||
this._cache = {};
|
||||
this.length = 0;
|
||||
|
||||
this.getItem = function (key) {
|
||||
|
||||
return this._cache.hasOwnProperty(key) ? String(this._cache[key]) : null;
|
||||
};
|
||||
|
||||
this.setItem = function (key, value) {
|
||||
|
||||
this._cache[key] = String(value);
|
||||
this.length = Object.keys(this._cache).length;
|
||||
};
|
||||
|
||||
this.removeItem = function (key) {
|
||||
|
||||
delete this._cache[key];
|
||||
this.length = Object.keys(this._cache).length;
|
||||
};
|
||||
|
||||
this.clear = function () {
|
||||
|
||||
this._cache = {};
|
||||
this.length = 0;
|
||||
};
|
||||
|
||||
this.key = function (i) {
|
||||
|
||||
return Object.keys(this._cache)[i || 0];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
hawk.utils = {
|
||||
|
||||
storage: new hawk.internals.LocalStorage(),
|
||||
|
||||
setStorage: function (storage) {
|
||||
|
||||
var ntpOffset = hawk.utils.storage.getItem('hawk_ntp_offset');
|
||||
hawk.utils.storage = storage;
|
||||
if (ntpOffset) {
|
||||
hawk.utils.setNtpOffset(ntpOffset);
|
||||
}
|
||||
},
|
||||
|
||||
setNtpOffset: function (offset) {
|
||||
|
||||
try {
|
||||
hawk.utils.storage.setItem('hawk_ntp_offset', offset);
|
||||
}
|
||||
catch (err) {
|
||||
console.error('[hawk] could not write to storage.');
|
||||
console.error(err);
|
||||
}
|
||||
},
|
||||
|
||||
getNtpOffset: function () {
|
||||
|
||||
var offset = hawk.utils.storage.getItem('hawk_ntp_offset');
|
||||
if (!offset) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return parseInt(offset, 10);
|
||||
},
|
||||
|
||||
now: function (localtimeOffsetMsec) {
|
||||
|
||||
return Math.floor(((new Date()).getTime() + (localtimeOffsetMsec || 0)) / 1000) + hawk.utils.getNtpOffset();
|
||||
},
|
||||
|
||||
escapeHeaderAttribute: function (attribute) {
|
||||
|
||||
return attribute.replace(/\\/g, '\\\\').replace(/\"/g, '\\"');
|
||||
},
|
||||
|
||||
parseContentType: function (header) {
|
||||
|
||||
if (!header) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return header.split(';')[0].replace(/^\s+|\s+$/g, '').toLowerCase();
|
||||
},
|
||||
|
||||
parseAuthorizationHeader: function (header, keys) {
|
||||
|
||||
if (!header) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var headerParts = header.match(/^(\w+)(?:\s+(.*))?$/); // Header: scheme[ something]
|
||||
if (!headerParts) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var scheme = headerParts[1];
|
||||
if (scheme.toLowerCase() !== 'hawk') {
|
||||
return null;
|
||||
}
|
||||
|
||||
var attributesString = headerParts[2];
|
||||
if (!attributesString) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var attributes = {};
|
||||
var verify = attributesString.replace(/(\w+)="([^"\\]*)"\s*(?:,\s*|$)/g, function ($0, $1, $2) {
|
||||
|
||||
// Check valid attribute names
|
||||
|
||||
if (keys.indexOf($1) === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Allowed attribute value characters: !#$%&'()*+,-./:;<=>?@[]^_`{|}~ and space, a-z, A-Z, 0-9
|
||||
|
||||
if ($2.match(/^[ \w\!#\$%&'\(\)\*\+,\-\.\/\:;<\=>\?@\[\]\^`\{\|\}~]+$/) === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for duplicates
|
||||
|
||||
if (attributes.hasOwnProperty($1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
attributes[$1] = $2;
|
||||
return '';
|
||||
});
|
||||
|
||||
if (verify !== '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return attributes;
|
||||
},
|
||||
|
||||
randomString: function (size) {
|
||||
|
||||
var randomSource = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||
var len = randomSource.length;
|
||||
|
||||
var result = [];
|
||||
for (var i = 0; i < size; ++i) {
|
||||
result[i] = randomSource[Math.floor(Math.random() * len)];
|
||||
}
|
||||
|
||||
return result.join('');
|
||||
},
|
||||
|
||||
uriRegex: /^([^:]+)\:\/\/(?:[^@]*@)?([^\/:]+)(?:\:(\d+))?([^#]*)(?:#.*)?$/, // scheme://credentials@host:port/resource#fragment
|
||||
parseUri: function (input) {
|
||||
|
||||
var parts = input.match(hawk.utils.uriRegex);
|
||||
if (!parts) {
|
||||
return { host: '', port: '', resource: '' };
|
||||
}
|
||||
|
||||
var scheme = parts[1].toLowerCase();
|
||||
var uri = {
|
||||
host: parts[2],
|
||||
port: parts[3] || (scheme === 'http' ? '80' : (scheme === 'https' ? '443' : '')),
|
||||
resource: parts[4]
|
||||
};
|
||||
|
||||
return uri;
|
||||
},
|
||||
|
||||
base64urlEncode: function (value) {
|
||||
|
||||
var wordArray = CryptoJS.enc.Utf8.parse(value);
|
||||
var encoded = CryptoJS.enc.Base64.stringify(wordArray);
|
||||
return encoded.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// $lab:coverage:off$
|
||||
/* eslint-disable */
|
||||
|
||||
// Based on: Crypto-JS v3.1.2
|
||||
// Copyright (c) 2009-2013, Jeff Mott. All rights reserved.
|
||||
// http://code.google.com/p/crypto-js/
|
||||
// http://code.google.com/p/crypto-js/wiki/License
|
||||
|
||||
var CryptoJS = CryptoJS || function (h, r) { var k = {}, l = k.lib = {}, n = function () { }, f = l.Base = { extend: function (a) { n.prototype = this; var b = new n; a && b.mixIn(a); b.hasOwnProperty("init") || (b.init = function () { b.$super.init.apply(this, arguments) }); b.init.prototype = b; b.$super = this; return b }, create: function () { var a = this.extend(); a.init.apply(a, arguments); return a }, init: function () { }, mixIn: function (a) { for (var b in a) a.hasOwnProperty(b) && (this[b] = a[b]); a.hasOwnProperty("toString") && (this.toString = a.toString) }, clone: function () { return this.init.prototype.extend(this) } }, j = l.WordArray = f.extend({ init: function (a, b) { a = this.words = a || []; this.sigBytes = b != r ? b : 4 * a.length }, toString: function (a) { return (a || s).stringify(this) }, concat: function (a) { var b = this.words, d = a.words, c = this.sigBytes; a = a.sigBytes; this.clamp(); if (c % 4) for (var e = 0; e < a; e++) b[c + e >>> 2] |= (d[e >>> 2] >>> 24 - 8 * (e % 4) & 255) << 24 - 8 * ((c + e) % 4); else if (65535 < d.length) for (e = 0; e < a; e += 4) b[c + e >>> 2] = d[e >>> 2]; else b.push.apply(b, d); this.sigBytes += a; return this }, clamp: function () { var a = this.words, b = this.sigBytes; a[b >>> 2] &= 4294967295 << 32 - 8 * (b % 4); a.length = h.ceil(b / 4) }, clone: function () { var a = f.clone.call(this); a.words = this.words.slice(0); return a }, random: function (a) { for (var b = [], d = 0; d < a; d += 4) b.push(4294967296 * h.random() | 0); return new j.init(b, a) } }), m = k.enc = {}, s = m.Hex = { stringify: function (a) { var b = a.words; a = a.sigBytes; for (var d = [], c = 0; c < a; c++) { var e = b[c >>> 2] >>> 24 - 8 * (c % 4) & 255; d.push((e >>> 4).toString(16)); d.push((e & 15).toString(16)) } return d.join("") }, parse: function (a) { for (var b = a.length, d = [], c = 0; c < b; c += 2) d[c >>> 3] |= parseInt(a.substr(c, 2), 16) << 24 - 4 * (c % 8); return new j.init(d, b / 2) } }, p = m.Latin1 = { stringify: function (a) { var b = a.words; a = a.sigBytes; for (var d = [], c = 0; c < a; c++) d.push(String.fromCharCode(b[c >>> 2] >>> 24 - 8 * (c % 4) & 255)); return d.join("") }, parse: function (a) { for (var b = a.length, d = [], c = 0; c < b; c++) d[c >>> 2] |= (a.charCodeAt(c) & 255) << 24 - 8 * (c % 4); return new j.init(d, b) } }, t = m.Utf8 = { stringify: function (a) { try { return decodeURIComponent(escape(p.stringify(a))) } catch (b) { throw Error("Malformed UTF-8 data"); } }, parse: function (a) { return p.parse(unescape(encodeURIComponent(a))) } }, q = l.BufferedBlockAlgorithm = f.extend({ reset: function () { this._data = new j.init; this._nDataBytes = 0 }, _append: function (a) { "string" == typeof a && (a = t.parse(a)); this._data.concat(a); this._nDataBytes += a.sigBytes }, _process: function (a) { var b = this._data, d = b.words, c = b.sigBytes, e = this.blockSize, f = c / (4 * e), f = a ? h.ceil(f) : h.max((f | 0) - this._minBufferSize, 0); a = f * e; c = h.min(4 * a, c); if (a) { for (var g = 0; g < a; g += e) this._doProcessBlock(d, g); g = d.splice(0, a); b.sigBytes -= c } return new j.init(g, c) }, clone: function () { var a = f.clone.call(this); a._data = this._data.clone(); return a }, _minBufferSize: 0 }); l.Hasher = q.extend({ cfg: f.extend(), init: function (a) { this.cfg = this.cfg.extend(a); this.reset() }, reset: function () { q.reset.call(this); this._doReset() }, update: function (a) { this._append(a); this._process(); return this }, finalize: function (a) { a && this._append(a); return this._doFinalize() }, blockSize: 16, _createHelper: function (a) { return function (b, d) { return (new a.init(d)).finalize(b) } }, _createHmacHelper: function (a) { return function (b, d) { return (new u.HMAC.init(a, d)).finalize(b) } } }); var u = k.algo = {}; return k }(Math);
|
||||
(function () { var k = CryptoJS, b = k.lib, m = b.WordArray, l = b.Hasher, d = [], b = k.algo.SHA1 = l.extend({ _doReset: function () { this._hash = new m.init([1732584193, 4023233417, 2562383102, 271733878, 3285377520]) }, _doProcessBlock: function (n, p) { for (var a = this._hash.words, e = a[0], f = a[1], h = a[2], j = a[3], b = a[4], c = 0; 80 > c; c++) { if (16 > c) d[c] = n[p + c] | 0; else { var g = d[c - 3] ^ d[c - 8] ^ d[c - 14] ^ d[c - 16]; d[c] = g << 1 | g >>> 31 } g = (e << 5 | e >>> 27) + b + d[c]; g = 20 > c ? g + ((f & h | ~f & j) + 1518500249) : 40 > c ? g + ((f ^ h ^ j) + 1859775393) : 60 > c ? g + ((f & h | f & j | h & j) - 1894007588) : g + ((f ^ h ^ j) - 899497514); b = j; j = h; h = f << 30 | f >>> 2; f = e; e = g } a[0] = a[0] + e | 0; a[1] = a[1] + f | 0; a[2] = a[2] + h | 0; a[3] = a[3] + j | 0; a[4] = a[4] + b | 0 }, _doFinalize: function () { var b = this._data, d = b.words, a = 8 * this._nDataBytes, e = 8 * b.sigBytes; d[e >>> 5] |= 128 << 24 - e % 32; d[(e + 64 >>> 9 << 4) + 14] = Math.floor(a / 4294967296); d[(e + 64 >>> 9 << 4) + 15] = a; b.sigBytes = 4 * d.length; this._process(); return this._hash }, clone: function () { var b = l.clone.call(this); b._hash = this._hash.clone(); return b } }); k.SHA1 = l._createHelper(b); k.HmacSHA1 = l._createHmacHelper(b) })();
|
||||
(function (k) { for (var g = CryptoJS, h = g.lib, v = h.WordArray, j = h.Hasher, h = g.algo, s = [], t = [], u = function (q) { return 4294967296 * (q - (q | 0)) | 0 }, l = 2, b = 0; 64 > b;) { var d; a: { d = l; for (var w = k.sqrt(d), r = 2; r <= w; r++) if (!(d % r)) { d = !1; break a } d = !0 } d && (8 > b && (s[b] = u(k.pow(l, 0.5))), t[b] = u(k.pow(l, 1 / 3)), b++); l++ } var n = [], h = h.SHA256 = j.extend({ _doReset: function () { this._hash = new v.init(s.slice(0)) }, _doProcessBlock: function (q, h) { for (var a = this._hash.words, c = a[0], d = a[1], b = a[2], k = a[3], f = a[4], g = a[5], j = a[6], l = a[7], e = 0; 64 > e; e++) { if (16 > e) n[e] = q[h + e] | 0; else { var m = n[e - 15], p = n[e - 2]; n[e] = ((m << 25 | m >>> 7) ^ (m << 14 | m >>> 18) ^ m >>> 3) + n[e - 7] + ((p << 15 | p >>> 17) ^ (p << 13 | p >>> 19) ^ p >>> 10) + n[e - 16] } m = l + ((f << 26 | f >>> 6) ^ (f << 21 | f >>> 11) ^ (f << 7 | f >>> 25)) + (f & g ^ ~f & j) + t[e] + n[e]; p = ((c << 30 | c >>> 2) ^ (c << 19 | c >>> 13) ^ (c << 10 | c >>> 22)) + (c & d ^ c & b ^ d & b); l = j; j = g; g = f; f = k + m | 0; k = b; b = d; d = c; c = m + p | 0 } a[0] = a[0] + c | 0; a[1] = a[1] + d | 0; a[2] = a[2] + b | 0; a[3] = a[3] + k | 0; a[4] = a[4] + f | 0; a[5] = a[5] + g | 0; a[6] = a[6] + j | 0; a[7] = a[7] + l | 0 }, _doFinalize: function () { var d = this._data, b = d.words, a = 8 * this._nDataBytes, c = 8 * d.sigBytes; b[c >>> 5] |= 128 << 24 - c % 32; b[(c + 64 >>> 9 << 4) + 14] = k.floor(a / 4294967296); b[(c + 64 >>> 9 << 4) + 15] = a; d.sigBytes = 4 * b.length; this._process(); return this._hash }, clone: function () { var b = j.clone.call(this); b._hash = this._hash.clone(); return b } }); g.SHA256 = j._createHelper(h); g.HmacSHA256 = j._createHmacHelper(h) })(Math);
|
||||
(function () { var c = CryptoJS, k = c.enc.Utf8; c.algo.HMAC = c.lib.Base.extend({ init: function (a, b) { a = this._hasher = new a.init; "string" == typeof b && (b = k.parse(b)); var c = a.blockSize, e = 4 * c; b.sigBytes > e && (b = a.finalize(b)); b.clamp(); for (var f = this._oKey = b.clone(), g = this._iKey = b.clone(), h = f.words, j = g.words, d = 0; d < c; d++) h[d] ^= 1549556828, j[d] ^= 909522486; f.sigBytes = g.sigBytes = e; this.reset() }, reset: function () { var a = this._hasher; a.reset(); a.update(this._iKey) }, update: function (a) { this._hasher.update(a); return this }, finalize: function (a) { var b = this._hasher; a = b.finalize(a); b.reset(); return b.finalize(this._oKey.clone().concat(a)) } }) })();
|
||||
(function () { var h = CryptoJS, j = h.lib.WordArray; h.enc.Base64 = { stringify: function (b) { var e = b.words, f = b.sigBytes, c = this._map; b.clamp(); b = []; for (var a = 0; a < f; a += 3) for (var d = (e[a >>> 2] >>> 24 - 8 * (a % 4) & 255) << 16 | (e[a + 1 >>> 2] >>> 24 - 8 * ((a + 1) % 4) & 255) << 8 | e[a + 2 >>> 2] >>> 24 - 8 * ((a + 2) % 4) & 255, g = 0; 4 > g && a + 0.75 * g < f; g++) b.push(c.charAt(d >>> 6 * (3 - g) & 63)); if (e = c.charAt(64)) for (; b.length % 4;) b.push(e); return b.join("") }, parse: function (b) { var e = b.length, f = this._map, c = f.charAt(64); c && (c = b.indexOf(c), -1 != c && (e = c)); for (var c = [], a = 0, d = 0; d < e; d++) if (d % 4) { var g = f.indexOf(b.charAt(d - 1)) << 2 * (d % 4), h = f.indexOf(b.charAt(d)) >>> 6 - 2 * (d % 4); c[a >>> 2] |= (g | h) << 24 - 8 * (a % 4); a++ } return j.create(c, a) }, _map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" } })();
|
||||
|
||||
hawk.crypto.internals = CryptoJS;
|
||||
|
||||
|
||||
// Export if used as a module
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = hawk;
|
||||
}
|
||||
|
||||
/* eslint-enable */
|
||||
// $lab:coverage:on$
|
||||
369
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/lib/client.js
generated
vendored
Executable file
369
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/lib/client.js
generated
vendored
Executable file
@ -0,0 +1,369 @@
|
||||
// Load modules
|
||||
|
||||
var Url = require('url');
|
||||
var Hoek = require('hoek');
|
||||
var Cryptiles = require('cryptiles');
|
||||
var Crypto = require('./crypto');
|
||||
var Utils = require('./utils');
|
||||
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
|
||||
// Generate an Authorization header for a given request
|
||||
|
||||
/*
|
||||
uri: 'http://example.com/resource?a=b' or object from Url.parse()
|
||||
method: HTTP verb (e.g. 'GET', 'POST')
|
||||
options: {
|
||||
|
||||
// Required
|
||||
|
||||
credentials: {
|
||||
id: 'dh37fgj492je',
|
||||
key: 'aoijedoaijsdlaksjdl',
|
||||
algorithm: 'sha256' // 'sha1', 'sha256'
|
||||
},
|
||||
|
||||
// Optional
|
||||
|
||||
ext: 'application-specific', // Application specific data sent via the ext attribute
|
||||
timestamp: Date.now(), // A pre-calculated timestamp
|
||||
nonce: '2334f34f', // A pre-generated nonce
|
||||
localtimeOffsetMsec: 400, // Time offset to sync with server time (ignored if timestamp provided)
|
||||
payload: '{"some":"payload"}', // UTF-8 encoded string for body hash generation (ignored if hash provided)
|
||||
contentType: 'application/json', // Payload content-type (ignored if hash provided)
|
||||
hash: 'U4MKKSmiVxk37JCCrAVIjV=', // Pre-calculated payload hash
|
||||
app: '24s23423f34dx', // Oz application id
|
||||
dlg: '234sz34tww3sd' // Oz delegated-by application id
|
||||
}
|
||||
*/
|
||||
|
||||
exports.header = function (uri, method, options) {
|
||||
|
||||
var result = {
|
||||
field: '',
|
||||
artifacts: {}
|
||||
};
|
||||
|
||||
// Validate inputs
|
||||
|
||||
if (!uri || (typeof uri !== 'string' && typeof uri !== 'object') ||
|
||||
!method || typeof method !== 'string' ||
|
||||
!options || typeof options !== 'object') {
|
||||
|
||||
result.err = 'Invalid argument type';
|
||||
return result;
|
||||
}
|
||||
|
||||
// Application time
|
||||
|
||||
var timestamp = options.timestamp || Utils.nowSecs(options.localtimeOffsetMsec);
|
||||
|
||||
// Validate credentials
|
||||
|
||||
var credentials = options.credentials;
|
||||
if (!credentials ||
|
||||
!credentials.id ||
|
||||
!credentials.key ||
|
||||
!credentials.algorithm) {
|
||||
|
||||
result.err = 'Invalid credential object';
|
||||
return result;
|
||||
}
|
||||
|
||||
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
|
||||
result.err = 'Unknown algorithm';
|
||||
return result;
|
||||
}
|
||||
|
||||
// Parse URI
|
||||
|
||||
if (typeof uri === 'string') {
|
||||
uri = Url.parse(uri);
|
||||
}
|
||||
|
||||
// Calculate signature
|
||||
|
||||
var artifacts = {
|
||||
ts: timestamp,
|
||||
nonce: options.nonce || Cryptiles.randomString(6),
|
||||
method: method,
|
||||
resource: uri.pathname + (uri.search || ''), // Maintain trailing '?'
|
||||
host: uri.hostname,
|
||||
port: uri.port || (uri.protocol === 'http:' ? 80 : 443),
|
||||
hash: options.hash,
|
||||
ext: options.ext,
|
||||
app: options.app,
|
||||
dlg: options.dlg
|
||||
};
|
||||
|
||||
result.artifacts = artifacts;
|
||||
|
||||
// Calculate payload hash
|
||||
|
||||
if (!artifacts.hash &&
|
||||
(options.payload || options.payload === '')) {
|
||||
|
||||
artifacts.hash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType);
|
||||
}
|
||||
|
||||
var mac = Crypto.calculateMac('header', credentials, artifacts);
|
||||
|
||||
// Construct header
|
||||
|
||||
var hasExt = artifacts.ext !== null && artifacts.ext !== undefined && artifacts.ext !== ''; // Other falsey values allowed
|
||||
var header = 'Hawk id="' + credentials.id +
|
||||
'", ts="' + artifacts.ts +
|
||||
'", nonce="' + artifacts.nonce +
|
||||
(artifacts.hash ? '", hash="' + artifacts.hash : '') +
|
||||
(hasExt ? '", ext="' + Hoek.escapeHeaderAttribute(artifacts.ext) : '') +
|
||||
'", mac="' + mac + '"';
|
||||
|
||||
if (artifacts.app) {
|
||||
header += ', app="' + artifacts.app +
|
||||
(artifacts.dlg ? '", dlg="' + artifacts.dlg : '') + '"';
|
||||
}
|
||||
|
||||
result.field = header;
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
// Validate server response
|
||||
|
||||
/*
|
||||
res: node's response object
|
||||
artifacts: object received from header().artifacts
|
||||
options: {
|
||||
payload: optional payload received
|
||||
required: specifies if a Server-Authorization header is required. Defaults to 'false'
|
||||
}
|
||||
*/
|
||||
|
||||
exports.authenticate = function (res, credentials, artifacts, options) {
|
||||
|
||||
artifacts = Hoek.clone(artifacts);
|
||||
options = options || {};
|
||||
|
||||
if (res.headers['www-authenticate']) {
|
||||
|
||||
// Parse HTTP WWW-Authenticate header
|
||||
|
||||
var wwwAttributes = Utils.parseAuthorizationHeader(res.headers['www-authenticate'], ['ts', 'tsm', 'error']);
|
||||
if (wwwAttributes instanceof Error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate server timestamp (not used to update clock since it is done via the SNPT client)
|
||||
|
||||
if (wwwAttributes.ts) {
|
||||
var tsm = Crypto.calculateTsMac(wwwAttributes.ts, credentials);
|
||||
if (tsm !== wwwAttributes.tsm) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse HTTP Server-Authorization header
|
||||
|
||||
if (!res.headers['server-authorization'] &&
|
||||
!options.required) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
var attributes = Utils.parseAuthorizationHeader(res.headers['server-authorization'], ['mac', 'ext', 'hash']);
|
||||
if (attributes instanceof Error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
artifacts.ext = attributes.ext;
|
||||
artifacts.hash = attributes.hash;
|
||||
|
||||
var mac = Crypto.calculateMac('response', credentials, artifacts);
|
||||
if (mac !== attributes.mac) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!options.payload &&
|
||||
options.payload !== '') {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!attributes.hash) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var calculatedHash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, res.headers['content-type']);
|
||||
return (calculatedHash === attributes.hash);
|
||||
};
|
||||
|
||||
|
||||
// Generate a bewit value for a given URI
|
||||
|
||||
/*
|
||||
uri: 'http://example.com/resource?a=b' or object from Url.parse()
|
||||
options: {
|
||||
|
||||
// Required
|
||||
|
||||
credentials: {
|
||||
id: 'dh37fgj492je',
|
||||
key: 'aoijedoaijsdlaksjdl',
|
||||
algorithm: 'sha256' // 'sha1', 'sha256'
|
||||
},
|
||||
ttlSec: 60 * 60, // TTL in seconds
|
||||
|
||||
// Optional
|
||||
|
||||
ext: 'application-specific', // Application specific data sent via the ext attribute
|
||||
localtimeOffsetMsec: 400 // Time offset to sync with server time
|
||||
};
|
||||
*/
|
||||
|
||||
exports.getBewit = function (uri, options) {
|
||||
|
||||
// Validate inputs
|
||||
|
||||
if (!uri ||
|
||||
(typeof uri !== 'string' && typeof uri !== 'object') ||
|
||||
!options ||
|
||||
typeof options !== 'object' ||
|
||||
!options.ttlSec) {
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
options.ext = (options.ext === null || options.ext === undefined ? '' : options.ext); // Zero is valid value
|
||||
|
||||
// Application time
|
||||
|
||||
var now = Utils.now(options.localtimeOffsetMsec);
|
||||
|
||||
// Validate credentials
|
||||
|
||||
var credentials = options.credentials;
|
||||
if (!credentials ||
|
||||
!credentials.id ||
|
||||
!credentials.key ||
|
||||
!credentials.algorithm) {
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Parse URI
|
||||
|
||||
if (typeof uri === 'string') {
|
||||
uri = Url.parse(uri);
|
||||
}
|
||||
|
||||
// Calculate signature
|
||||
|
||||
var exp = Math.floor(now / 1000) + options.ttlSec;
|
||||
var mac = Crypto.calculateMac('bewit', credentials, {
|
||||
ts: exp,
|
||||
nonce: '',
|
||||
method: 'GET',
|
||||
resource: uri.pathname + (uri.search || ''), // Maintain trailing '?'
|
||||
host: uri.hostname,
|
||||
port: uri.port || (uri.protocol === 'http:' ? 80 : 443),
|
||||
ext: options.ext
|
||||
});
|
||||
|
||||
// Construct bewit: id\exp\mac\ext
|
||||
|
||||
var bewit = credentials.id + '\\' + exp + '\\' + mac + '\\' + options.ext;
|
||||
return Hoek.base64urlEncode(bewit);
|
||||
};
|
||||
|
||||
|
||||
// Generate an authorization string for a message
|
||||
|
||||
/*
|
||||
host: 'example.com',
|
||||
port: 8000,
|
||||
message: '{"some":"payload"}', // UTF-8 encoded string for body hash generation
|
||||
options: {
|
||||
|
||||
// Required
|
||||
|
||||
credentials: {
|
||||
id: 'dh37fgj492je',
|
||||
key: 'aoijedoaijsdlaksjdl',
|
||||
algorithm: 'sha256' // 'sha1', 'sha256'
|
||||
},
|
||||
|
||||
// Optional
|
||||
|
||||
timestamp: Date.now(), // A pre-calculated timestamp
|
||||
nonce: '2334f34f', // A pre-generated nonce
|
||||
localtimeOffsetMsec: 400, // Time offset to sync with server time (ignored if timestamp provided)
|
||||
}
|
||||
*/
|
||||
|
||||
exports.message = function (host, port, message, options) {
|
||||
|
||||
// Validate inputs
|
||||
|
||||
if (!host || typeof host !== 'string' ||
|
||||
!port || typeof port !== 'number' ||
|
||||
message === null || message === undefined || typeof message !== 'string' ||
|
||||
!options || typeof options !== 'object') {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Application time
|
||||
|
||||
var timestamp = options.timestamp || Utils.nowSecs(options.localtimeOffsetMsec);
|
||||
|
||||
// Validate credentials
|
||||
|
||||
var credentials = options.credentials;
|
||||
if (!credentials ||
|
||||
!credentials.id ||
|
||||
!credentials.key ||
|
||||
!credentials.algorithm) {
|
||||
|
||||
// Invalid credential object
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Calculate signature
|
||||
|
||||
var artifacts = {
|
||||
ts: timestamp,
|
||||
nonce: options.nonce || Cryptiles.randomString(6),
|
||||
host: host,
|
||||
port: port,
|
||||
hash: Crypto.calculatePayloadHash(message, credentials.algorithm)
|
||||
};
|
||||
|
||||
// Construct authorization
|
||||
|
||||
var result = {
|
||||
id: credentials.id,
|
||||
ts: artifacts.ts,
|
||||
nonce: artifacts.nonce,
|
||||
hash: artifacts.hash,
|
||||
mac: Crypto.calculateMac('message', credentials, artifacts)
|
||||
};
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
|
||||
126
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/lib/crypto.js
generated
vendored
Executable file
126
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/lib/crypto.js
generated
vendored
Executable file
@ -0,0 +1,126 @@
|
||||
// Load modules
|
||||
|
||||
var Crypto = require('crypto');
|
||||
var Url = require('url');
|
||||
var Utils = require('./utils');
|
||||
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
|
||||
// MAC normalization format version
|
||||
|
||||
exports.headerVersion = '1'; // Prevent comparison of mac values generated with different normalized string formats
|
||||
|
||||
|
||||
// Supported HMAC algorithms
|
||||
|
||||
exports.algorithms = ['sha1', 'sha256'];
|
||||
|
||||
|
||||
// Calculate the request MAC
|
||||
|
||||
/*
|
||||
type: 'header', // 'header', 'bewit', 'response'
|
||||
credentials: {
|
||||
key: 'aoijedoaijsdlaksjdl',
|
||||
algorithm: 'sha256' // 'sha1', 'sha256'
|
||||
},
|
||||
options: {
|
||||
method: 'GET',
|
||||
resource: '/resource?a=1&b=2',
|
||||
host: 'example.com',
|
||||
port: 8080,
|
||||
ts: 1357718381034,
|
||||
nonce: 'd3d345f',
|
||||
hash: 'U4MKKSmiVxk37JCCrAVIjV/OhB3y+NdwoCr6RShbVkE=',
|
||||
ext: 'app-specific-data',
|
||||
app: 'hf48hd83qwkj', // Application id (Oz)
|
||||
dlg: 'd8djwekds9cj' // Delegated by application id (Oz), requires options.app
|
||||
}
|
||||
*/
|
||||
|
||||
exports.calculateMac = function (type, credentials, options) {
|
||||
|
||||
var normalized = exports.generateNormalizedString(type, options);
|
||||
|
||||
var hmac = Crypto.createHmac(credentials.algorithm, credentials.key).update(normalized);
|
||||
var digest = hmac.digest('base64');
|
||||
return digest;
|
||||
};
|
||||
|
||||
|
||||
exports.generateNormalizedString = function (type, options) {
|
||||
|
||||
var resource = options.resource || '';
|
||||
if (resource &&
|
||||
resource[0] !== '/') {
|
||||
|
||||
var url = Url.parse(resource, false);
|
||||
resource = url.path; // Includes query
|
||||
}
|
||||
|
||||
var normalized = 'hawk.' + exports.headerVersion + '.' + type + '\n' +
|
||||
options.ts + '\n' +
|
||||
options.nonce + '\n' +
|
||||
(options.method || '').toUpperCase() + '\n' +
|
||||
resource + '\n' +
|
||||
options.host.toLowerCase() + '\n' +
|
||||
options.port + '\n' +
|
||||
(options.hash || '') + '\n';
|
||||
|
||||
if (options.ext) {
|
||||
normalized += options.ext.replace('\\', '\\\\').replace('\n', '\\n');
|
||||
}
|
||||
|
||||
normalized += '\n';
|
||||
|
||||
if (options.app) {
|
||||
normalized += options.app + '\n' +
|
||||
(options.dlg || '') + '\n';
|
||||
}
|
||||
|
||||
return normalized;
|
||||
};
|
||||
|
||||
|
||||
exports.calculatePayloadHash = function (payload, algorithm, contentType) {
|
||||
|
||||
var hash = exports.initializePayloadHash(algorithm, contentType);
|
||||
hash.update(payload || '');
|
||||
return exports.finalizePayloadHash(hash);
|
||||
};
|
||||
|
||||
|
||||
exports.initializePayloadHash = function (algorithm, contentType) {
|
||||
|
||||
var hash = Crypto.createHash(algorithm);
|
||||
hash.update('hawk.' + exports.headerVersion + '.payload\n');
|
||||
hash.update(Utils.parseContentType(contentType) + '\n');
|
||||
return hash;
|
||||
};
|
||||
|
||||
|
||||
exports.finalizePayloadHash = function (hash) {
|
||||
|
||||
hash.update('\n');
|
||||
return hash.digest('base64');
|
||||
};
|
||||
|
||||
|
||||
exports.calculateTsMac = function (ts, credentials) {
|
||||
|
||||
var hmac = Crypto.createHmac(credentials.algorithm, credentials.key);
|
||||
hmac.update('hawk.' + exports.headerVersion + '.ts\n' + ts + '\n');
|
||||
return hmac.digest('base64');
|
||||
};
|
||||
|
||||
|
||||
exports.timestampMessage = function (credentials, localtimeOffsetMsec) {
|
||||
|
||||
var now = Utils.nowSecs(localtimeOffsetMsec);
|
||||
var tsm = exports.calculateTsMac(now, credentials);
|
||||
return { ts: now, tsm: tsm };
|
||||
};
|
||||
15
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/lib/index.js
generated
vendored
Executable file
15
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/lib/index.js
generated
vendored
Executable file
@ -0,0 +1,15 @@
|
||||
// Export sub-modules
|
||||
|
||||
exports.error = exports.Error = require('boom');
|
||||
exports.sntp = require('sntp');
|
||||
|
||||
exports.server = require('./server');
|
||||
exports.client = require('./client');
|
||||
exports.crypto = require('./crypto');
|
||||
exports.utils = require('./utils');
|
||||
|
||||
exports.uri = {
|
||||
authenticate: exports.server.authenticateBewit,
|
||||
getBewit: exports.client.getBewit
|
||||
};
|
||||
|
||||
548
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/lib/server.js
generated
vendored
Executable file
548
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/lib/server.js
generated
vendored
Executable file
@ -0,0 +1,548 @@
|
||||
// Load modules
|
||||
|
||||
var Boom = require('boom');
|
||||
var Hoek = require('hoek');
|
||||
var Cryptiles = require('cryptiles');
|
||||
var Crypto = require('./crypto');
|
||||
var Utils = require('./utils');
|
||||
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
|
||||
// Hawk authentication
|
||||
|
||||
/*
|
||||
req: node's HTTP request object or an object as follows:
|
||||
|
||||
var request = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?a=1&b=2',
|
||||
host: 'example.com',
|
||||
port: 8080,
|
||||
authorization: 'Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", ext="some-app-ext-data", mac="6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE="'
|
||||
};
|
||||
|
||||
credentialsFunc: required function to lookup the set of Hawk credentials based on the provided credentials id.
|
||||
The credentials include the MAC key, MAC algorithm, and other attributes (such as username)
|
||||
needed by the application. This function is the equivalent of verifying the username and
|
||||
password in Basic authentication.
|
||||
|
||||
var credentialsFunc = function (id, callback) {
|
||||
|
||||
// Lookup credentials in database
|
||||
db.lookup(id, function (err, item) {
|
||||
|
||||
if (err || !item) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
var credentials = {
|
||||
// Required
|
||||
key: item.key,
|
||||
algorithm: item.algorithm,
|
||||
// Application specific
|
||||
user: item.user
|
||||
};
|
||||
|
||||
return callback(null, credentials);
|
||||
});
|
||||
};
|
||||
|
||||
options: {
|
||||
|
||||
hostHeaderName: optional header field name, used to override the default 'Host' header when used
|
||||
behind a cache of a proxy. Apache2 changes the value of the 'Host' header while preserving
|
||||
the original (which is what the module must verify) in the 'x-forwarded-host' header field.
|
||||
Only used when passed a node Http.ServerRequest object.
|
||||
|
||||
nonceFunc: optional nonce validation function. The function signature is function(key, nonce, ts, callback)
|
||||
where 'callback' must be called using the signature function(err).
|
||||
|
||||
timestampSkewSec: optional number of seconds of permitted clock skew for incoming timestamps. Defaults to 60 seconds.
|
||||
Provides a +/- skew which means actual allowed window is double the number of seconds.
|
||||
|
||||
localtimeOffsetMsec: optional local clock time offset express in a number of milliseconds (positive or negative).
|
||||
Defaults to 0.
|
||||
|
||||
payload: optional payload for validation. The client calculates the hash value and includes it via the 'hash'
|
||||
header attribute. The server always ensures the value provided has been included in the request
|
||||
MAC. When this option is provided, it validates the hash value itself. Validation is done by calculating
|
||||
a hash value over the entire payload (assuming it has already be normalized to the same format and
|
||||
encoding used by the client to calculate the hash on request). If the payload is not available at the time
|
||||
of authentication, the authenticatePayload() method can be used by passing it the credentials and
|
||||
attributes.hash returned in the authenticate callback.
|
||||
|
||||
host: optional host name override. Only used when passed a node request object.
|
||||
port: optional port override. Only used when passed a node request object.
|
||||
}
|
||||
|
||||
callback: function (err, credentials, artifacts) { }
|
||||
*/
|
||||
|
||||
exports.authenticate = function (req, credentialsFunc, options, callback) {
|
||||
|
||||
callback = Hoek.nextTick(callback);
|
||||
|
||||
// Default options
|
||||
|
||||
options.nonceFunc = options.nonceFunc || internals.nonceFunc;
|
||||
options.timestampSkewSec = options.timestampSkewSec || 60; // 60 seconds
|
||||
|
||||
// Application time
|
||||
|
||||
var now = Utils.now(options.localtimeOffsetMsec); // Measure now before any other processing
|
||||
|
||||
// Convert node Http request object to a request configuration object
|
||||
|
||||
var request = Utils.parseRequest(req, options);
|
||||
if (request instanceof Error) {
|
||||
return callback(Boom.badRequest(request.message));
|
||||
}
|
||||
|
||||
// Parse HTTP Authorization header
|
||||
|
||||
var attributes = Utils.parseAuthorizationHeader(request.authorization);
|
||||
if (attributes instanceof Error) {
|
||||
return callback(attributes);
|
||||
}
|
||||
|
||||
// Construct artifacts container
|
||||
|
||||
var artifacts = {
|
||||
method: request.method,
|
||||
host: request.host,
|
||||
port: request.port,
|
||||
resource: request.url,
|
||||
ts: attributes.ts,
|
||||
nonce: attributes.nonce,
|
||||
hash: attributes.hash,
|
||||
ext: attributes.ext,
|
||||
app: attributes.app,
|
||||
dlg: attributes.dlg,
|
||||
mac: attributes.mac,
|
||||
id: attributes.id
|
||||
};
|
||||
|
||||
// Verify required header attributes
|
||||
|
||||
if (!attributes.id ||
|
||||
!attributes.ts ||
|
||||
!attributes.nonce ||
|
||||
!attributes.mac) {
|
||||
|
||||
return callback(Boom.badRequest('Missing attributes'), null, artifacts);
|
||||
}
|
||||
|
||||
// Fetch Hawk credentials
|
||||
|
||||
credentialsFunc(attributes.id, function (err, credentials) {
|
||||
|
||||
if (err) {
|
||||
return callback(err, credentials || null, artifacts);
|
||||
}
|
||||
|
||||
if (!credentials) {
|
||||
return callback(Boom.unauthorized('Unknown credentials', 'Hawk'), null, artifacts);
|
||||
}
|
||||
|
||||
if (!credentials.key ||
|
||||
!credentials.algorithm) {
|
||||
|
||||
return callback(Boom.internal('Invalid credentials'), credentials, artifacts);
|
||||
}
|
||||
|
||||
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
|
||||
return callback(Boom.internal('Unknown algorithm'), credentials, artifacts);
|
||||
}
|
||||
|
||||
// Calculate MAC
|
||||
|
||||
var mac = Crypto.calculateMac('header', credentials, artifacts);
|
||||
if (!Cryptiles.fixedTimeComparison(mac, attributes.mac)) {
|
||||
return callback(Boom.unauthorized('Bad mac', 'Hawk'), credentials, artifacts);
|
||||
}
|
||||
|
||||
// Check payload hash
|
||||
|
||||
if (options.payload ||
|
||||
options.payload === '') {
|
||||
|
||||
if (!attributes.hash) {
|
||||
return callback(Boom.unauthorized('Missing required payload hash', 'Hawk'), credentials, artifacts);
|
||||
}
|
||||
|
||||
var hash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, request.contentType);
|
||||
if (!Cryptiles.fixedTimeComparison(hash, attributes.hash)) {
|
||||
return callback(Boom.unauthorized('Bad payload hash', 'Hawk'), credentials, artifacts);
|
||||
}
|
||||
}
|
||||
|
||||
// Check nonce
|
||||
|
||||
options.nonceFunc(credentials.key, attributes.nonce, attributes.ts, function (err) {
|
||||
|
||||
if (err) {
|
||||
return callback(Boom.unauthorized('Invalid nonce', 'Hawk'), credentials, artifacts);
|
||||
}
|
||||
|
||||
// Check timestamp staleness
|
||||
|
||||
if (Math.abs((attributes.ts * 1000) - now) > (options.timestampSkewSec * 1000)) {
|
||||
var tsm = Crypto.timestampMessage(credentials, options.localtimeOffsetMsec);
|
||||
return callback(Boom.unauthorized('Stale timestamp', 'Hawk', tsm), credentials, artifacts);
|
||||
}
|
||||
|
||||
// Successful authentication
|
||||
|
||||
return callback(null, credentials, artifacts);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Authenticate payload hash - used when payload cannot be provided during authenticate()
|
||||
|
||||
/*
|
||||
payload: raw request payload
|
||||
credentials: from authenticate callback
|
||||
artifacts: from authenticate callback
|
||||
contentType: req.headers['content-type']
|
||||
*/
|
||||
|
||||
exports.authenticatePayload = function (payload, credentials, artifacts, contentType) {
|
||||
|
||||
var calculatedHash = Crypto.calculatePayloadHash(payload, credentials.algorithm, contentType);
|
||||
return Cryptiles.fixedTimeComparison(calculatedHash, artifacts.hash);
|
||||
};
|
||||
|
||||
|
||||
// Authenticate payload hash - used when payload cannot be provided during authenticate()
|
||||
|
||||
/*
|
||||
calculatedHash: the payload hash calculated using Crypto.calculatePayloadHash()
|
||||
artifacts: from authenticate callback
|
||||
*/
|
||||
|
||||
exports.authenticatePayloadHash = function (calculatedHash, artifacts) {
|
||||
|
||||
return Cryptiles.fixedTimeComparison(calculatedHash, artifacts.hash);
|
||||
};
|
||||
|
||||
|
||||
// Generate a Server-Authorization header for a given response
|
||||
|
||||
/*
|
||||
credentials: {}, // Object received from authenticate()
|
||||
artifacts: {} // Object received from authenticate(); 'mac', 'hash', and 'ext' - ignored
|
||||
options: {
|
||||
ext: 'application-specific', // Application specific data sent via the ext attribute
|
||||
payload: '{"some":"payload"}', // UTF-8 encoded string for body hash generation (ignored if hash provided)
|
||||
contentType: 'application/json', // Payload content-type (ignored if hash provided)
|
||||
hash: 'U4MKKSmiVxk37JCCrAVIjV=' // Pre-calculated payload hash
|
||||
}
|
||||
*/
|
||||
|
||||
exports.header = function (credentials, artifacts, options) {
|
||||
|
||||
// Prepare inputs
|
||||
|
||||
options = options || {};
|
||||
|
||||
if (!artifacts ||
|
||||
typeof artifacts !== 'object' ||
|
||||
typeof options !== 'object') {
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
artifacts = Hoek.clone(artifacts);
|
||||
delete artifacts.mac;
|
||||
artifacts.hash = options.hash;
|
||||
artifacts.ext = options.ext;
|
||||
|
||||
// Validate credentials
|
||||
|
||||
if (!credentials ||
|
||||
!credentials.key ||
|
||||
!credentials.algorithm) {
|
||||
|
||||
// Invalid credential object
|
||||
return '';
|
||||
}
|
||||
|
||||
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Calculate payload hash
|
||||
|
||||
if (!artifacts.hash &&
|
||||
(options.payload || options.payload === '')) {
|
||||
|
||||
artifacts.hash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType);
|
||||
}
|
||||
|
||||
var mac = Crypto.calculateMac('response', credentials, artifacts);
|
||||
|
||||
// Construct header
|
||||
|
||||
var header = 'Hawk mac="' + mac + '"' +
|
||||
(artifacts.hash ? ', hash="' + artifacts.hash + '"' : '');
|
||||
|
||||
if (artifacts.ext !== null &&
|
||||
artifacts.ext !== undefined &&
|
||||
artifacts.ext !== '') { // Other falsey values allowed
|
||||
|
||||
header += ', ext="' + Hoek.escapeHeaderAttribute(artifacts.ext) + '"';
|
||||
}
|
||||
|
||||
return header;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Arguments and options are the same as authenticate() with the exception that the only supported options are:
|
||||
* 'hostHeaderName', 'localtimeOffsetMsec', 'host', 'port'
|
||||
*/
|
||||
|
||||
|
||||
// 1 2 3 4
|
||||
internals.bewitRegex = /^(\/.*)([\?&])bewit\=([^&$]*)(?:&(.+))?$/;
|
||||
|
||||
|
||||
exports.authenticateBewit = function (req, credentialsFunc, options, callback) {
|
||||
|
||||
callback = Hoek.nextTick(callback);
|
||||
|
||||
// Application time
|
||||
|
||||
var now = Utils.now(options.localtimeOffsetMsec);
|
||||
|
||||
// Convert node Http request object to a request configuration object
|
||||
|
||||
var request = Utils.parseRequest(req, options);
|
||||
if (request instanceof Error) {
|
||||
return callback(Boom.badRequest(request.message));
|
||||
}
|
||||
|
||||
// Extract bewit
|
||||
|
||||
if (request.url.length > Utils.limits.maxMatchLength) {
|
||||
return callback(Boom.badRequest('Resource path exceeds max length'));
|
||||
}
|
||||
|
||||
var resource = request.url.match(internals.bewitRegex);
|
||||
if (!resource) {
|
||||
return callback(Boom.unauthorized(null, 'Hawk'));
|
||||
}
|
||||
|
||||
// Bewit not empty
|
||||
|
||||
if (!resource[3]) {
|
||||
return callback(Boom.unauthorized('Empty bewit', 'Hawk'));
|
||||
}
|
||||
|
||||
// Verify method is GET
|
||||
|
||||
if (request.method !== 'GET' &&
|
||||
request.method !== 'HEAD') {
|
||||
|
||||
return callback(Boom.unauthorized('Invalid method', 'Hawk'));
|
||||
}
|
||||
|
||||
// No other authentication
|
||||
|
||||
if (request.authorization) {
|
||||
return callback(Boom.badRequest('Multiple authentications'));
|
||||
}
|
||||
|
||||
// Parse bewit
|
||||
|
||||
var bewitString = Hoek.base64urlDecode(resource[3]);
|
||||
if (bewitString instanceof Error) {
|
||||
return callback(Boom.badRequest('Invalid bewit encoding'));
|
||||
}
|
||||
|
||||
// Bewit format: id\exp\mac\ext ('\' is used because it is a reserved header attribute character)
|
||||
|
||||
var bewitParts = bewitString.split('\\');
|
||||
if (bewitParts.length !== 4) {
|
||||
return callback(Boom.badRequest('Invalid bewit structure'));
|
||||
}
|
||||
|
||||
var bewit = {
|
||||
id: bewitParts[0],
|
||||
exp: parseInt(bewitParts[1], 10),
|
||||
mac: bewitParts[2],
|
||||
ext: bewitParts[3] || ''
|
||||
};
|
||||
|
||||
if (!bewit.id ||
|
||||
!bewit.exp ||
|
||||
!bewit.mac) {
|
||||
|
||||
return callback(Boom.badRequest('Missing bewit attributes'));
|
||||
}
|
||||
|
||||
// Construct URL without bewit
|
||||
|
||||
var url = resource[1];
|
||||
if (resource[4]) {
|
||||
url += resource[2] + resource[4];
|
||||
}
|
||||
|
||||
// Check expiration
|
||||
|
||||
if (bewit.exp * 1000 <= now) {
|
||||
return callback(Boom.unauthorized('Access expired', 'Hawk'), null, bewit);
|
||||
}
|
||||
|
||||
// Fetch Hawk credentials
|
||||
|
||||
credentialsFunc(bewit.id, function (err, credentials) {
|
||||
|
||||
if (err) {
|
||||
return callback(err, credentials || null, bewit.ext);
|
||||
}
|
||||
|
||||
if (!credentials) {
|
||||
return callback(Boom.unauthorized('Unknown credentials', 'Hawk'), null, bewit);
|
||||
}
|
||||
|
||||
if (!credentials.key ||
|
||||
!credentials.algorithm) {
|
||||
|
||||
return callback(Boom.internal('Invalid credentials'), credentials, bewit);
|
||||
}
|
||||
|
||||
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
|
||||
return callback(Boom.internal('Unknown algorithm'), credentials, bewit);
|
||||
}
|
||||
|
||||
// Calculate MAC
|
||||
|
||||
var mac = Crypto.calculateMac('bewit', credentials, {
|
||||
ts: bewit.exp,
|
||||
nonce: '',
|
||||
method: 'GET',
|
||||
resource: url,
|
||||
host: request.host,
|
||||
port: request.port,
|
||||
ext: bewit.ext
|
||||
});
|
||||
|
||||
if (!Cryptiles.fixedTimeComparison(mac, bewit.mac)) {
|
||||
return callback(Boom.unauthorized('Bad mac', 'Hawk'), credentials, bewit);
|
||||
}
|
||||
|
||||
// Successful authentication
|
||||
|
||||
return callback(null, credentials, bewit);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* options are the same as authenticate() with the exception that the only supported options are:
|
||||
* 'nonceFunc', 'timestampSkewSec', 'localtimeOffsetMsec'
|
||||
*/
|
||||
|
||||
exports.authenticateMessage = function (host, port, message, authorization, credentialsFunc, options, callback) {
|
||||
|
||||
callback = Hoek.nextTick(callback);
|
||||
|
||||
// Default options
|
||||
|
||||
options.nonceFunc = options.nonceFunc || internals.nonceFunc;
|
||||
options.timestampSkewSec = options.timestampSkewSec || 60; // 60 seconds
|
||||
|
||||
// Application time
|
||||
|
||||
var now = Utils.now(options.localtimeOffsetMsec); // Measure now before any other processing
|
||||
|
||||
// Validate authorization
|
||||
|
||||
if (!authorization.id ||
|
||||
!authorization.ts ||
|
||||
!authorization.nonce ||
|
||||
!authorization.hash ||
|
||||
!authorization.mac) {
|
||||
|
||||
return callback(Boom.badRequest('Invalid authorization'));
|
||||
}
|
||||
|
||||
// Fetch Hawk credentials
|
||||
|
||||
credentialsFunc(authorization.id, function (err, credentials) {
|
||||
|
||||
if (err) {
|
||||
return callback(err, credentials || null);
|
||||
}
|
||||
|
||||
if (!credentials) {
|
||||
return callback(Boom.unauthorized('Unknown credentials', 'Hawk'));
|
||||
}
|
||||
|
||||
if (!credentials.key ||
|
||||
!credentials.algorithm) {
|
||||
|
||||
return callback(Boom.internal('Invalid credentials'), credentials);
|
||||
}
|
||||
|
||||
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
|
||||
return callback(Boom.internal('Unknown algorithm'), credentials);
|
||||
}
|
||||
|
||||
// Construct artifacts container
|
||||
|
||||
var artifacts = {
|
||||
ts: authorization.ts,
|
||||
nonce: authorization.nonce,
|
||||
host: host,
|
||||
port: port,
|
||||
hash: authorization.hash
|
||||
};
|
||||
|
||||
// Calculate MAC
|
||||
|
||||
var mac = Crypto.calculateMac('message', credentials, artifacts);
|
||||
if (!Cryptiles.fixedTimeComparison(mac, authorization.mac)) {
|
||||
return callback(Boom.unauthorized('Bad mac', 'Hawk'), credentials);
|
||||
}
|
||||
|
||||
// Check payload hash
|
||||
|
||||
var hash = Crypto.calculatePayloadHash(message, credentials.algorithm);
|
||||
if (!Cryptiles.fixedTimeComparison(hash, authorization.hash)) {
|
||||
return callback(Boom.unauthorized('Bad message hash', 'Hawk'), credentials);
|
||||
}
|
||||
|
||||
// Check nonce
|
||||
|
||||
options.nonceFunc(credentials.key, authorization.nonce, authorization.ts, function (err) {
|
||||
|
||||
if (err) {
|
||||
return callback(Boom.unauthorized('Invalid nonce', 'Hawk'), credentials);
|
||||
}
|
||||
|
||||
// Check timestamp staleness
|
||||
|
||||
if (Math.abs((authorization.ts * 1000) - now) > (options.timestampSkewSec * 1000)) {
|
||||
return callback(Boom.unauthorized('Stale timestamp'), credentials);
|
||||
}
|
||||
|
||||
// Successful authentication
|
||||
|
||||
return callback(null, credentials);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
internals.nonceFunc = function (key, nonce, ts, nonceCallback) {
|
||||
|
||||
return nonceCallback(); // No validation
|
||||
};
|
||||
184
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/lib/utils.js
generated
vendored
Executable file
184
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/lib/utils.js
generated
vendored
Executable file
@ -0,0 +1,184 @@
|
||||
// Load modules
|
||||
|
||||
var Sntp = require('sntp');
|
||||
var Boom = require('boom');
|
||||
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
|
||||
exports.version = function () {
|
||||
|
||||
return require('../package.json').version;
|
||||
};
|
||||
|
||||
|
||||
exports.limits = {
|
||||
maxMatchLength: 4096 // Limit the length of uris and headers to avoid a DoS attack on string matching
|
||||
};
|
||||
|
||||
|
||||
// Extract host and port from request
|
||||
|
||||
// $1 $2
|
||||
internals.hostHeaderRegex = /^(?:(?:\r\n)?\s)*((?:[^:]+)|(?:\[[^\]]+\]))(?::(\d+))?(?:(?:\r\n)?\s)*$/; // (IPv4, hostname)|(IPv6)
|
||||
|
||||
|
||||
exports.parseHost = function (req, hostHeaderName) {
|
||||
|
||||
hostHeaderName = (hostHeaderName ? hostHeaderName.toLowerCase() : 'host');
|
||||
var hostHeader = req.headers[hostHeaderName];
|
||||
if (!hostHeader) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (hostHeader.length > exports.limits.maxMatchLength) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var hostParts = hostHeader.match(internals.hostHeaderRegex);
|
||||
if (!hostParts) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
name: hostParts[1],
|
||||
port: (hostParts[2] ? hostParts[2] : (req.connection && req.connection.encrypted ? 443 : 80))
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Parse Content-Type header content
|
||||
|
||||
exports.parseContentType = function (header) {
|
||||
|
||||
if (!header) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return header.split(';')[0].trim().toLowerCase();
|
||||
};
|
||||
|
||||
|
||||
// Convert node's to request configuration object
|
||||
|
||||
exports.parseRequest = function (req, options) {
|
||||
|
||||
if (!req.headers) {
|
||||
return req;
|
||||
}
|
||||
|
||||
// Obtain host and port information
|
||||
|
||||
var host;
|
||||
if (!options.host ||
|
||||
!options.port) {
|
||||
|
||||
host = exports.parseHost(req, options.hostHeaderName);
|
||||
if (!host) {
|
||||
return new Error('Invalid Host header');
|
||||
}
|
||||
}
|
||||
|
||||
var request = {
|
||||
method: req.method,
|
||||
url: req.url,
|
||||
host: options.host || host.name,
|
||||
port: options.port || host.port,
|
||||
authorization: req.headers.authorization,
|
||||
contentType: req.headers['content-type'] || ''
|
||||
};
|
||||
|
||||
return request;
|
||||
};
|
||||
|
||||
|
||||
exports.now = function (localtimeOffsetMsec) {
|
||||
|
||||
return Sntp.now() + (localtimeOffsetMsec || 0);
|
||||
};
|
||||
|
||||
|
||||
exports.nowSecs = function (localtimeOffsetMsec) {
|
||||
|
||||
return Math.floor(exports.now(localtimeOffsetMsec) / 1000);
|
||||
};
|
||||
|
||||
|
||||
internals.authHeaderRegex = /^(\w+)(?:\s+(.*))?$/; // Header: scheme[ something]
|
||||
internals.attributeRegex = /^[ \w\!#\$%&'\(\)\*\+,\-\.\/\:;<\=>\?@\[\]\^`\{\|\}~]+$/; // !#$%&'()*+,-./:;<=>?@[]^_`{|}~ and space, a-z, A-Z, 0-9
|
||||
|
||||
|
||||
// Parse Hawk HTTP Authorization header
|
||||
|
||||
exports.parseAuthorizationHeader = function (header, keys) {
|
||||
|
||||
keys = keys || ['id', 'ts', 'nonce', 'hash', 'ext', 'mac', 'app', 'dlg'];
|
||||
|
||||
if (!header) {
|
||||
return Boom.unauthorized(null, 'Hawk');
|
||||
}
|
||||
|
||||
if (header.length > exports.limits.maxMatchLength) {
|
||||
return Boom.badRequest('Header length too long');
|
||||
}
|
||||
|
||||
var headerParts = header.match(internals.authHeaderRegex);
|
||||
if (!headerParts) {
|
||||
return Boom.badRequest('Invalid header syntax');
|
||||
}
|
||||
|
||||
var scheme = headerParts[1];
|
||||
if (scheme.toLowerCase() !== 'hawk') {
|
||||
return Boom.unauthorized(null, 'Hawk');
|
||||
}
|
||||
|
||||
var attributesString = headerParts[2];
|
||||
if (!attributesString) {
|
||||
return Boom.badRequest('Invalid header syntax');
|
||||
}
|
||||
|
||||
var attributes = {};
|
||||
var errorMessage = '';
|
||||
var verify = attributesString.replace(/(\w+)="([^"\\]*)"\s*(?:,\s*|$)/g, function ($0, $1, $2) {
|
||||
|
||||
// Check valid attribute names
|
||||
|
||||
if (keys.indexOf($1) === -1) {
|
||||
errorMessage = 'Unknown attribute: ' + $1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Allowed attribute value characters
|
||||
|
||||
if ($2.match(internals.attributeRegex) === null) {
|
||||
errorMessage = 'Bad attribute value: ' + $1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for duplicates
|
||||
|
||||
if (attributes.hasOwnProperty($1)) {
|
||||
errorMessage = 'Duplicate attribute: ' + $1;
|
||||
return;
|
||||
}
|
||||
|
||||
attributes[$1] = $2;
|
||||
return '';
|
||||
});
|
||||
|
||||
if (verify !== '') {
|
||||
return Boom.badRequest(errorMessage || 'Bad header format');
|
||||
}
|
||||
|
||||
return attributes;
|
||||
};
|
||||
|
||||
|
||||
exports.unauthorized = function (message, attributes) {
|
||||
|
||||
return Boom.unauthorized(message, 'Hawk', attributes);
|
||||
};
|
||||
|
||||
70
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/package.json
generated
vendored
Executable file
70
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/package.json
generated
vendored
Executable file
@ -0,0 +1,70 @@
|
||||
{
|
||||
"_from": "hawk@~3.1.3",
|
||||
"_id": "hawk@3.1.3",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
|
||||
"_location": "/coveralls/hawk",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "hawk@~3.1.3",
|
||||
"name": "hawk",
|
||||
"escapedName": "hawk",
|
||||
"rawSpec": "~3.1.3",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "~3.1.3"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/coveralls/request"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
|
||||
"_shasum": "078444bd7c1640b0fe540d2c9b73d59678e8e1c4",
|
||||
"_spec": "hawk@~3.1.3",
|
||||
"_where": "/home/manfred/enviPath/ketcher2/ketcher/node_modules/coveralls/node_modules/request",
|
||||
"author": {
|
||||
"name": "Eran Hammer",
|
||||
"email": "eran@hammer.io",
|
||||
"url": "http://hueniverse.com"
|
||||
},
|
||||
"browser": "./lib/browser.js",
|
||||
"bugs": {
|
||||
"url": "https://github.com/hueniverse/hawk/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"contributors": [],
|
||||
"dependencies": {
|
||||
"boom": "2.x.x",
|
||||
"cryptiles": "2.x.x",
|
||||
"hoek": "2.x.x",
|
||||
"sntp": "1.x.x"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "HTTP Hawk Authentication Scheme",
|
||||
"devDependencies": {
|
||||
"code": "1.x.x",
|
||||
"lab": "5.x.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.32"
|
||||
},
|
||||
"homepage": "https://github.com/hueniverse/hawk#readme",
|
||||
"keywords": [
|
||||
"http",
|
||||
"authentication",
|
||||
"scheme",
|
||||
"hawk"
|
||||
],
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "lib/index.js",
|
||||
"name": "hawk",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/hueniverse/hawk.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "lab -a code -t 100 -L",
|
||||
"test-cov-html": "lab -a code -r html -o coverage.html"
|
||||
},
|
||||
"version": "3.1.3"
|
||||
}
|
||||
1492
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/test/browser.js
generated
vendored
Executable file
1492
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/test/browser.js
generated
vendored
Executable file
File diff suppressed because it is too large
Load Diff
440
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/test/client.js
generated
vendored
Executable file
440
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/test/client.js
generated
vendored
Executable file
@ -0,0 +1,440 @@
|
||||
// Load modules
|
||||
|
||||
var Url = require('url');
|
||||
var Code = require('code');
|
||||
var Hawk = require('../lib');
|
||||
var Lab = require('lab');
|
||||
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
|
||||
// Test shortcuts
|
||||
|
||||
var lab = exports.lab = Lab.script();
|
||||
var describe = lab.experiment;
|
||||
var it = lab.test;
|
||||
var expect = Code.expect;
|
||||
|
||||
|
||||
describe('Client', function () {
|
||||
|
||||
describe('header()', function () {
|
||||
|
||||
it('returns a valid authorization header (sha1)', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha1'
|
||||
};
|
||||
|
||||
var header = Hawk.client.header('http://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about' }).field;
|
||||
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="bsvY3IfUllw6V5rvk4tStEvpBhE=", ext="Bazinga!", mac="qbf1ZPG/r/e06F4ht+T77LXi5vw="');
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns a valid authorization header (sha256)', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha256'
|
||||
};
|
||||
|
||||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' }).field;
|
||||
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", ext="Bazinga!", mac="q1CwFoSHzPZSkbIvl0oYlD+91rBUEvFk763nMjMndj8="');
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns a valid authorization header (no ext)', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha256'
|
||||
};
|
||||
|
||||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' }).field;
|
||||
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", mac="HTgtd0jPI6E4izx8e4OHdO36q00xFCU0FolNq3RiCYs="');
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns a valid authorization header (null ext)', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha256'
|
||||
};
|
||||
|
||||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain', ext: null }).field;
|
||||
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", mac="HTgtd0jPI6E4izx8e4OHdO36q00xFCU0FolNq3RiCYs="');
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns a valid authorization header (empty payload)', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha256'
|
||||
};
|
||||
|
||||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: '', contentType: 'text/plain' }).field;
|
||||
expect(header).to.equal('Hawk id=\"123456\", ts=\"1353809207\", nonce=\"Ygvqdz\", hash=\"q/t+NNAkQZNlq/aAD6PlexImwQTxwgT2MahfTa9XRLA=\", mac=\"U5k16YEzn3UnBHKeBzsDXn067Gu3R4YaY6xOt9PYRZM=\"');
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns a valid authorization header (pre hashed payload)', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha256'
|
||||
};
|
||||
|
||||
var options = { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' };
|
||||
options.hash = Hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType);
|
||||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', options).field;
|
||||
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", mac="HTgtd0jPI6E4izx8e4OHdO36q00xFCU0FolNq3RiCYs="');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on missing uri', function (done) {
|
||||
|
||||
var header = Hawk.client.header('', 'POST');
|
||||
expect(header.field).to.equal('');
|
||||
expect(header.err).to.equal('Invalid argument type');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on invalid uri', function (done) {
|
||||
|
||||
var header = Hawk.client.header(4, 'POST');
|
||||
expect(header.field).to.equal('');
|
||||
expect(header.err).to.equal('Invalid argument type');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on missing method', function (done) {
|
||||
|
||||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', '');
|
||||
expect(header.field).to.equal('');
|
||||
expect(header.err).to.equal('Invalid argument type');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on invalid method', function (done) {
|
||||
|
||||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 5);
|
||||
expect(header.field).to.equal('');
|
||||
expect(header.err).to.equal('Invalid argument type');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on missing options', function (done) {
|
||||
|
||||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST');
|
||||
expect(header.field).to.equal('');
|
||||
expect(header.err).to.equal('Invalid argument type');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on invalid credentials (id)', function (done) {
|
||||
|
||||
var credentials = {
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha256'
|
||||
};
|
||||
|
||||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207 });
|
||||
expect(header.field).to.equal('');
|
||||
expect(header.err).to.equal('Invalid credential object');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on missing credentials', function (done) {
|
||||
|
||||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { ext: 'Bazinga!', timestamp: 1353809207 });
|
||||
expect(header.field).to.equal('');
|
||||
expect(header.err).to.equal('Invalid credential object');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on invalid credentials', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
algorithm: 'sha256'
|
||||
};
|
||||
|
||||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207 });
|
||||
expect(header.field).to.equal('');
|
||||
expect(header.err).to.equal('Invalid credential object');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on invalid algorithm', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'hmac-sha-0'
|
||||
};
|
||||
|
||||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, payload: 'something, anything!', ext: 'Bazinga!', timestamp: 1353809207 });
|
||||
expect(header.field).to.equal('');
|
||||
expect(header.err).to.equal('Unknown algorithm');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('authenticate()', function () {
|
||||
|
||||
it('returns false on invalid header', function (done) {
|
||||
|
||||
var res = {
|
||||
headers: {
|
||||
'server-authorization': 'Hawk mac="abc", bad="xyz"'
|
||||
}
|
||||
};
|
||||
|
||||
expect(Hawk.client.authenticate(res, {})).to.equal(false);
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns false on invalid mac', function (done) {
|
||||
|
||||
var res = {
|
||||
headers: {
|
||||
'content-type': 'text/plain',
|
||||
'server-authorization': 'Hawk mac="_IJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"'
|
||||
}
|
||||
};
|
||||
|
||||
var artifacts = {
|
||||
method: 'POST',
|
||||
host: 'example.com',
|
||||
port: '8080',
|
||||
resource: '/resource/4?filter=a',
|
||||
ts: '1362336900',
|
||||
nonce: 'eb5S_L',
|
||||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
|
||||
ext: 'some-app-data',
|
||||
app: undefined,
|
||||
dlg: undefined,
|
||||
mac: 'BlmSe8K+pbKIb6YsZCnt4E1GrYvY1AaYayNR82dGpIk=',
|
||||
id: '123456'
|
||||
};
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
|
||||
algorithm: 'sha256',
|
||||
user: 'steve'
|
||||
};
|
||||
|
||||
expect(Hawk.client.authenticate(res, credentials, artifacts)).to.equal(false);
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns true on ignoring hash', function (done) {
|
||||
|
||||
var res = {
|
||||
headers: {
|
||||
'content-type': 'text/plain',
|
||||
'server-authorization': 'Hawk mac="XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"'
|
||||
}
|
||||
};
|
||||
|
||||
var artifacts = {
|
||||
method: 'POST',
|
||||
host: 'example.com',
|
||||
port: '8080',
|
||||
resource: '/resource/4?filter=a',
|
||||
ts: '1362336900',
|
||||
nonce: 'eb5S_L',
|
||||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=',
|
||||
ext: 'some-app-data',
|
||||
app: undefined,
|
||||
dlg: undefined,
|
||||
mac: 'BlmSe8K+pbKIb6YsZCnt4E1GrYvY1AaYayNR82dGpIk=',
|
||||
id: '123456'
|
||||
};
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
|
||||
algorithm: 'sha256',
|
||||
user: 'steve'
|
||||
};
|
||||
|
||||
expect(Hawk.client.authenticate(res, credentials, artifacts)).to.equal(true);
|
||||
done();
|
||||
});
|
||||
|
||||
it('fails on invalid WWW-Authenticate header format', function (done) {
|
||||
|
||||
var header = 'Hawk ts="1362346425875", tsm="PhwayS28vtnn3qbv0mqRBYSXebN/zggEtucfeZ620Zo=", x="Stale timestamp"';
|
||||
expect(Hawk.client.authenticate({ headers: { 'www-authenticate': header } }, {})).to.equal(false);
|
||||
done();
|
||||
});
|
||||
|
||||
it('fails on invalid WWW-Authenticate header format', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
|
||||
algorithm: 'sha256',
|
||||
user: 'steve'
|
||||
};
|
||||
|
||||
var header = 'Hawk ts="1362346425875", tsm="hwayS28vtnn3qbv0mqRBYSXebN/zggEtucfeZ620Zo=", error="Stale timestamp"';
|
||||
expect(Hawk.client.authenticate({ headers: { 'www-authenticate': header } }, credentials)).to.equal(false);
|
||||
done();
|
||||
});
|
||||
|
||||
it('skips tsm validation when missing ts', function (done) {
|
||||
|
||||
var header = 'Hawk error="Stale timestamp"';
|
||||
expect(Hawk.client.authenticate({ headers: { 'www-authenticate': header } }, {})).to.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('message()', function () {
|
||||
|
||||
it('generates authorization', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha1'
|
||||
};
|
||||
|
||||
var auth = Hawk.client.message('example.com', 80, 'I am the boodyman', { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' });
|
||||
expect(auth).to.exist();
|
||||
expect(auth.ts).to.equal(1353809207);
|
||||
expect(auth.nonce).to.equal('abc123');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on invalid host', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha1'
|
||||
};
|
||||
|
||||
var auth = Hawk.client.message(5, 80, 'I am the boodyman', { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' });
|
||||
expect(auth).to.not.exist();
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on invalid port', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha1'
|
||||
};
|
||||
|
||||
var auth = Hawk.client.message('example.com', '80', 'I am the boodyman', { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' });
|
||||
expect(auth).to.not.exist();
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on missing host', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha1'
|
||||
};
|
||||
|
||||
var auth = Hawk.client.message('example.com', 0, 'I am the boodyman', { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' });
|
||||
expect(auth).to.not.exist();
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on null message', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha1'
|
||||
};
|
||||
|
||||
var auth = Hawk.client.message('example.com', 80, null, { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' });
|
||||
expect(auth).to.not.exist();
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on missing message', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha1'
|
||||
};
|
||||
|
||||
var auth = Hawk.client.message('example.com', 80, undefined, { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' });
|
||||
expect(auth).to.not.exist();
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on invalid message', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha1'
|
||||
};
|
||||
|
||||
var auth = Hawk.client.message('example.com', 80, 5, { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' });
|
||||
expect(auth).to.not.exist();
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on missing options', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha1'
|
||||
};
|
||||
|
||||
var auth = Hawk.client.message('example.com', 80, 'I am the boodyman');
|
||||
expect(auth).to.not.exist();
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on invalid credentials (id)', function (done) {
|
||||
|
||||
var credentials = {
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha1'
|
||||
};
|
||||
|
||||
var auth = Hawk.client.message('example.com', 80, 'I am the boodyman', { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' });
|
||||
expect(auth).to.not.exist();
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on invalid credentials (key)', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
algorithm: 'sha1'
|
||||
};
|
||||
|
||||
var auth = Hawk.client.message('example.com', 80, 'I am the boodyman', { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' });
|
||||
expect(auth).to.not.exist();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
70
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/test/crypto.js
generated
vendored
Executable file
70
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/test/crypto.js
generated
vendored
Executable file
@ -0,0 +1,70 @@
|
||||
// Load modules
|
||||
|
||||
var Code = require('code');
|
||||
var Hawk = require('../lib');
|
||||
var Lab = require('lab');
|
||||
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
|
||||
// Test shortcuts
|
||||
|
||||
var lab = exports.lab = Lab.script();
|
||||
var describe = lab.experiment;
|
||||
var it = lab.test;
|
||||
var expect = Code.expect;
|
||||
|
||||
|
||||
describe('Crypto', function () {
|
||||
|
||||
describe('generateNormalizedString()', function () {
|
||||
|
||||
it('should return a valid normalized string', function (done) {
|
||||
|
||||
expect(Hawk.crypto.generateNormalizedString('header', {
|
||||
ts: 1357747017,
|
||||
nonce: 'k3k4j5',
|
||||
method: 'GET',
|
||||
resource: '/resource/something',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
})).to.equal('hawk.1.header\n1357747017\nk3k4j5\nGET\n/resource/something\nexample.com\n8080\n\n\n');
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should return a valid normalized string (ext)', function (done) {
|
||||
|
||||
expect(Hawk.crypto.generateNormalizedString('header', {
|
||||
ts: 1357747017,
|
||||
nonce: 'k3k4j5',
|
||||
method: 'GET',
|
||||
resource: '/resource/something',
|
||||
host: 'example.com',
|
||||
port: 8080,
|
||||
ext: 'this is some app data'
|
||||
})).to.equal('hawk.1.header\n1357747017\nk3k4j5\nGET\n/resource/something\nexample.com\n8080\n\nthis is some app data\n');
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should return a valid normalized string (payload + ext)', function (done) {
|
||||
|
||||
expect(Hawk.crypto.generateNormalizedString('header', {
|
||||
ts: 1357747017,
|
||||
nonce: 'k3k4j5',
|
||||
method: 'GET',
|
||||
resource: '/resource/something',
|
||||
host: 'example.com',
|
||||
port: 8080,
|
||||
hash: 'U4MKKSmiVxk37JCCrAVIjV/OhB3y+NdwoCr6RShbVkE=',
|
||||
ext: 'this is some app data'
|
||||
})).to.equal('hawk.1.header\n1357747017\nk3k4j5\nGET\n/resource/something\nexample.com\n8080\nU4MKKSmiVxk37JCCrAVIjV/OhB3y+NdwoCr6RShbVkE=\nthis is some app data\n');
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
378
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/test/index.js
generated
vendored
Executable file
378
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/test/index.js
generated
vendored
Executable file
@ -0,0 +1,378 @@
|
||||
// Load modules
|
||||
|
||||
var Url = require('url');
|
||||
var Code = require('code');
|
||||
var Hawk = require('../lib');
|
||||
var Lab = require('lab');
|
||||
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
|
||||
// Test shortcuts
|
||||
|
||||
var lab = exports.lab = Lab.script();
|
||||
var describe = lab.experiment;
|
||||
var it = lab.test;
|
||||
var expect = Code.expect;
|
||||
|
||||
|
||||
describe('Hawk', function () {
|
||||
|
||||
var credentialsFunc = function (id, callback) {
|
||||
|
||||
var credentials = {
|
||||
id: id,
|
||||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
|
||||
algorithm: (id === '1' ? 'sha1' : 'sha256'),
|
||||
user: 'steve'
|
||||
};
|
||||
|
||||
return callback(null, credentials);
|
||||
};
|
||||
|
||||
it('generates a header then successfully parse it (configuration)', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?filter=a',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
req.authorization = Hawk.client.header(Url.parse('http://example.com:8080/resource/4?filter=a'), req.method, { credentials: credentials1, ext: 'some-app-data' }).field;
|
||||
expect(req.authorization).to.exist();
|
||||
|
||||
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials2, artifacts) {
|
||||
|
||||
expect(err).to.not.exist();
|
||||
expect(credentials2.user).to.equal('steve');
|
||||
expect(artifacts.ext).to.equal('some-app-data');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('generates a header then successfully parse it (node request)', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'POST',
|
||||
url: '/resource/4?filter=a',
|
||||
headers: {
|
||||
host: 'example.com:8080',
|
||||
'content-type': 'text/plain;x=y'
|
||||
}
|
||||
};
|
||||
|
||||
var payload = 'some not so random text';
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var reqHeader = Hawk.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials1, ext: 'some-app-data', payload: payload, contentType: req.headers['content-type'] });
|
||||
req.headers.authorization = reqHeader.field;
|
||||
|
||||
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials2, artifacts) {
|
||||
|
||||
expect(err).to.not.exist();
|
||||
expect(credentials2.user).to.equal('steve');
|
||||
expect(artifacts.ext).to.equal('some-app-data');
|
||||
expect(Hawk.server.authenticatePayload(payload, credentials2, artifacts, req.headers['content-type'])).to.equal(true);
|
||||
|
||||
var res = {
|
||||
headers: {
|
||||
'content-type': 'text/plain'
|
||||
}
|
||||
};
|
||||
|
||||
res.headers['server-authorization'] = Hawk.server.header(credentials2, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
|
||||
expect(res.headers['server-authorization']).to.exist();
|
||||
|
||||
expect(Hawk.client.authenticate(res, credentials2, artifacts, { payload: 'some reply' })).to.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('generates a header then successfully parse it (absolute request uri)', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'POST',
|
||||
url: 'http://example.com:8080/resource/4?filter=a',
|
||||
headers: {
|
||||
host: 'example.com:8080',
|
||||
'content-type': 'text/plain;x=y'
|
||||
}
|
||||
};
|
||||
|
||||
var payload = 'some not so random text';
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var reqHeader = Hawk.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials1, ext: 'some-app-data', payload: payload, contentType: req.headers['content-type'] });
|
||||
req.headers.authorization = reqHeader.field;
|
||||
|
||||
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials2, artifacts) {
|
||||
|
||||
expect(err).to.not.exist();
|
||||
expect(credentials2.user).to.equal('steve');
|
||||
expect(artifacts.ext).to.equal('some-app-data');
|
||||
expect(Hawk.server.authenticatePayload(payload, credentials2, artifacts, req.headers['content-type'])).to.equal(true);
|
||||
|
||||
var res = {
|
||||
headers: {
|
||||
'content-type': 'text/plain'
|
||||
}
|
||||
};
|
||||
|
||||
res.headers['server-authorization'] = Hawk.server.header(credentials2, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' });
|
||||
expect(res.headers['server-authorization']).to.exist();
|
||||
|
||||
expect(Hawk.client.authenticate(res, credentials2, artifacts, { payload: 'some reply' })).to.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('generates a header then successfully parse it (no server header options)', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'POST',
|
||||
url: '/resource/4?filter=a',
|
||||
headers: {
|
||||
host: 'example.com:8080',
|
||||
'content-type': 'text/plain;x=y'
|
||||
}
|
||||
};
|
||||
|
||||
var payload = 'some not so random text';
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var reqHeader = Hawk.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials1, ext: 'some-app-data', payload: payload, contentType: req.headers['content-type'] });
|
||||
req.headers.authorization = reqHeader.field;
|
||||
|
||||
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials2, artifacts) {
|
||||
|
||||
expect(err).to.not.exist();
|
||||
expect(credentials2.user).to.equal('steve');
|
||||
expect(artifacts.ext).to.equal('some-app-data');
|
||||
expect(Hawk.server.authenticatePayload(payload, credentials2, artifacts, req.headers['content-type'])).to.equal(true);
|
||||
|
||||
var res = {
|
||||
headers: {
|
||||
'content-type': 'text/plain'
|
||||
}
|
||||
};
|
||||
|
||||
res.headers['server-authorization'] = Hawk.server.header(credentials2, artifacts);
|
||||
expect(res.headers['server-authorization']).to.exist();
|
||||
|
||||
expect(Hawk.client.authenticate(res, credentials2, artifacts)).to.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('generates a header then fails to parse it (missing server header hash)', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'POST',
|
||||
url: '/resource/4?filter=a',
|
||||
headers: {
|
||||
host: 'example.com:8080',
|
||||
'content-type': 'text/plain;x=y'
|
||||
}
|
||||
};
|
||||
|
||||
var payload = 'some not so random text';
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var reqHeader = Hawk.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials1, ext: 'some-app-data', payload: payload, contentType: req.headers['content-type'] });
|
||||
req.headers.authorization = reqHeader.field;
|
||||
|
||||
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials2, artifacts) {
|
||||
|
||||
expect(err).to.not.exist();
|
||||
expect(credentials2.user).to.equal('steve');
|
||||
expect(artifacts.ext).to.equal('some-app-data');
|
||||
expect(Hawk.server.authenticatePayload(payload, credentials2, artifacts, req.headers['content-type'])).to.equal(true);
|
||||
|
||||
var res = {
|
||||
headers: {
|
||||
'content-type': 'text/plain'
|
||||
}
|
||||
};
|
||||
|
||||
res.headers['server-authorization'] = Hawk.server.header(credentials2, artifacts);
|
||||
expect(res.headers['server-authorization']).to.exist();
|
||||
|
||||
expect(Hawk.client.authenticate(res, credentials2, artifacts, { payload: 'some reply' })).to.equal(false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('generates a header then successfully parse it (with hash)', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?filter=a',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
req.authorization = Hawk.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials1, payload: 'hola!', ext: 'some-app-data' }).field;
|
||||
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials2, artifacts) {
|
||||
|
||||
expect(err).to.not.exist();
|
||||
expect(credentials2.user).to.equal('steve');
|
||||
expect(artifacts.ext).to.equal('some-app-data');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('generates a header then successfully parse it then validate payload', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?filter=a',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
req.authorization = Hawk.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials1, payload: 'hola!', ext: 'some-app-data' }).field;
|
||||
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials2, artifacts) {
|
||||
|
||||
expect(err).to.not.exist();
|
||||
expect(credentials2.user).to.equal('steve');
|
||||
expect(artifacts.ext).to.equal('some-app-data');
|
||||
expect(Hawk.server.authenticatePayload('hola!', credentials2, artifacts)).to.be.true();
|
||||
expect(Hawk.server.authenticatePayload('hello!', credentials2, artifacts)).to.be.false();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('generates a header then successfully parses and validates payload', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?filter=a',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
req.authorization = Hawk.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials1, payload: 'hola!', ext: 'some-app-data' }).field;
|
||||
Hawk.server.authenticate(req, credentialsFunc, { payload: 'hola!' }, function (err, credentials2, artifacts) {
|
||||
|
||||
expect(err).to.not.exist();
|
||||
expect(credentials2.user).to.equal('steve');
|
||||
expect(artifacts.ext).to.equal('some-app-data');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('generates a header then successfully parse it (app)', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?filter=a',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
req.authorization = Hawk.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials1, ext: 'some-app-data', app: 'asd23ased' }).field;
|
||||
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials2, artifacts) {
|
||||
|
||||
expect(err).to.not.exist();
|
||||
expect(credentials2.user).to.equal('steve');
|
||||
expect(artifacts.ext).to.equal('some-app-data');
|
||||
expect(artifacts.app).to.equal('asd23ased');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('generates a header then successfully parse it (app, dlg)', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?filter=a',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
req.authorization = Hawk.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials1, ext: 'some-app-data', app: 'asd23ased', dlg: '23434szr3q4d' }).field;
|
||||
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials2, artifacts) {
|
||||
|
||||
expect(err).to.not.exist();
|
||||
expect(credentials2.user).to.equal('steve');
|
||||
expect(artifacts.ext).to.equal('some-app-data');
|
||||
expect(artifacts.app).to.equal('asd23ased');
|
||||
expect(artifacts.dlg).to.equal('23434szr3q4d');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('generates a header then fail authentication due to bad hash', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?filter=a',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
req.authorization = Hawk.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials1, payload: 'hola!', ext: 'some-app-data' }).field;
|
||||
Hawk.server.authenticate(req, credentialsFunc, { payload: 'byebye!' }, function (err, credentials2, artifacts) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.output.payload.message).to.equal('Bad payload hash');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('generates a header for one resource then fail to authenticate another', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?filter=a',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
req.authorization = Hawk.client.header('http://example.com:8080/resource/4?filter=a', req.method, { credentials: credentials1, ext: 'some-app-data' }).field;
|
||||
req.url = '/something/else';
|
||||
|
||||
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials2, artifacts) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(credentials2).to.exist();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
95
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/test/readme.js
generated
vendored
Executable file
95
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/test/readme.js
generated
vendored
Executable file
@ -0,0 +1,95 @@
|
||||
// Load modules
|
||||
|
||||
var Code = require('code');
|
||||
var Hawk = require('../lib');
|
||||
var Hoek = require('hoek');
|
||||
var Lab = require('lab');
|
||||
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
|
||||
// Test shortcuts
|
||||
|
||||
var lab = exports.lab = Lab.script();
|
||||
var describe = lab.experiment;
|
||||
var it = lab.test;
|
||||
var expect = Code.expect;
|
||||
|
||||
|
||||
describe('README', function () {
|
||||
|
||||
describe('core', function () {
|
||||
|
||||
var credentials = {
|
||||
id: 'dh37fgj492je',
|
||||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
|
||||
algorithm: 'sha256'
|
||||
};
|
||||
|
||||
var options = {
|
||||
credentials: credentials,
|
||||
timestamp: 1353832234,
|
||||
nonce: 'j4h3g2',
|
||||
ext: 'some-app-ext-data'
|
||||
};
|
||||
|
||||
it('should generate a header protocol example', function (done) {
|
||||
|
||||
var header = Hawk.client.header('http://example.com:8000/resource/1?b=1&a=2', 'GET', options).field;
|
||||
|
||||
expect(header).to.equal('Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", ext="some-app-ext-data", mac="6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE="');
|
||||
done();
|
||||
});
|
||||
|
||||
it('should generate a normalized string protocol example', function (done) {
|
||||
|
||||
var normalized = Hawk.crypto.generateNormalizedString('header', {
|
||||
credentials: credentials,
|
||||
ts: options.timestamp,
|
||||
nonce: options.nonce,
|
||||
method: 'GET',
|
||||
resource: '/resource?a=1&b=2',
|
||||
host: 'example.com',
|
||||
port: 8000,
|
||||
ext: options.ext
|
||||
});
|
||||
|
||||
expect(normalized).to.equal('hawk.1.header\n1353832234\nj4h3g2\nGET\n/resource?a=1&b=2\nexample.com\n8000\n\nsome-app-ext-data\n');
|
||||
done();
|
||||
});
|
||||
|
||||
var payloadOptions = Hoek.clone(options);
|
||||
payloadOptions.payload = 'Thank you for flying Hawk';
|
||||
payloadOptions.contentType = 'text/plain';
|
||||
|
||||
it('should generate a header protocol example (with payload)', function (done) {
|
||||
|
||||
var header = Hawk.client.header('http://example.com:8000/resource/1?b=1&a=2', 'POST', payloadOptions).field;
|
||||
|
||||
expect(header).to.equal('Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", hash="Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=", ext="some-app-ext-data", mac="aSe1DERmZuRl3pI36/9BdZmnErTw3sNzOOAUlfeKjVw="');
|
||||
done();
|
||||
});
|
||||
|
||||
it('should generate a normalized string protocol example (with payload)', function (done) {
|
||||
|
||||
var normalized = Hawk.crypto.generateNormalizedString('header', {
|
||||
credentials: credentials,
|
||||
ts: options.timestamp,
|
||||
nonce: options.nonce,
|
||||
method: 'POST',
|
||||
resource: '/resource?a=1&b=2',
|
||||
host: 'example.com',
|
||||
port: 8000,
|
||||
hash: Hawk.crypto.calculatePayloadHash(payloadOptions.payload, credentials.algorithm, payloadOptions.contentType),
|
||||
ext: options.ext
|
||||
});
|
||||
|
||||
expect(normalized).to.equal('hawk.1.header\n1353832234\nj4h3g2\nPOST\n/resource?a=1&b=2\nexample.com\n8000\nYi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=\nsome-app-ext-data\n');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
1329
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/test/server.js
generated
vendored
Executable file
1329
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/test/server.js
generated
vendored
Executable file
File diff suppressed because it is too large
Load Diff
838
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/test/uri.js
generated
vendored
Executable file
838
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/test/uri.js
generated
vendored
Executable file
@ -0,0 +1,838 @@
|
||||
// Load modules
|
||||
|
||||
var Http = require('http');
|
||||
var Url = require('url');
|
||||
var Code = require('code');
|
||||
var Hawk = require('../lib');
|
||||
var Hoek = require('hoek');
|
||||
var Lab = require('lab');
|
||||
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
|
||||
// Test shortcuts
|
||||
|
||||
var lab = exports.lab = Lab.script();
|
||||
var describe = lab.experiment;
|
||||
var it = lab.test;
|
||||
var expect = Code.expect;
|
||||
|
||||
|
||||
describe('Uri', function () {
|
||||
|
||||
var credentialsFunc = function (id, callback) {
|
||||
|
||||
var credentials = {
|
||||
id: id,
|
||||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
|
||||
algorithm: (id === '1' ? 'sha1' : 'sha256'),
|
||||
user: 'steve'
|
||||
};
|
||||
|
||||
return callback(null, credentials);
|
||||
};
|
||||
|
||||
it('should generate a bewit then successfully authenticate it', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?a=1&b=2',
|
||||
host: 'example.com',
|
||||
port: 80
|
||||
};
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var bewit = Hawk.uri.getBewit('http://example.com/resource/4?a=1&b=2', { credentials: credentials1, ttlSec: 60 * 60 * 24 * 365 * 100, ext: 'some-app-data' });
|
||||
req.url += '&bewit=' + bewit;
|
||||
|
||||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials2, attributes) {
|
||||
|
||||
expect(err).to.not.exist();
|
||||
expect(credentials2.user).to.equal('steve');
|
||||
expect(attributes.ext).to.equal('some-app-data');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should generate a bewit then successfully authenticate it (no ext)', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?a=1&b=2',
|
||||
host: 'example.com',
|
||||
port: 80
|
||||
};
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var bewit = Hawk.uri.getBewit('http://example.com/resource/4?a=1&b=2', { credentials: credentials1, ttlSec: 60 * 60 * 24 * 365 * 100 });
|
||||
req.url += '&bewit=' + bewit;
|
||||
|
||||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials2, attributes) {
|
||||
|
||||
expect(err).to.not.exist();
|
||||
expect(credentials2.user).to.equal('steve');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should successfully authenticate a request (last param)', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?a=1&b=2&bewit=MTIzNDU2XDQ1MTE0ODQ2MjFcMzFjMmNkbUJFd1NJRVZDOVkva1NFb2c3d3YrdEVNWjZ3RXNmOGNHU2FXQT1cc29tZS1hcHAtZGF0YQ',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
|
||||
|
||||
expect(err).to.not.exist();
|
||||
expect(credentials.user).to.equal('steve');
|
||||
expect(attributes.ext).to.equal('some-app-data');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should successfully authenticate a request (first param)', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?bewit=MTIzNDU2XDQ1MTE0ODQ2MjFcMzFjMmNkbUJFd1NJRVZDOVkva1NFb2c3d3YrdEVNWjZ3RXNmOGNHU2FXQT1cc29tZS1hcHAtZGF0YQ&a=1&b=2',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
|
||||
|
||||
expect(err).to.not.exist();
|
||||
expect(credentials.user).to.equal('steve');
|
||||
expect(attributes.ext).to.equal('some-app-data');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should successfully authenticate a request (only param)', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?bewit=MTIzNDU2XDQ1MTE0ODQ2NDFcZm1CdkNWT3MvcElOTUUxSTIwbWhrejQ3UnBwTmo4Y1VrSHpQd3Q5OXJ1cz1cc29tZS1hcHAtZGF0YQ',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
|
||||
|
||||
expect(err).to.not.exist();
|
||||
expect(credentials.user).to.equal('steve');
|
||||
expect(attributes.ext).to.equal('some-app-data');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on multiple authentication', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?bewit=MTIzNDU2XDQ1MTE0ODQ2NDFcZm1CdkNWT3MvcElOTUUxSTIwbWhrejQ3UnBwTmo4Y1VrSHpQd3Q5OXJ1cz1cc29tZS1hcHAtZGF0YQ',
|
||||
host: 'example.com',
|
||||
port: 8080,
|
||||
authorization: 'Basic asdasdasdasd'
|
||||
};
|
||||
|
||||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.output.payload.message).to.equal('Multiple authentications');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on method other than GET', function (done) {
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var req = {
|
||||
method: 'POST',
|
||||
url: '/resource/4?filter=a',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
var exp = Math.floor(Hawk.utils.now() / 1000) + 60;
|
||||
var ext = 'some-app-data';
|
||||
var mac = Hawk.crypto.calculateMac('bewit', credentials1, {
|
||||
timestamp: exp,
|
||||
nonce: '',
|
||||
method: req.method,
|
||||
resource: req.url,
|
||||
host: req.host,
|
||||
port: req.port,
|
||||
ext: ext
|
||||
});
|
||||
|
||||
var bewit = credentials1.id + '\\' + exp + '\\' + mac + '\\' + ext;
|
||||
|
||||
req.url += '&bewit=' + Hoek.base64urlEncode(bewit);
|
||||
|
||||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials2, attributes) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.output.payload.message).to.equal('Invalid method');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on invalid host header', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ',
|
||||
headers: {
|
||||
host: 'example.com:something'
|
||||
}
|
||||
};
|
||||
|
||||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.output.payload.message).to.equal('Invalid Host header');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on empty bewit', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?bewit=',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.output.payload.message).to.equal('Empty bewit');
|
||||
expect(err.isMissing).to.not.exist();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on invalid bewit', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?bewit=*',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.output.payload.message).to.equal('Invalid bewit encoding');
|
||||
expect(err.isMissing).to.not.exist();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on missing bewit', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.output.payload.message).to.not.exist();
|
||||
expect(err.isMissing).to.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on invalid bewit structure', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?bewit=abc',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.output.payload.message).to.equal('Invalid bewit structure');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on empty bewit attribute', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?bewit=YVxcY1xk',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.output.payload.message).to.equal('Missing bewit attributes');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on missing bewit id attribute', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?bewit=XDQ1NTIxNDc2MjJcK0JFbFhQMXhuWjcvd1Nrbm1ldGhlZm5vUTNHVjZNSlFVRHk4NWpTZVJ4VT1cc29tZS1hcHAtZGF0YQ',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.output.payload.message).to.equal('Missing bewit attributes');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on expired access', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?a=1&b=2&bewit=MTIzNDU2XDEzNTY0MTg1ODNcWk1wZlMwWU5KNHV0WHpOMmRucTRydEk3NXNXTjFjeWVITTcrL0tNZFdVQT1cc29tZS1hcHAtZGF0YQ',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.output.payload.message).to.equal('Access expired');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on credentials function error', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
Hawk.uri.authenticate(req, function (id, callback) {
|
||||
|
||||
callback(Hawk.error.badRequest('Boom'));
|
||||
}, {}, function (err, credentials, attributes) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.output.payload.message).to.equal('Boom');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on credentials function error with credentials', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
Hawk.uri.authenticate(req, function (id, callback) {
|
||||
|
||||
callback(Hawk.error.badRequest('Boom'), { some: 'value' });
|
||||
}, {}, function (err, credentials, attributes) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.output.payload.message).to.equal('Boom');
|
||||
expect(credentials.some).to.equal('value');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on null credentials function response', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
Hawk.uri.authenticate(req, function (id, callback) {
|
||||
|
||||
callback(null, null);
|
||||
}, {}, function (err, credentials, attributes) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.output.payload.message).to.equal('Unknown credentials');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on invalid credentials function response', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
Hawk.uri.authenticate(req, function (id, callback) {
|
||||
|
||||
callback(null, {});
|
||||
}, {}, function (err, credentials, attributes) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.message).to.equal('Invalid credentials');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on invalid credentials function response (unknown algorithm)', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
Hawk.uri.authenticate(req, function (id, callback) {
|
||||
|
||||
callback(null, { key: 'xxx', algorithm: 'xxx' });
|
||||
}, {}, function (err, credentials, attributes) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.message).to.equal('Unknown algorithm');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on expired access', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'GET',
|
||||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ',
|
||||
host: 'example.com',
|
||||
port: 8080
|
||||
};
|
||||
|
||||
Hawk.uri.authenticate(req, function (id, callback) {
|
||||
|
||||
callback(null, { key: 'xxx', algorithm: 'sha256' });
|
||||
}, {}, function (err, credentials, attributes) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.output.payload.message).to.equal('Bad mac');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getBewit()', function () {
|
||||
|
||||
it('returns a valid bewit value', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha256'
|
||||
};
|
||||
|
||||
var bewit = Hawk.uri.getBewit('https://example.com/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 300, localtimeOffsetMsec: 1356420407232 - Hawk.utils.now(), ext: 'xandyandz' });
|
||||
expect(bewit).to.equal('MTIzNDU2XDEzNTY0MjA3MDdca3NjeHdOUjJ0SnBQMVQxekRMTlBiQjVVaUtJVTl0T1NKWFRVZEc3WDloOD1ceGFuZHlhbmR6');
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns a valid bewit value (explicit port)', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha256'
|
||||
};
|
||||
|
||||
var bewit = Hawk.uri.getBewit('https://example.com:8080/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 300, localtimeOffsetMsec: 1356420407232 - Hawk.utils.now(), ext: 'xandyandz' });
|
||||
expect(bewit).to.equal('MTIzNDU2XDEzNTY0MjA3MDdcaFpiSjNQMmNLRW80a3kwQzhqa1pBa1J5Q1p1ZWc0V1NOYnhWN3ZxM3hIVT1ceGFuZHlhbmR6');
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns a valid bewit value (null ext)', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha256'
|
||||
};
|
||||
|
||||
var bewit = Hawk.uri.getBewit('https://example.com/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 300, localtimeOffsetMsec: 1356420407232 - Hawk.utils.now(), ext: null });
|
||||
expect(bewit).to.equal('MTIzNDU2XDEzNTY0MjA3MDdcSUdZbUxnSXFMckNlOEN4dktQczRKbFdJQStValdKSm91d2dBUmlWaENBZz1c');
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns a valid bewit value (parsed uri)', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha256'
|
||||
};
|
||||
|
||||
var bewit = Hawk.uri.getBewit(Url.parse('https://example.com/somewhere/over/the/rainbow'), { credentials: credentials, ttlSec: 300, localtimeOffsetMsec: 1356420407232 - Hawk.utils.now(), ext: 'xandyandz' });
|
||||
expect(bewit).to.equal('MTIzNDU2XDEzNTY0MjA3MDdca3NjeHdOUjJ0SnBQMVQxekRMTlBiQjVVaUtJVTl0T1NKWFRVZEc3WDloOD1ceGFuZHlhbmR6');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on invalid options', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha256'
|
||||
};
|
||||
|
||||
var bewit = Hawk.uri.getBewit('https://example.com/somewhere/over/the/rainbow', 4);
|
||||
expect(bewit).to.equal('');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on missing uri', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha256'
|
||||
};
|
||||
|
||||
var bewit = Hawk.uri.getBewit('', { credentials: credentials, ttlSec: 300, localtimeOffsetMsec: 1356420407232 - Hawk.utils.now(), ext: 'xandyandz' });
|
||||
expect(bewit).to.equal('');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on invalid uri', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha256'
|
||||
};
|
||||
|
||||
var bewit = Hawk.uri.getBewit(5, { credentials: credentials, ttlSec: 300, localtimeOffsetMsec: 1356420407232 - Hawk.utils.now(), ext: 'xandyandz' });
|
||||
expect(bewit).to.equal('');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on invalid credentials (id)', function (done) {
|
||||
|
||||
var credentials = {
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'sha256'
|
||||
};
|
||||
|
||||
var bewit = Hawk.uri.getBewit('https://example.com/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 3000, ext: 'xandyandz' });
|
||||
expect(bewit).to.equal('');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on missing credentials', function (done) {
|
||||
|
||||
var bewit = Hawk.uri.getBewit('https://example.com/somewhere/over/the/rainbow', { ttlSec: 3000, ext: 'xandyandz' });
|
||||
expect(bewit).to.equal('');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on invalid credentials (key)', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
algorithm: 'sha256'
|
||||
};
|
||||
|
||||
var bewit = Hawk.uri.getBewit('https://example.com/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 3000, ext: 'xandyandz' });
|
||||
expect(bewit).to.equal('');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on invalid algorithm', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'hmac-sha-0'
|
||||
};
|
||||
|
||||
var bewit = Hawk.uri.getBewit('https://example.com/somewhere/over/the/rainbow', { credentials: credentials, ttlSec: 300, ext: 'xandyandz' });
|
||||
expect(bewit).to.equal('');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on missing options', function (done) {
|
||||
|
||||
var credentials = {
|
||||
id: '123456',
|
||||
key: '2983d45yun89q',
|
||||
algorithm: 'hmac-sha-0'
|
||||
};
|
||||
|
||||
var bewit = Hawk.uri.getBewit('https://example.com/somewhere/over/the/rainbow');
|
||||
expect(bewit).to.equal('');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('authenticateMessage()', function () {
|
||||
|
||||
it('should generate an authorization then successfully parse it', function (done) {
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
|
||||
expect(auth).to.exist();
|
||||
|
||||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials2) {
|
||||
|
||||
expect(err).to.not.exist();
|
||||
expect(credentials2.user).to.equal('steve');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail authorization on mismatching host', function (done) {
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
|
||||
expect(auth).to.exist();
|
||||
|
||||
Hawk.server.authenticateMessage('example1.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials2) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.message).to.equal('Bad mac');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail authorization on stale timestamp', function (done) {
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
|
||||
expect(auth).to.exist();
|
||||
|
||||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, { localtimeOffsetMsec: 100000 }, function (err, credentials2) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.message).to.equal('Stale timestamp');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('overrides timestampSkewSec', function (done) {
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1, localtimeOffsetMsec: 100000 });
|
||||
expect(auth).to.exist();
|
||||
|
||||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, { timestampSkewSec: 500 }, function (err, credentials2) {
|
||||
|
||||
expect(err).to.not.exist();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail authorization on invalid authorization', function (done) {
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
|
||||
expect(auth).to.exist();
|
||||
delete auth.id;
|
||||
|
||||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials2) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.message).to.equal('Invalid authorization');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail authorization on bad hash', function (done) {
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
|
||||
expect(auth).to.exist();
|
||||
|
||||
Hawk.server.authenticateMessage('example.com', 8080, 'some message1', auth, credentialsFunc, {}, function (err, credentials2) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.message).to.equal('Bad message hash');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail authorization on nonce error', function (done) {
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
|
||||
expect(auth).to.exist();
|
||||
|
||||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {
|
||||
nonceFunc: function (key, nonce, ts, callback) {
|
||||
|
||||
callback(new Error('kaboom'));
|
||||
}
|
||||
}, function (err, credentials2) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.message).to.equal('Invalid nonce');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail authorization on credentials error', function (done) {
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
|
||||
expect(auth).to.exist();
|
||||
|
||||
var errFunc = function (id, callback) {
|
||||
|
||||
callback(new Error('kablooey'));
|
||||
};
|
||||
|
||||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials2) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.message).to.equal('kablooey');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail authorization on missing credentials', function (done) {
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
|
||||
expect(auth).to.exist();
|
||||
|
||||
var errFunc = function (id, callback) {
|
||||
|
||||
callback();
|
||||
};
|
||||
|
||||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials2) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.message).to.equal('Unknown credentials');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail authorization on invalid credentials', function (done) {
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
|
||||
expect(auth).to.exist();
|
||||
|
||||
var errFunc = function (id, callback) {
|
||||
|
||||
callback(null, {});
|
||||
};
|
||||
|
||||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials2) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.message).to.equal('Invalid credentials');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail authorization on invalid credentials algorithm', function (done) {
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials1 });
|
||||
expect(auth).to.exist();
|
||||
|
||||
var errFunc = function (id, callback) {
|
||||
|
||||
callback(null, { key: '123', algorithm: '456' });
|
||||
};
|
||||
|
||||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials2) {
|
||||
|
||||
expect(err).to.exist();
|
||||
expect(err.message).to.equal('Unknown algorithm');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on missing host', function (done) {
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var auth = Hawk.client.message(null, 8080, 'some message', { credentials: credentials1 });
|
||||
expect(auth).to.not.exist();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on missing credentials', function (done) {
|
||||
|
||||
var auth = Hawk.client.message('example.com', 8080, 'some message', {});
|
||||
expect(auth).to.not.exist();
|
||||
done();
|
||||
});
|
||||
|
||||
it('should fail on invalid algorithm', function (done) {
|
||||
|
||||
credentialsFunc('123456', function (err, credentials1) {
|
||||
|
||||
var creds = Hoek.clone(credentials1);
|
||||
creds.algorithm = 'blah';
|
||||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: creds });
|
||||
expect(auth).to.not.exist();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
149
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/test/utils.js
generated
vendored
Executable file
149
static/js/ketcher2/node_modules/coveralls/node_modules/hawk/test/utils.js
generated
vendored
Executable file
@ -0,0 +1,149 @@
|
||||
// Load modules
|
||||
|
||||
var Code = require('code');
|
||||
var Hawk = require('../lib');
|
||||
var Lab = require('lab');
|
||||
var Package = require('../package.json');
|
||||
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
|
||||
// Test shortcuts
|
||||
|
||||
var lab = exports.lab = Lab.script();
|
||||
var describe = lab.experiment;
|
||||
var it = lab.test;
|
||||
var expect = Code.expect;
|
||||
|
||||
|
||||
describe('Utils', function () {
|
||||
|
||||
describe('parseHost()', function () {
|
||||
|
||||
it('returns port 80 for non tls node request', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'POST',
|
||||
url: '/resource/4?filter=a',
|
||||
headers: {
|
||||
host: 'example.com',
|
||||
'content-type': 'text/plain;x=y'
|
||||
}
|
||||
};
|
||||
|
||||
expect(Hawk.utils.parseHost(req, 'Host').port).to.equal(80);
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns port 443 for non tls node request', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'POST',
|
||||
url: '/resource/4?filter=a',
|
||||
headers: {
|
||||
host: 'example.com',
|
||||
'content-type': 'text/plain;x=y'
|
||||
},
|
||||
connection: {
|
||||
encrypted: true
|
||||
}
|
||||
};
|
||||
|
||||
expect(Hawk.utils.parseHost(req, 'Host').port).to.equal(443);
|
||||
done();
|
||||
});
|
||||
|
||||
it('returns port 443 for non tls node request (IPv6)', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'POST',
|
||||
url: '/resource/4?filter=a',
|
||||
headers: {
|
||||
host: '[123:123:123]',
|
||||
'content-type': 'text/plain;x=y'
|
||||
},
|
||||
connection: {
|
||||
encrypted: true
|
||||
}
|
||||
};
|
||||
|
||||
expect(Hawk.utils.parseHost(req, 'Host').port).to.equal(443);
|
||||
done();
|
||||
});
|
||||
|
||||
it('parses IPv6 headers', function (done) {
|
||||
|
||||
var req = {
|
||||
method: 'POST',
|
||||
url: '/resource/4?filter=a',
|
||||
headers: {
|
||||
host: '[123:123:123]:8000',
|
||||
'content-type': 'text/plain;x=y'
|
||||
},
|
||||
connection: {
|
||||
encrypted: true
|
||||
}
|
||||
};
|
||||
|
||||
var host = Hawk.utils.parseHost(req, 'Host');
|
||||
expect(host.port).to.equal('8000');
|
||||
expect(host.name).to.equal('[123:123:123]');
|
||||
done();
|
||||
});
|
||||
|
||||
it('errors on header too long', function (done) {
|
||||
|
||||
var long = '';
|
||||
for (var i = 0; i < 5000; ++i) {
|
||||
long += 'x';
|
||||
}
|
||||
|
||||
expect(Hawk.utils.parseHost({ headers: { host: long } })).to.be.null();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseAuthorizationHeader()', function () {
|
||||
|
||||
it('errors on header too long', function (done) {
|
||||
|
||||
var long = 'Scheme a="';
|
||||
for (var i = 0; i < 5000; ++i) {
|
||||
long += 'x';
|
||||
}
|
||||
long += '"';
|
||||
|
||||
var err = Hawk.utils.parseAuthorizationHeader(long, ['a']);
|
||||
expect(err).to.be.instanceof(Error);
|
||||
expect(err.message).to.equal('Header length too long');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('version()', function () {
|
||||
|
||||
it('returns the correct package version number', function (done) {
|
||||
|
||||
expect(Hawk.utils.version()).to.equal(Package.version);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('unauthorized()', function () {
|
||||
|
||||
it('returns a hawk 401', function (done) {
|
||||
|
||||
expect(Hawk.utils.unauthorized('kaboom').output.headers['WWW-Authenticate']).to.equal('Hawk error="kaboom"');
|
||||
done();
|
||||
});
|
||||
|
||||
it('supports attributes', function (done) {
|
||||
|
||||
expect(Hawk.utils.unauthorized('kaboom', { a: 'b' }).output.headers['WWW-Authenticate']).to.equal('Hawk a="b", error="kaboom"');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
1
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/CONTRIBUTING.md
generated
vendored
Normal file
1
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/CONTRIBUTING.md
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
Please view our [hapijs contributing guide](https://github.com/hapijs/hapi/blob/master/CONTRIBUTING.md).
|
||||
31
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/LICENSE
generated
vendored
Normal file
31
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/LICENSE
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
Copyright (c) 2011-2014, Walmart and other contributors.
|
||||
Copyright (c) 2011, Yahoo Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* The names of any contributors may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
* * *
|
||||
|
||||
The complete list of contributors can be found at: https://github.com/hapijs/hapi/graphs/contributors
|
||||
Portions of this project were initially based on the Yahoo! Inc. Postmile project,
|
||||
published at https://github.com/yahoo/postmile.
|
||||
584
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/README.md
generated
vendored
Normal file
584
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/README.md
generated
vendored
Normal file
@ -0,0 +1,584 @@
|
||||

|
||||
|
||||
Utility methods for the hapi ecosystem. This module is not intended to solve every problem for everyone, but rather as a central place to store hapi-specific methods. If you're looking for a general purpose utility module, check out [lodash](https://github.com/lodash/lodash) or [underscore](https://github.com/jashkenas/underscore).
|
||||
|
||||
[](http://travis-ci.org/hapijs/hoek)
|
||||
|
||||
Lead Maintainer: [Nathan LaFreniere](https://github.com/nlf)
|
||||
|
||||
# Table of Contents
|
||||
|
||||
* [Introduction](#introduction "Introduction")
|
||||
* [Object](#object "Object")
|
||||
* [clone](#cloneobj "clone")
|
||||
* [cloneWithShallow](#clonewithshallowobj-keys "cloneWithShallow")
|
||||
* [merge](#mergetarget-source-isnulloverride-ismergearrays "merge")
|
||||
* [applyToDefaults](#applytodefaultsdefaults-options-isnulloverride "applyToDefaults")
|
||||
* [applyToDefaultsWithShallow](#applytodefaultswithshallowdefaults-options-keys "applyToDefaultsWithShallow")
|
||||
* [deepEqual](#deepequala-b "deepEqual")
|
||||
* [unique](#uniquearray-key "unique")
|
||||
* [mapToObject](#maptoobjectarray-key "mapToObject")
|
||||
* [intersect](#intersectarray1-array2 "intersect")
|
||||
* [contain](#containref-values-options "contain")
|
||||
* [flatten](#flattenarray-target "flatten")
|
||||
* [reach](#reachobj-chain-options "reach")
|
||||
* [reachTemplate](#reachtemplateobj-template-options "reachTemplate")
|
||||
* [transform](#transformobj-transform-options "transform")
|
||||
* [shallow](#shallowobj "shallow")
|
||||
* [stringify](#stringifyobj "stringify")
|
||||
* [Timer](#timer "Timer")
|
||||
* [Bench](#bench "Bench")
|
||||
* [Binary Encoding/Decoding](#binary-encodingdecoding "Binary Encoding/Decoding")
|
||||
* [base64urlEncode](#base64urlencodevalue "binary64urlEncode")
|
||||
* [base64urlDecode](#base64urldecodevalue "binary64urlDecode")
|
||||
* [Escaping Characters](#escaping-characters "Escaping Characters")
|
||||
* [escapeHtml](#escapehtmlstring "escapeHtml")
|
||||
* [escapeHeaderAttribute](#escapeheaderattributeattribute "escapeHeaderAttribute")
|
||||
* [escapeRegex](#escaperegexstring "escapeRegex")
|
||||
* [Errors](#errors "Errors")
|
||||
* [assert](#assertcondition-message "assert")
|
||||
* [abort](#abortmessage "abort")
|
||||
* [displayStack](#displaystackslice "displayStack")
|
||||
* [callStack](#callstackslice "callStack")
|
||||
* [Function](#function "Function")
|
||||
* [nextTick](#nexttickfn "nextTick")
|
||||
* [once](#oncefn "once")
|
||||
* [ignore](#ignore "ignore")
|
||||
* [Miscellaneous](#miscellaneous "Miscellaneous")
|
||||
* [uniqueFilename](#uniquefilenamepath-extension "uniqueFilename")
|
||||
* [isAbsolutePath](#isabsolutepathpath-platform "isAbsolutePath")
|
||||
* [isInteger](#isintegervalue "isInteger")
|
||||
|
||||
|
||||
|
||||
# Introduction
|
||||
|
||||
The *Hoek* library contains some common functions used within the hapi ecosystem. It comes with useful methods for Arrays (clone, merge, applyToDefaults), Objects (removeKeys, copy), Asserting and more.
|
||||
|
||||
For example, to use Hoek to set configuration with default options:
|
||||
```javascript
|
||||
var Hoek = require('hoek');
|
||||
|
||||
var default = {url : "www.github.com", port : "8000", debug : true};
|
||||
|
||||
var config = Hoek.applyToDefaults(default, {port : "3000", admin : true});
|
||||
|
||||
// In this case, config would be { url: 'www.github.com', port: '3000', debug: true, admin: true }
|
||||
```
|
||||
|
||||
Under each of the sections (such as Array), there are subsections which correspond to Hoek methods. Each subsection will explain how to use the corresponding method. In each js excerpt below, the `var Hoek = require('hoek');` is omitted for brevity.
|
||||
|
||||
## Object
|
||||
|
||||
Hoek provides several helpful methods for objects and arrays.
|
||||
|
||||
### clone(obj)
|
||||
|
||||
This method is used to clone an object or an array. A *deep copy* is made (duplicates everything, including values that are objects, as well as non-enumerable properties).
|
||||
|
||||
```javascript
|
||||
|
||||
var nestedObj = {
|
||||
w: /^something$/ig,
|
||||
x: {
|
||||
a: [1, 2, 3],
|
||||
b: 123456,
|
||||
c: new Date()
|
||||
},
|
||||
y: 'y',
|
||||
z: new Date()
|
||||
};
|
||||
|
||||
var copy = Hoek.clone(nestedObj);
|
||||
|
||||
copy.x.b = 100;
|
||||
|
||||
console.log(copy.y); // results in 'y'
|
||||
console.log(nestedObj.x.b); // results in 123456
|
||||
console.log(copy.x.b); // results in 100
|
||||
```
|
||||
|
||||
### cloneWithShallow(obj, keys)
|
||||
keys is an array of key names to shallow copy
|
||||
|
||||
This method is also used to clone an object or array, however any keys listed in the `keys` array are shallow copied while those not listed are deep copied.
|
||||
|
||||
```javascript
|
||||
|
||||
var nestedObj = {
|
||||
w: /^something$/ig,
|
||||
x: {
|
||||
a: [1, 2, 3],
|
||||
b: 123456,
|
||||
c: new Date()
|
||||
},
|
||||
y: 'y',
|
||||
z: new Date()
|
||||
};
|
||||
|
||||
var copy = Hoek.cloneWithShallow(nestedObj, ['x']);
|
||||
|
||||
copy.x.b = 100;
|
||||
|
||||
console.log(copy.y); // results in 'y'
|
||||
console.log(nestedObj.x.b); // results in 100
|
||||
console.log(copy.x.b); // results in 100
|
||||
```
|
||||
|
||||
### merge(target, source, isNullOverride, isMergeArrays)
|
||||
isNullOverride, isMergeArrays default to true
|
||||
|
||||
Merge all the properties of source into target, source wins in conflict, and by default null and undefined from source are applied.
|
||||
Merge is destructive where the target is modified. For non destructive merge, use `applyToDefaults`.
|
||||
|
||||
|
||||
```javascript
|
||||
|
||||
var target = {a: 1, b : 2};
|
||||
var source = {a: 0, c: 5};
|
||||
var source2 = {a: null, c: 5};
|
||||
|
||||
Hoek.merge(target, source); // results in {a: 0, b: 2, c: 5}
|
||||
Hoek.merge(target, source2); // results in {a: null, b: 2, c: 5}
|
||||
Hoek.merge(target, source2, false); // results in {a: 1, b: 2, c: 5}
|
||||
|
||||
var targetArray = [1, 2, 3];
|
||||
var sourceArray = [4, 5];
|
||||
|
||||
Hoek.merge(targetArray, sourceArray); // results in [1, 2, 3, 4, 5]
|
||||
Hoek.merge(targetArray, sourceArray, true, false); // results in [4, 5]
|
||||
```
|
||||
|
||||
### applyToDefaults(defaults, options, isNullOverride)
|
||||
isNullOverride defaults to false
|
||||
|
||||
Apply options to a copy of the defaults
|
||||
|
||||
```javascript
|
||||
|
||||
var defaults = { host: "localhost", port: 8000 };
|
||||
var options = { port: 8080 };
|
||||
|
||||
var config = Hoek.applyToDefaults(defaults, options); // results in { host: "localhost", port: 8080 }
|
||||
```
|
||||
|
||||
Apply options with a null value to a copy of the defaults
|
||||
|
||||
```javascript
|
||||
|
||||
var defaults = { host: "localhost", port: 8000 };
|
||||
var options = { host: null, port: 8080 };
|
||||
|
||||
var config = Hoek.applyToDefaults(defaults, options, true); // results in { host: null, port: 8080 }
|
||||
```
|
||||
|
||||
### applyToDefaultsWithShallow(defaults, options, keys)
|
||||
keys is an array of key names to shallow copy
|
||||
|
||||
Apply options to a copy of the defaults. Keys specified in the last parameter are shallow copied from options instead of merged.
|
||||
|
||||
```javascript
|
||||
|
||||
var defaults = {
|
||||
server: {
|
||||
host: "localhost",
|
||||
port: 8000
|
||||
},
|
||||
name: 'example'
|
||||
};
|
||||
|
||||
var options = { server: { port: 8080 } };
|
||||
|
||||
var config = Hoek.applyToDefaultsWithShallow(defaults, options, ['server']); // results in { server: { port: 8080 }, name: 'example' }
|
||||
```
|
||||
|
||||
### deepEqual(b, a, [options])
|
||||
|
||||
Performs a deep comparison of the two values including support for circular dependencies, prototype, and properties. To skip prototype comparisons, use `options.prototype = false`
|
||||
|
||||
```javascript
|
||||
Hoek.deepEqual({ a: [1, 2], b: 'string', c: { d: true } }, { a: [1, 2], b: 'string', c: { d: true } }); //results in true
|
||||
Hoek.deepEqual(Object.create(null), {}, { prototype: false }); //results in true
|
||||
Hoek.deepEqual(Object.create(null), {}); //results in false
|
||||
```
|
||||
|
||||
### unique(array, key)
|
||||
|
||||
Remove duplicate items from Array
|
||||
|
||||
```javascript
|
||||
|
||||
var array = [1, 2, 2, 3, 3, 4, 5, 6];
|
||||
|
||||
var newArray = Hoek.unique(array); // results in [1,2,3,4,5,6]
|
||||
|
||||
array = [{id: 1}, {id: 1}, {id: 2}];
|
||||
|
||||
newArray = Hoek.unique(array, "id"); // results in [{id: 1}, {id: 2}]
|
||||
```
|
||||
|
||||
### mapToObject(array, key)
|
||||
|
||||
Convert an Array into an Object
|
||||
|
||||
```javascript
|
||||
|
||||
var array = [1,2,3];
|
||||
var newObject = Hoek.mapToObject(array); // results in [{"1": true}, {"2": true}, {"3": true}]
|
||||
|
||||
array = [{id: 1}, {id: 2}];
|
||||
newObject = Hoek.mapToObject(array, "id"); // results in [{"id": 1}, {"id": 2}]
|
||||
```
|
||||
|
||||
### intersect(array1, array2)
|
||||
|
||||
Find the common unique items in two arrays
|
||||
|
||||
```javascript
|
||||
|
||||
var array1 = [1, 2, 3];
|
||||
var array2 = [1, 4, 5];
|
||||
|
||||
var newArray = Hoek.intersect(array1, array2); // results in [1]
|
||||
```
|
||||
|
||||
### contain(ref, values, [options])
|
||||
|
||||
Tests if the reference value contains the provided values where:
|
||||
- `ref` - the reference string, array, or object.
|
||||
- `values` - a single or array of values to find within the `ref` value. If `ref` is an object, `values` can be a key name,
|
||||
an array of key names, or an object with key-value pairs to compare.
|
||||
- `options` - an optional object with the following optional settings:
|
||||
- `deep` - if `true`, performed a deep comparison of the values.
|
||||
- `once` - if `true`, allows only one occurrence of each value.
|
||||
- `only` - if `true`, does not allow values not explicitly listed.
|
||||
- `part` - if `true`, allows partial match of the values (at least one must always match).
|
||||
|
||||
Note: comparing a string to overlapping values will result in failed comparison (e.g. `contain('abc', ['ab', 'bc'])`).
|
||||
Also, if an object key's value does not match the provided value, `false` is returned even when `part` is specified.
|
||||
|
||||
```javascript
|
||||
Hoek.contain('aaa', 'a', { only: true }); // true
|
||||
Hoek.contain([{ a: 1 }], [{ a: 1 }], { deep: true }); // true
|
||||
Hoek.contain([1, 2, 2], [1, 2], { once: true }); // false
|
||||
Hoek.contain({ a: 1, b: 2, c: 3 }, { a: 1, d: 4 }, { part: true }); // true
|
||||
```
|
||||
|
||||
### flatten(array, [target])
|
||||
|
||||
Flatten an array
|
||||
|
||||
```javascript
|
||||
|
||||
var array = [1, [2, 3]];
|
||||
|
||||
var flattenedArray = Hoek.flatten(array); // results in [1, 2, 3]
|
||||
|
||||
array = [1, [2, 3]];
|
||||
target = [4, [5]];
|
||||
|
||||
flattenedArray = Hoek.flatten(array, target); // results in [4, [5], 1, 2, 3]
|
||||
```
|
||||
|
||||
### reach(obj, chain, [options])
|
||||
|
||||
Converts an object key chain string to reference
|
||||
|
||||
- `options` - optional settings
|
||||
- `separator` - string to split chain path on, defaults to '.'
|
||||
- `default` - value to return if the path or value is not present, default is `undefined`
|
||||
- `strict` - if `true`, will throw an error on missing member, default is `false`
|
||||
- `functions` - if `true` allow traversing functions for properties. `false` will throw an error if a function is part of the chain.
|
||||
|
||||
A chain including negative numbers will work like negative indices on an
|
||||
array.
|
||||
|
||||
If chain is `null`, `undefined` or `false`, the object itself will be returned.
|
||||
|
||||
```javascript
|
||||
|
||||
var chain = 'a.b.c';
|
||||
var obj = {a : {b : { c : 1}}};
|
||||
|
||||
Hoek.reach(obj, chain); // returns 1
|
||||
|
||||
var chain = 'a.b.-1';
|
||||
var obj = {a : {b : [2,3,6]}};
|
||||
|
||||
Hoek.reach(obj, chain); // returns 6
|
||||
```
|
||||
|
||||
### reachTemplate(obj, template, [options])
|
||||
|
||||
Replaces string parameters (`{name}`) with their corresponding object key values by applying the
|
||||
(`reach()`)[#reachobj-chain-options] method where:
|
||||
|
||||
- `obj` - the context object used for key lookup.
|
||||
- `template` - a string containing `{}` parameters.
|
||||
- `options` - optional (`reach()`)[#reachobj-chain-options] options.
|
||||
|
||||
```javascript
|
||||
|
||||
var chain = 'a.b.c';
|
||||
var obj = {a : {b : { c : 1}}};
|
||||
|
||||
Hoek.reachTemplate(obj, '1+{a.b.c}=2'); // returns '1+1=2'
|
||||
```
|
||||
|
||||
### transform(obj, transform, [options])
|
||||
|
||||
Transforms an existing object into a new one based on the supplied `obj` and `transform` map. `options` are the same as the `reach` options. The first argument can also be an array of objects. In that case the method will return an array of transformed objects.
|
||||
|
||||
```javascript
|
||||
var source = {
|
||||
address: {
|
||||
one: '123 main street',
|
||||
two: 'PO Box 1234'
|
||||
},
|
||||
title: 'Warehouse',
|
||||
state: 'CA'
|
||||
};
|
||||
|
||||
var result = Hoek.transform(source, {
|
||||
'person.address.lineOne': 'address.one',
|
||||
'person.address.lineTwo': 'address.two',
|
||||
'title': 'title',
|
||||
'person.address.region': 'state'
|
||||
});
|
||||
// Results in
|
||||
// {
|
||||
// person: {
|
||||
// address: {
|
||||
// lineOne: '123 main street',
|
||||
// lineTwo: 'PO Box 1234',
|
||||
// region: 'CA'
|
||||
// }
|
||||
// },
|
||||
// title: 'Warehouse'
|
||||
// }
|
||||
```
|
||||
|
||||
### shallow(obj)
|
||||
|
||||
Performs a shallow copy by copying the references of all the top level children where:
|
||||
- `obj` - the object to be copied.
|
||||
|
||||
```javascript
|
||||
var shallow = Hoek.shallow({ a: { b: 1 } });
|
||||
```
|
||||
|
||||
### stringify(obj)
|
||||
|
||||
Converts an object to string using the built-in `JSON.stringify()` method with the difference that any errors are caught
|
||||
and reported back in the form of the returned string. Used as a shortcut for displaying information to the console (e.g. in
|
||||
error message) without the need to worry about invalid conversion.
|
||||
|
||||
```javascript
|
||||
var a = {};
|
||||
a.b = a;
|
||||
Hoek.stringify(a); // Returns '[Cannot display object: Converting circular structure to JSON]'
|
||||
```
|
||||
|
||||
# Timer
|
||||
|
||||
A Timer object. Initializing a new timer object sets the ts to the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC.
|
||||
|
||||
```javascript
|
||||
|
||||
var timerObj = new Hoek.Timer();
|
||||
console.log("Time is now: " + timerObj.ts);
|
||||
console.log("Elapsed time from initialization: " + timerObj.elapsed() + 'milliseconds');
|
||||
```
|
||||
|
||||
|
||||
# Bench
|
||||
|
||||
Same as Timer with the exception that `ts` stores the internal node clock which is not related to `Date.now()` and cannot be used to display
|
||||
human-readable timestamps. More accurate for benchmarking or internal timers.
|
||||
|
||||
# Binary Encoding/Decoding
|
||||
|
||||
### base64urlEncode(value)
|
||||
|
||||
Encodes value in Base64 or URL encoding
|
||||
|
||||
### base64urlDecode(value)
|
||||
|
||||
Decodes data in Base64 or URL encoding.
|
||||
# Escaping Characters
|
||||
|
||||
Hoek provides convenient methods for escaping html characters. The escaped characters are as followed:
|
||||
|
||||
```javascript
|
||||
|
||||
internals.htmlEscaped = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
"'": ''',
|
||||
'`': '`'
|
||||
};
|
||||
```
|
||||
|
||||
### escapeHtml(string)
|
||||
|
||||
```javascript
|
||||
|
||||
var string = '<html> hey </html>';
|
||||
var escapedString = Hoek.escapeHtml(string); // returns <html> hey </html>
|
||||
```
|
||||
|
||||
### escapeHeaderAttribute(attribute)
|
||||
|
||||
Escape attribute value for use in HTTP header
|
||||
|
||||
```javascript
|
||||
|
||||
var a = Hoek.escapeHeaderAttribute('I said "go w\\o me"'); //returns I said \"go w\\o me\"
|
||||
```
|
||||
|
||||
|
||||
### escapeRegex(string)
|
||||
|
||||
Escape string for Regex construction
|
||||
|
||||
```javascript
|
||||
|
||||
var a = Hoek.escapeRegex('4^f$s.4*5+-_?%=#!:@|~\\/`"(>)[<]d{}s,'); // returns 4\^f\$s\.4\*5\+\-_\?%\=#\!\:@\|~\\\/`"\(>\)\[<\]d\{\}s\,
|
||||
```
|
||||
|
||||
# Errors
|
||||
|
||||
### assert(condition, message)
|
||||
|
||||
```javascript
|
||||
|
||||
var a = 1, b = 2;
|
||||
|
||||
Hoek.assert(a === b, 'a should equal b'); // Throws 'a should equal b'
|
||||
```
|
||||
|
||||
Note that you may also pass an already created Error object as the second parameter, and `assert` will throw that object.
|
||||
|
||||
```javascript
|
||||
|
||||
var a = 1, b = 2;
|
||||
|
||||
Hoek.assert(a === b, new Error('a should equal b')); // Throws the given error object
|
||||
```
|
||||
|
||||
### abort(message)
|
||||
|
||||
First checks if `process.env.NODE_ENV === 'test'`, and if so, throws error message. Otherwise,
|
||||
displays most recent stack and then exits process.
|
||||
|
||||
|
||||
|
||||
### displayStack(slice)
|
||||
|
||||
Displays the trace stack
|
||||
|
||||
```javascript
|
||||
|
||||
var stack = Hoek.displayStack();
|
||||
console.log(stack); // returns something like:
|
||||
|
||||
[ 'null (/Users/user/Desktop/hoek/test.js:4:18)',
|
||||
'Module._compile (module.js:449:26)',
|
||||
'Module._extensions..js (module.js:467:10)',
|
||||
'Module.load (module.js:356:32)',
|
||||
'Module._load (module.js:312:12)',
|
||||
'Module.runMain (module.js:492:10)',
|
||||
'startup.processNextTick.process._tickCallback (node.js:244:9)' ]
|
||||
```
|
||||
|
||||
### callStack(slice)
|
||||
|
||||
Returns a trace stack array.
|
||||
|
||||
```javascript
|
||||
|
||||
var stack = Hoek.callStack();
|
||||
console.log(stack); // returns something like:
|
||||
|
||||
[ [ '/Users/user/Desktop/hoek/test.js', 4, 18, null, false ],
|
||||
[ 'module.js', 449, 26, 'Module._compile', false ],
|
||||
[ 'module.js', 467, 10, 'Module._extensions..js', false ],
|
||||
[ 'module.js', 356, 32, 'Module.load', false ],
|
||||
[ 'module.js', 312, 12, 'Module._load', false ],
|
||||
[ 'module.js', 492, 10, 'Module.runMain', false ],
|
||||
[ 'node.js',
|
||||
244,
|
||||
9,
|
||||
'startup.processNextTick.process._tickCallback',
|
||||
false ] ]
|
||||
```
|
||||
|
||||
## Function
|
||||
|
||||
### nextTick(fn)
|
||||
|
||||
Returns a new function that wraps `fn` in `process.nextTick`.
|
||||
|
||||
```javascript
|
||||
|
||||
var myFn = function () {
|
||||
console.log('Do this later');
|
||||
};
|
||||
|
||||
var nextFn = Hoek.nextTick(myFn);
|
||||
|
||||
nextFn();
|
||||
console.log('Do this first');
|
||||
|
||||
// Results in:
|
||||
//
|
||||
// Do this first
|
||||
// Do this later
|
||||
```
|
||||
|
||||
### once(fn)
|
||||
|
||||
Returns a new function that can be run multiple times, but makes sure `fn` is only run once.
|
||||
|
||||
```javascript
|
||||
|
||||
var myFn = function () {
|
||||
console.log('Ran myFn');
|
||||
};
|
||||
|
||||
var onceFn = Hoek.once(myFn);
|
||||
onceFn(); // results in "Ran myFn"
|
||||
onceFn(); // results in undefined
|
||||
```
|
||||
|
||||
### ignore
|
||||
|
||||
A simple no-op function. It does nothing at all.
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
### uniqueFilename(path, extension)
|
||||
`path` to prepend with the randomly generated file name. `extension` is the optional file extension, defaults to `''`.
|
||||
|
||||
Returns a randomly generated file name at the specified `path`. The result is a fully resolved path to a file.
|
||||
|
||||
```javascript
|
||||
var result = Hoek.uniqueFilename('./test/modules', 'txt'); // results in "full/path/test/modules/{random}.txt"
|
||||
```
|
||||
|
||||
### isAbsolutePath(path, [platform])
|
||||
|
||||
Determines whether `path` is an absolute path. Returns `true` or `false`.
|
||||
|
||||
- `path` - A file path to test for whether it is absolute or not.
|
||||
- `platform` - An optional parameter used for specifying the platform. Defaults to `process.platform`.
|
||||
|
||||
### isInteger(value)
|
||||
|
||||
Check `value` to see if it is an integer. Returns true/false.
|
||||
|
||||
```javascript
|
||||
var result = Hoek.isInteger('23')
|
||||
```
|
||||
BIN
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/images/hoek.png
generated
vendored
Normal file
BIN
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/images/hoek.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 37 KiB |
132
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/lib/escape.js
generated
vendored
Normal file
132
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/lib/escape.js
generated
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
|
||||
exports.escapeJavaScript = function (input) {
|
||||
|
||||
if (!input) {
|
||||
return '';
|
||||
}
|
||||
|
||||
var escaped = '';
|
||||
|
||||
for (var i = 0, il = input.length; i < il; ++i) {
|
||||
|
||||
var charCode = input.charCodeAt(i);
|
||||
|
||||
if (internals.isSafe(charCode)) {
|
||||
escaped += input[i];
|
||||
}
|
||||
else {
|
||||
escaped += internals.escapeJavaScriptChar(charCode);
|
||||
}
|
||||
}
|
||||
|
||||
return escaped;
|
||||
};
|
||||
|
||||
|
||||
exports.escapeHtml = function (input) {
|
||||
|
||||
if (!input) {
|
||||
return '';
|
||||
}
|
||||
|
||||
var escaped = '';
|
||||
|
||||
for (var i = 0, il = input.length; i < il; ++i) {
|
||||
|
||||
var charCode = input.charCodeAt(i);
|
||||
|
||||
if (internals.isSafe(charCode)) {
|
||||
escaped += input[i];
|
||||
}
|
||||
else {
|
||||
escaped += internals.escapeHtmlChar(charCode);
|
||||
}
|
||||
}
|
||||
|
||||
return escaped;
|
||||
};
|
||||
|
||||
|
||||
internals.escapeJavaScriptChar = function (charCode) {
|
||||
|
||||
if (charCode >= 256) {
|
||||
return '\\u' + internals.padLeft('' + charCode, 4);
|
||||
}
|
||||
|
||||
var hexValue = new Buffer(String.fromCharCode(charCode), 'ascii').toString('hex');
|
||||
return '\\x' + internals.padLeft(hexValue, 2);
|
||||
};
|
||||
|
||||
|
||||
internals.escapeHtmlChar = function (charCode) {
|
||||
|
||||
var namedEscape = internals.namedHtml[charCode];
|
||||
if (typeof namedEscape !== 'undefined') {
|
||||
return namedEscape;
|
||||
}
|
||||
|
||||
if (charCode >= 256) {
|
||||
return '&#' + charCode + ';';
|
||||
}
|
||||
|
||||
var hexValue = new Buffer(String.fromCharCode(charCode), 'ascii').toString('hex');
|
||||
return '&#x' + internals.padLeft(hexValue, 2) + ';';
|
||||
};
|
||||
|
||||
|
||||
internals.padLeft = function (str, len) {
|
||||
|
||||
while (str.length < len) {
|
||||
str = '0' + str;
|
||||
}
|
||||
|
||||
return str;
|
||||
};
|
||||
|
||||
|
||||
internals.isSafe = function (charCode) {
|
||||
|
||||
return (typeof internals.safeCharCodes[charCode] !== 'undefined');
|
||||
};
|
||||
|
||||
|
||||
internals.namedHtml = {
|
||||
'38': '&',
|
||||
'60': '<',
|
||||
'62': '>',
|
||||
'34': '"',
|
||||
'160': ' ',
|
||||
'162': '¢',
|
||||
'163': '£',
|
||||
'164': '¤',
|
||||
'169': '©',
|
||||
'174': '®'
|
||||
};
|
||||
|
||||
|
||||
internals.safeCharCodes = (function () {
|
||||
|
||||
var safe = {};
|
||||
|
||||
for (var i = 32; i < 123; ++i) {
|
||||
|
||||
if ((i >= 97) || // a-z
|
||||
(i >= 65 && i <= 90) || // A-Z
|
||||
(i >= 48 && i <= 57) || // 0-9
|
||||
i === 32 || // space
|
||||
i === 46 || // .
|
||||
i === 44 || // ,
|
||||
i === 45 || // -
|
||||
i === 58 || // :
|
||||
i === 95) { // _
|
||||
|
||||
safe[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return safe;
|
||||
}());
|
||||
993
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/lib/index.js
generated
vendored
Normal file
993
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/lib/index.js
generated
vendored
Normal file
@ -0,0 +1,993 @@
|
||||
// Load modules
|
||||
|
||||
var Crypto = require('crypto');
|
||||
var Path = require('path');
|
||||
var Util = require('util');
|
||||
var Escape = require('./escape');
|
||||
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
|
||||
// Clone object or array
|
||||
|
||||
exports.clone = function (obj, seen) {
|
||||
|
||||
if (typeof obj !== 'object' ||
|
||||
obj === null) {
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
seen = seen || { orig: [], copy: [] };
|
||||
|
||||
var lookup = seen.orig.indexOf(obj);
|
||||
if (lookup !== -1) {
|
||||
return seen.copy[lookup];
|
||||
}
|
||||
|
||||
var newObj;
|
||||
var cloneDeep = false;
|
||||
|
||||
if (!Array.isArray(obj)) {
|
||||
if (Buffer.isBuffer(obj)) {
|
||||
newObj = new Buffer(obj);
|
||||
}
|
||||
else if (obj instanceof Date) {
|
||||
newObj = new Date(obj.getTime());
|
||||
}
|
||||
else if (obj instanceof RegExp) {
|
||||
newObj = new RegExp(obj);
|
||||
}
|
||||
else {
|
||||
var proto = Object.getPrototypeOf(obj);
|
||||
if (proto &&
|
||||
proto.isImmutable) {
|
||||
|
||||
newObj = obj;
|
||||
}
|
||||
else {
|
||||
newObj = Object.create(proto);
|
||||
cloneDeep = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
newObj = [];
|
||||
cloneDeep = true;
|
||||
}
|
||||
|
||||
seen.orig.push(obj);
|
||||
seen.copy.push(newObj);
|
||||
|
||||
if (cloneDeep) {
|
||||
var keys = Object.getOwnPropertyNames(obj);
|
||||
for (var i = 0, il = keys.length; i < il; ++i) {
|
||||
var key = keys[i];
|
||||
var descriptor = Object.getOwnPropertyDescriptor(obj, key);
|
||||
if (descriptor &&
|
||||
(descriptor.get ||
|
||||
descriptor.set)) {
|
||||
|
||||
Object.defineProperty(newObj, key, descriptor);
|
||||
}
|
||||
else {
|
||||
newObj[key] = exports.clone(obj[key], seen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newObj;
|
||||
};
|
||||
|
||||
|
||||
// Merge all the properties of source into target, source wins in conflict, and by default null and undefined from source are applied
|
||||
/*eslint-disable */
|
||||
exports.merge = function (target, source, isNullOverride /* = true */, isMergeArrays /* = true */) {
|
||||
/*eslint-enable */
|
||||
exports.assert(target && typeof target === 'object', 'Invalid target value: must be an object');
|
||||
exports.assert(source === null || source === undefined || typeof source === 'object', 'Invalid source value: must be null, undefined, or an object');
|
||||
|
||||
if (!source) {
|
||||
return target;
|
||||
}
|
||||
|
||||
if (Array.isArray(source)) {
|
||||
exports.assert(Array.isArray(target), 'Cannot merge array onto an object');
|
||||
if (isMergeArrays === false) { // isMergeArrays defaults to true
|
||||
target.length = 0; // Must not change target assignment
|
||||
}
|
||||
|
||||
for (var i = 0, il = source.length; i < il; ++i) {
|
||||
target.push(exports.clone(source[i]));
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
var keys = Object.keys(source);
|
||||
for (var k = 0, kl = keys.length; k < kl; ++k) {
|
||||
var key = keys[k];
|
||||
var value = source[key];
|
||||
if (value &&
|
||||
typeof value === 'object') {
|
||||
|
||||
if (!target[key] ||
|
||||
typeof target[key] !== 'object' ||
|
||||
(Array.isArray(target[key]) ^ Array.isArray(value)) ||
|
||||
value instanceof Date ||
|
||||
Buffer.isBuffer(value) ||
|
||||
value instanceof RegExp) {
|
||||
|
||||
target[key] = exports.clone(value);
|
||||
}
|
||||
else {
|
||||
exports.merge(target[key], value, isNullOverride, isMergeArrays);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (value !== null &&
|
||||
value !== undefined) { // Explicit to preserve empty strings
|
||||
|
||||
target[key] = value;
|
||||
}
|
||||
else if (isNullOverride !== false) { // Defaults to true
|
||||
target[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
};
|
||||
|
||||
|
||||
// Apply options to a copy of the defaults
|
||||
|
||||
exports.applyToDefaults = function (defaults, options, isNullOverride) {
|
||||
|
||||
exports.assert(defaults && typeof defaults === 'object', 'Invalid defaults value: must be an object');
|
||||
exports.assert(!options || options === true || typeof options === 'object', 'Invalid options value: must be true, falsy or an object');
|
||||
|
||||
if (!options) { // If no options, return null
|
||||
return null;
|
||||
}
|
||||
|
||||
var copy = exports.clone(defaults);
|
||||
|
||||
if (options === true) { // If options is set to true, use defaults
|
||||
return copy;
|
||||
}
|
||||
|
||||
return exports.merge(copy, options, isNullOverride === true, false);
|
||||
};
|
||||
|
||||
|
||||
// Clone an object except for the listed keys which are shallow copied
|
||||
|
||||
exports.cloneWithShallow = function (source, keys) {
|
||||
|
||||
if (!source ||
|
||||
typeof source !== 'object') {
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
var storage = internals.store(source, keys); // Move shallow copy items to storage
|
||||
var copy = exports.clone(source); // Deep copy the rest
|
||||
internals.restore(copy, source, storage); // Shallow copy the stored items and restore
|
||||
return copy;
|
||||
};
|
||||
|
||||
|
||||
internals.store = function (source, keys) {
|
||||
|
||||
var storage = {};
|
||||
for (var i = 0, il = keys.length; i < il; ++i) {
|
||||
var key = keys[i];
|
||||
var value = exports.reach(source, key);
|
||||
if (value !== undefined) {
|
||||
storage[key] = value;
|
||||
internals.reachSet(source, key, undefined);
|
||||
}
|
||||
}
|
||||
|
||||
return storage;
|
||||
};
|
||||
|
||||
|
||||
internals.restore = function (copy, source, storage) {
|
||||
|
||||
var keys = Object.keys(storage);
|
||||
for (var i = 0, il = keys.length; i < il; ++i) {
|
||||
var key = keys[i];
|
||||
internals.reachSet(copy, key, storage[key]);
|
||||
internals.reachSet(source, key, storage[key]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
internals.reachSet = function (obj, key, value) {
|
||||
|
||||
var path = key.split('.');
|
||||
var ref = obj;
|
||||
for (var i = 0, il = path.length; i < il; ++i) {
|
||||
var segment = path[i];
|
||||
if (i + 1 === il) {
|
||||
ref[segment] = value;
|
||||
}
|
||||
|
||||
ref = ref[segment];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Apply options to defaults except for the listed keys which are shallow copied from option without merging
|
||||
|
||||
exports.applyToDefaultsWithShallow = function (defaults, options, keys) {
|
||||
|
||||
exports.assert(defaults && typeof defaults === 'object', 'Invalid defaults value: must be an object');
|
||||
exports.assert(!options || options === true || typeof options === 'object', 'Invalid options value: must be true, falsy or an object');
|
||||
exports.assert(keys && Array.isArray(keys), 'Invalid keys');
|
||||
|
||||
if (!options) { // If no options, return null
|
||||
return null;
|
||||
}
|
||||
|
||||
var copy = exports.cloneWithShallow(defaults, keys);
|
||||
|
||||
if (options === true) { // If options is set to true, use defaults
|
||||
return copy;
|
||||
}
|
||||
|
||||
var storage = internals.store(options, keys); // Move shallow copy items to storage
|
||||
exports.merge(copy, options, false, false); // Deep copy the rest
|
||||
internals.restore(copy, options, storage); // Shallow copy the stored items and restore
|
||||
return copy;
|
||||
};
|
||||
|
||||
|
||||
// Deep object or array comparison
|
||||
|
||||
exports.deepEqual = function (obj, ref, options, seen) {
|
||||
|
||||
options = options || { prototype: true };
|
||||
|
||||
var type = typeof obj;
|
||||
|
||||
if (type !== typeof ref) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type !== 'object' ||
|
||||
obj === null ||
|
||||
ref === null) {
|
||||
|
||||
if (obj === ref) { // Copied from Deep-eql, copyright(c) 2013 Jake Luer, jake@alogicalparadox.com, MIT Licensed, https://github.com/chaijs/deep-eql
|
||||
return obj !== 0 || 1 / obj === 1 / ref; // -0 / +0
|
||||
}
|
||||
|
||||
return obj !== obj && ref !== ref; // NaN
|
||||
}
|
||||
|
||||
seen = seen || [];
|
||||
if (seen.indexOf(obj) !== -1) {
|
||||
return true; // If previous comparison failed, it would have stopped execution
|
||||
}
|
||||
|
||||
seen.push(obj);
|
||||
|
||||
if (Array.isArray(obj)) {
|
||||
if (!Array.isArray(ref)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!options.part && obj.length !== ref.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0, il = obj.length; i < il; ++i) {
|
||||
if (options.part) {
|
||||
var found = false;
|
||||
for (var r = 0, rl = ref.length; r < rl; ++r) {
|
||||
if (exports.deepEqual(obj[i], ref[r], options, seen)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
if (!exports.deepEqual(obj[i], ref[i], options, seen)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Buffer.isBuffer(obj)) {
|
||||
if (!Buffer.isBuffer(ref)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (obj.length !== ref.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var j = 0, jl = obj.length; j < jl; ++j) {
|
||||
if (obj[j] !== ref[j]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj instanceof Date) {
|
||||
return (ref instanceof Date && obj.getTime() === ref.getTime());
|
||||
}
|
||||
|
||||
if (obj instanceof RegExp) {
|
||||
return (ref instanceof RegExp && obj.toString() === ref.toString());
|
||||
}
|
||||
|
||||
if (options.prototype) {
|
||||
if (Object.getPrototypeOf(obj) !== Object.getPrototypeOf(ref)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var keys = Object.getOwnPropertyNames(obj);
|
||||
|
||||
if (!options.part && keys.length !== Object.getOwnPropertyNames(ref).length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var k = 0, kl = keys.length; k < kl; ++k) {
|
||||
var key = keys[k];
|
||||
var descriptor = Object.getOwnPropertyDescriptor(obj, key);
|
||||
if (descriptor.get) {
|
||||
if (!exports.deepEqual(descriptor, Object.getOwnPropertyDescriptor(ref, key), options, seen)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!exports.deepEqual(obj[key], ref[key], options, seen)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
// Remove duplicate items from array
|
||||
|
||||
exports.unique = function (array, key) {
|
||||
|
||||
var index = {};
|
||||
var result = [];
|
||||
|
||||
for (var i = 0, il = array.length; i < il; ++i) {
|
||||
var id = (key ? array[i][key] : array[i]);
|
||||
if (index[id] !== true) {
|
||||
|
||||
result.push(array[i]);
|
||||
index[id] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
// Convert array into object
|
||||
|
||||
exports.mapToObject = function (array, key) {
|
||||
|
||||
if (!array) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var obj = {};
|
||||
for (var i = 0, il = array.length; i < il; ++i) {
|
||||
if (key) {
|
||||
if (array[i][key]) {
|
||||
obj[array[i][key]] = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
obj[array[i]] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
|
||||
// Find the common unique items in two arrays
|
||||
|
||||
exports.intersect = function (array1, array2, justFirst) {
|
||||
|
||||
if (!array1 || !array2) {
|
||||
return [];
|
||||
}
|
||||
|
||||
var common = [];
|
||||
var hash = (Array.isArray(array1) ? exports.mapToObject(array1) : array1);
|
||||
var found = {};
|
||||
for (var i = 0, il = array2.length; i < il; ++i) {
|
||||
if (hash[array2[i]] && !found[array2[i]]) {
|
||||
if (justFirst) {
|
||||
return array2[i];
|
||||
}
|
||||
|
||||
common.push(array2[i]);
|
||||
found[array2[i]] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return (justFirst ? null : common);
|
||||
};
|
||||
|
||||
|
||||
// Test if the reference contains the values
|
||||
|
||||
exports.contain = function (ref, values, options) {
|
||||
|
||||
/*
|
||||
string -> string(s)
|
||||
array -> item(s)
|
||||
object -> key(s)
|
||||
object -> object (key:value)
|
||||
*/
|
||||
|
||||
var valuePairs = null;
|
||||
if (typeof ref === 'object' &&
|
||||
typeof values === 'object' &&
|
||||
!Array.isArray(ref) &&
|
||||
!Array.isArray(values)) {
|
||||
|
||||
valuePairs = values;
|
||||
values = Object.keys(values);
|
||||
}
|
||||
else {
|
||||
values = [].concat(values);
|
||||
}
|
||||
|
||||
options = options || {}; // deep, once, only, part
|
||||
|
||||
exports.assert(arguments.length >= 2, 'Insufficient arguments');
|
||||
exports.assert(typeof ref === 'string' || typeof ref === 'object', 'Reference must be string or an object');
|
||||
exports.assert(values.length, 'Values array cannot be empty');
|
||||
|
||||
var compare, compareFlags;
|
||||
if (options.deep) {
|
||||
compare = exports.deepEqual;
|
||||
|
||||
var hasOnly = options.hasOwnProperty('only'), hasPart = options.hasOwnProperty('part');
|
||||
|
||||
compareFlags = {
|
||||
prototype: hasOnly ? options.only : hasPart ? !options.part : false,
|
||||
part: hasOnly ? !options.only : hasPart ? options.part : true
|
||||
};
|
||||
}
|
||||
else {
|
||||
compare = function (a, b) {
|
||||
|
||||
return a === b;
|
||||
};
|
||||
}
|
||||
|
||||
var misses = false;
|
||||
var matches = new Array(values.length);
|
||||
for (var i = 0, il = matches.length; i < il; ++i) {
|
||||
matches[i] = 0;
|
||||
}
|
||||
|
||||
if (typeof ref === 'string') {
|
||||
var pattern = '(';
|
||||
for (i = 0, il = values.length; i < il; ++i) {
|
||||
var value = values[i];
|
||||
exports.assert(typeof value === 'string', 'Cannot compare string reference to non-string value');
|
||||
pattern += (i ? '|' : '') + exports.escapeRegex(value);
|
||||
}
|
||||
|
||||
var regex = new RegExp(pattern + ')', 'g');
|
||||
var leftovers = ref.replace(regex, function ($0, $1) {
|
||||
|
||||
var index = values.indexOf($1);
|
||||
++matches[index];
|
||||
return ''; // Remove from string
|
||||
});
|
||||
|
||||
misses = !!leftovers;
|
||||
}
|
||||
else if (Array.isArray(ref)) {
|
||||
for (i = 0, il = ref.length; i < il; ++i) {
|
||||
for (var j = 0, jl = values.length, matched = false; j < jl && matched === false; ++j) {
|
||||
matched = compare(values[j], ref[i], compareFlags) && j;
|
||||
}
|
||||
|
||||
if (matched !== false) {
|
||||
++matches[matched];
|
||||
}
|
||||
else {
|
||||
misses = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
var keys = Object.keys(ref);
|
||||
for (i = 0, il = keys.length; i < il; ++i) {
|
||||
var key = keys[i];
|
||||
var pos = values.indexOf(key);
|
||||
if (pos !== -1) {
|
||||
if (valuePairs &&
|
||||
!compare(valuePairs[key], ref[key], compareFlags)) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
++matches[pos];
|
||||
}
|
||||
else {
|
||||
misses = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var result = false;
|
||||
for (i = 0, il = matches.length; i < il; ++i) {
|
||||
result = result || !!matches[i];
|
||||
if ((options.once && matches[i] > 1) ||
|
||||
(!options.part && !matches[i])) {
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (options.only &&
|
||||
misses) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
// Flatten array
|
||||
|
||||
exports.flatten = function (array, target) {
|
||||
|
||||
var result = target || [];
|
||||
|
||||
for (var i = 0, il = array.length; i < il; ++i) {
|
||||
if (Array.isArray(array[i])) {
|
||||
exports.flatten(array[i], result);
|
||||
}
|
||||
else {
|
||||
result.push(array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
// Convert an object key chain string ('a.b.c') to reference (object[a][b][c])
|
||||
|
||||
exports.reach = function (obj, chain, options) {
|
||||
|
||||
if (chain === false ||
|
||||
chain === null ||
|
||||
typeof chain === 'undefined') {
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
if (typeof options === 'string') {
|
||||
options = { separator: options };
|
||||
}
|
||||
|
||||
var path = chain.split(options.separator || '.');
|
||||
var ref = obj;
|
||||
for (var i = 0, il = path.length; i < il; ++i) {
|
||||
var key = path[i];
|
||||
if (key[0] === '-' && Array.isArray(ref)) {
|
||||
key = key.slice(1, key.length);
|
||||
key = ref.length - key;
|
||||
}
|
||||
|
||||
if (!ref ||
|
||||
!ref.hasOwnProperty(key) ||
|
||||
(typeof ref !== 'object' && options.functions === false)) { // Only object and function can have properties
|
||||
|
||||
exports.assert(!options.strict || i + 1 === il, 'Missing segment', key, 'in reach path ', chain);
|
||||
exports.assert(typeof ref === 'object' || options.functions === true || typeof ref !== 'function', 'Invalid segment', key, 'in reach path ', chain);
|
||||
ref = options.default;
|
||||
break;
|
||||
}
|
||||
|
||||
ref = ref[key];
|
||||
}
|
||||
|
||||
return ref;
|
||||
};
|
||||
|
||||
|
||||
exports.reachTemplate = function (obj, template, options) {
|
||||
|
||||
return template.replace(/{([^}]+)}/g, function ($0, chain) {
|
||||
|
||||
var value = exports.reach(obj, chain, options);
|
||||
return (value === undefined || value === null ? '' : value);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
exports.formatStack = function (stack) {
|
||||
|
||||
var trace = [];
|
||||
for (var i = 0, il = stack.length; i < il; ++i) {
|
||||
var item = stack[i];
|
||||
trace.push([item.getFileName(), item.getLineNumber(), item.getColumnNumber(), item.getFunctionName(), item.isConstructor()]);
|
||||
}
|
||||
|
||||
return trace;
|
||||
};
|
||||
|
||||
|
||||
exports.formatTrace = function (trace) {
|
||||
|
||||
var display = [];
|
||||
|
||||
for (var i = 0, il = trace.length; i < il; ++i) {
|
||||
var row = trace[i];
|
||||
display.push((row[4] ? 'new ' : '') + row[3] + ' (' + row[0] + ':' + row[1] + ':' + row[2] + ')');
|
||||
}
|
||||
|
||||
return display;
|
||||
};
|
||||
|
||||
|
||||
exports.callStack = function (slice) {
|
||||
|
||||
// http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
|
||||
|
||||
var v8 = Error.prepareStackTrace;
|
||||
Error.prepareStackTrace = function (err, stack) {
|
||||
|
||||
return stack;
|
||||
};
|
||||
|
||||
var capture = {};
|
||||
Error.captureStackTrace(capture, arguments.callee); /*eslint no-caller:0 */
|
||||
var stack = capture.stack;
|
||||
|
||||
Error.prepareStackTrace = v8;
|
||||
|
||||
var trace = exports.formatStack(stack);
|
||||
|
||||
if (slice) {
|
||||
return trace.slice(slice);
|
||||
}
|
||||
|
||||
return trace;
|
||||
};
|
||||
|
||||
|
||||
exports.displayStack = function (slice) {
|
||||
|
||||
var trace = exports.callStack(slice === undefined ? 1 : slice + 1);
|
||||
|
||||
return exports.formatTrace(trace);
|
||||
};
|
||||
|
||||
|
||||
exports.abortThrow = false;
|
||||
|
||||
|
||||
exports.abort = function (message, hideStack) {
|
||||
|
||||
if (process.env.NODE_ENV === 'test' || exports.abortThrow === true) {
|
||||
throw new Error(message || 'Unknown error');
|
||||
}
|
||||
|
||||
var stack = '';
|
||||
if (!hideStack) {
|
||||
stack = exports.displayStack(1).join('\n\t');
|
||||
}
|
||||
console.log('ABORT: ' + message + '\n\t' + stack);
|
||||
process.exit(1);
|
||||
};
|
||||
|
||||
|
||||
exports.assert = function (condition /*, msg1, msg2, msg3 */) {
|
||||
|
||||
if (condition) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (arguments.length === 2 && arguments[1] instanceof Error) {
|
||||
throw arguments[1];
|
||||
}
|
||||
|
||||
var msgs = [];
|
||||
for (var i = 1, il = arguments.length; i < il; ++i) {
|
||||
if (arguments[i] !== '') {
|
||||
msgs.push(arguments[i]); // Avoids Array.slice arguments leak, allowing for V8 optimizations
|
||||
}
|
||||
}
|
||||
|
||||
msgs = msgs.map(function (msg) {
|
||||
|
||||
return typeof msg === 'string' ? msg : msg instanceof Error ? msg.message : exports.stringify(msg);
|
||||
});
|
||||
throw new Error(msgs.join(' ') || 'Unknown error');
|
||||
};
|
||||
|
||||
|
||||
exports.Timer = function () {
|
||||
|
||||
this.ts = 0;
|
||||
this.reset();
|
||||
};
|
||||
|
||||
|
||||
exports.Timer.prototype.reset = function () {
|
||||
|
||||
this.ts = Date.now();
|
||||
};
|
||||
|
||||
|
||||
exports.Timer.prototype.elapsed = function () {
|
||||
|
||||
return Date.now() - this.ts;
|
||||
};
|
||||
|
||||
|
||||
exports.Bench = function () {
|
||||
|
||||
this.ts = 0;
|
||||
this.reset();
|
||||
};
|
||||
|
||||
|
||||
exports.Bench.prototype.reset = function () {
|
||||
|
||||
this.ts = exports.Bench.now();
|
||||
};
|
||||
|
||||
|
||||
exports.Bench.prototype.elapsed = function () {
|
||||
|
||||
return exports.Bench.now() - this.ts;
|
||||
};
|
||||
|
||||
|
||||
exports.Bench.now = function () {
|
||||
|
||||
var ts = process.hrtime();
|
||||
return (ts[0] * 1e3) + (ts[1] / 1e6);
|
||||
};
|
||||
|
||||
|
||||
// Escape string for Regex construction
|
||||
|
||||
exports.escapeRegex = function (string) {
|
||||
|
||||
// Escape ^$.*+-?=!:|\/()[]{},
|
||||
return string.replace(/[\^\$\.\*\+\-\?\=\!\:\|\\\/\(\)\[\]\{\}\,]/g, '\\$&');
|
||||
};
|
||||
|
||||
|
||||
// Base64url (RFC 4648) encode
|
||||
|
||||
exports.base64urlEncode = function (value, encoding) {
|
||||
|
||||
var buf = (Buffer.isBuffer(value) ? value : new Buffer(value, encoding || 'binary'));
|
||||
return buf.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');
|
||||
};
|
||||
|
||||
|
||||
// Base64url (RFC 4648) decode
|
||||
|
||||
exports.base64urlDecode = function (value, encoding) {
|
||||
|
||||
if (value &&
|
||||
!/^[\w\-]*$/.test(value)) {
|
||||
|
||||
return new Error('Invalid character');
|
||||
}
|
||||
|
||||
try {
|
||||
var buf = new Buffer(value, 'base64');
|
||||
return (encoding === 'buffer' ? buf : buf.toString(encoding || 'binary'));
|
||||
}
|
||||
catch (err) {
|
||||
return err;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Escape attribute value for use in HTTP header
|
||||
|
||||
exports.escapeHeaderAttribute = function (attribute) {
|
||||
|
||||
// Allowed value characters: !#$%&'()*+,-./:;<=>?@[]^_`{|}~ and space, a-z, A-Z, 0-9, \, "
|
||||
|
||||
exports.assert(/^[ \w\!#\$%&'\(\)\*\+,\-\.\/\:;<\=>\?@\[\]\^`\{\|\}~\"\\]*$/.test(attribute), 'Bad attribute value (' + attribute + ')');
|
||||
|
||||
return attribute.replace(/\\/g, '\\\\').replace(/\"/g, '\\"'); // Escape quotes and slash
|
||||
};
|
||||
|
||||
|
||||
exports.escapeHtml = function (string) {
|
||||
|
||||
return Escape.escapeHtml(string);
|
||||
};
|
||||
|
||||
|
||||
exports.escapeJavaScript = function (string) {
|
||||
|
||||
return Escape.escapeJavaScript(string);
|
||||
};
|
||||
|
||||
|
||||
exports.nextTick = function (callback) {
|
||||
|
||||
return function () {
|
||||
|
||||
var args = arguments;
|
||||
process.nextTick(function () {
|
||||
|
||||
callback.apply(null, args);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
exports.once = function (method) {
|
||||
|
||||
if (method._hoekOnce) {
|
||||
return method;
|
||||
}
|
||||
|
||||
var once = false;
|
||||
var wrapped = function () {
|
||||
|
||||
if (!once) {
|
||||
once = true;
|
||||
method.apply(null, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
wrapped._hoekOnce = true;
|
||||
|
||||
return wrapped;
|
||||
};
|
||||
|
||||
|
||||
exports.isAbsolutePath = function (path, platform) {
|
||||
|
||||
if (!path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Path.isAbsolute) { // node >= 0.11
|
||||
return Path.isAbsolute(path);
|
||||
}
|
||||
|
||||
platform = platform || process.platform;
|
||||
|
||||
// Unix
|
||||
|
||||
if (platform !== 'win32') {
|
||||
return path[0] === '/';
|
||||
}
|
||||
|
||||
// Windows
|
||||
|
||||
return !!/^(?:[a-zA-Z]:[\\\/])|(?:[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/])/.test(path); // C:\ or \\something\something
|
||||
};
|
||||
|
||||
|
||||
exports.isInteger = function (value) {
|
||||
|
||||
return (typeof value === 'number' &&
|
||||
parseFloat(value) === parseInt(value, 10) &&
|
||||
!isNaN(value));
|
||||
};
|
||||
|
||||
|
||||
exports.ignore = function () { };
|
||||
|
||||
|
||||
exports.inherits = Util.inherits;
|
||||
|
||||
|
||||
exports.format = Util.format;
|
||||
|
||||
|
||||
exports.transform = function (source, transform, options) {
|
||||
|
||||
exports.assert(source === null || source === undefined || typeof source === 'object' || Array.isArray(source), 'Invalid source object: must be null, undefined, an object, or an array');
|
||||
|
||||
if (Array.isArray(source)) {
|
||||
var results = [];
|
||||
for (var i = 0, il = source.length; i < il; ++i) {
|
||||
results.push(exports.transform(source[i], transform, options));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
var result = {};
|
||||
var keys = Object.keys(transform);
|
||||
|
||||
for (var k = 0, kl = keys.length; k < kl; ++k) {
|
||||
var key = keys[k];
|
||||
var path = key.split('.');
|
||||
var sourcePath = transform[key];
|
||||
|
||||
exports.assert(typeof sourcePath === 'string', 'All mappings must be "." delineated strings');
|
||||
|
||||
var segment;
|
||||
var res = result;
|
||||
|
||||
while (path.length > 1) {
|
||||
segment = path.shift();
|
||||
if (!res[segment]) {
|
||||
res[segment] = {};
|
||||
}
|
||||
res = res[segment];
|
||||
}
|
||||
segment = path.shift();
|
||||
res[segment] = exports.reach(source, sourcePath, options);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
exports.uniqueFilename = function (path, extension) {
|
||||
|
||||
if (extension) {
|
||||
extension = extension[0] !== '.' ? '.' + extension : extension;
|
||||
}
|
||||
else {
|
||||
extension = '';
|
||||
}
|
||||
|
||||
path = Path.resolve(path);
|
||||
var name = [Date.now(), process.pid, Crypto.randomBytes(8).toString('hex')].join('-') + extension;
|
||||
return Path.join(path, name);
|
||||
};
|
||||
|
||||
|
||||
exports.stringify = function () {
|
||||
|
||||
try {
|
||||
return JSON.stringify.apply(null, arguments);
|
||||
}
|
||||
catch (err) {
|
||||
return '[Cannot display object: ' + err.message + ']';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
exports.shallow = function (source) {
|
||||
|
||||
var target = {};
|
||||
var keys = Object.keys(source);
|
||||
for (var i = 0, il = keys.length; i < il; ++i) {
|
||||
var key = keys[i];
|
||||
target[key] = source[key];
|
||||
}
|
||||
|
||||
return target;
|
||||
};
|
||||
57
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/package.json
generated
vendored
Normal file
57
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/package.json
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
{
|
||||
"_from": "hoek@2.x.x",
|
||||
"_id": "hoek@2.16.3",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
|
||||
"_location": "/coveralls/hoek",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "hoek@2.x.x",
|
||||
"name": "hoek",
|
||||
"escapedName": "hoek",
|
||||
"rawSpec": "2.x.x",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "2.x.x"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/coveralls/boom",
|
||||
"/coveralls/hawk",
|
||||
"/coveralls/sntp"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
|
||||
"_shasum": "20bb7403d3cea398e91dc4710a8ff1b8274a25ed",
|
||||
"_spec": "hoek@2.x.x",
|
||||
"_where": "/home/manfred/enviPath/ketcher2/ketcher/node_modules/coveralls/node_modules/hawk",
|
||||
"bugs": {
|
||||
"url": "https://github.com/hapijs/hoek/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {},
|
||||
"deprecated": false,
|
||||
"description": "General purpose node utilities",
|
||||
"devDependencies": {
|
||||
"code": "1.x.x",
|
||||
"lab": "5.x.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.40"
|
||||
},
|
||||
"homepage": "https://github.com/hapijs/hoek#readme",
|
||||
"keywords": [
|
||||
"utilities"
|
||||
],
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "lib/index.js",
|
||||
"name": "hoek",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/hapijs/hoek.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "lab -a code -t 100 -L",
|
||||
"test-cov-html": "lab -a code -t 100 -L -r html -o coverage.html"
|
||||
},
|
||||
"version": "2.16.3"
|
||||
}
|
||||
88
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/test/escaper.js
generated
vendored
Normal file
88
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/test/escaper.js
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
// Load modules
|
||||
|
||||
var Code = require('code');
|
||||
var Hoek = require('../lib');
|
||||
var Lab = require('lab');
|
||||
|
||||
|
||||
// Declare internals
|
||||
|
||||
var internals = {};
|
||||
|
||||
|
||||
// Test shortcuts
|
||||
|
||||
var lab = exports.lab = Lab.script();
|
||||
var describe = lab.experiment;
|
||||
var it = lab.test;
|
||||
var expect = Code.expect;
|
||||
|
||||
|
||||
describe('escapeJavaScript()', function () {
|
||||
|
||||
it('encodes / characters', function (done) {
|
||||
|
||||
var encoded = Hoek.escapeJavaScript('<script>alert(1)</script>');
|
||||
expect(encoded).to.equal('\\x3cscript\\x3ealert\\x281\\x29\\x3c\\x2fscript\\x3e');
|
||||
done();
|
||||
});
|
||||
|
||||
it('encodes \' characters', function (done) {
|
||||
|
||||
var encoded = Hoek.escapeJavaScript('something(\'param\')');
|
||||
expect(encoded).to.equal('something\\x28\\x27param\\x27\\x29');
|
||||
done();
|
||||
});
|
||||
|
||||
it('encodes large unicode characters with the correct padding', function (done) {
|
||||
|
||||
var encoded = Hoek.escapeJavaScript(String.fromCharCode(500) + String.fromCharCode(1000));
|
||||
expect(encoded).to.equal('\\u0500\\u1000');
|
||||
done();
|
||||
});
|
||||
|
||||
it('doesn\'t throw an exception when passed null', function (done) {
|
||||
|
||||
var encoded = Hoek.escapeJavaScript(null);
|
||||
expect(encoded).to.equal('');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('escapeHtml()', function () {
|
||||
|
||||
it('encodes / characters', function (done) {
|
||||
|
||||
var encoded = Hoek.escapeHtml('<script>alert(1)</script>');
|
||||
expect(encoded).to.equal('<script>alert(1)</script>');
|
||||
done();
|
||||
});
|
||||
|
||||
it('encodes < and > as named characters', function (done) {
|
||||
|
||||
var encoded = Hoek.escapeHtml('<script><>');
|
||||
expect(encoded).to.equal('<script><>');
|
||||
done();
|
||||
});
|
||||
|
||||
it('encodes large unicode characters', function (done) {
|
||||
|
||||
var encoded = Hoek.escapeHtml(String.fromCharCode(500) + String.fromCharCode(1000));
|
||||
expect(encoded).to.equal('ǴϨ');
|
||||
done();
|
||||
});
|
||||
|
||||
it('doesn\'t throw an exception when passed null', function (done) {
|
||||
|
||||
var encoded = Hoek.escapeHtml(null);
|
||||
expect(encoded).to.equal('');
|
||||
done();
|
||||
});
|
||||
|
||||
it('encodes {} characters', function (done) {
|
||||
|
||||
var encoded = Hoek.escapeHtml('{}');
|
||||
expect(encoded).to.equal('{}');
|
||||
done();
|
||||
});
|
||||
});
|
||||
2513
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/test/index.js
generated
vendored
Normal file
2513
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/test/index.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
0
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/test/modules/ignore.txt
generated
vendored
Normal file
0
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/test/modules/ignore.txt
generated
vendored
Normal file
1
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/test/modules/test1.js
generated
vendored
Normal file
1
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/test/modules/test1.js
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
exports.x = 1;
|
||||
1
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/test/modules/test2.js
generated
vendored
Normal file
1
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/test/modules/test2.js
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
exports.y = 2;
|
||||
1
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/test/modules/test3.js
generated
vendored
Normal file
1
static/js/ketcher2/node_modules/coveralls/node_modules/hoek/test/modules/test3.js
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
exports.z = 3;
|
||||
46
static/js/ketcher2/node_modules/coveralls/node_modules/http-signature/CHANGES.md
generated
vendored
Normal file
46
static/js/ketcher2/node_modules/coveralls/node_modules/http-signature/CHANGES.md
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
# node-http-signature changelog
|
||||
|
||||
## 1.1.1
|
||||
|
||||
- Version of dependency `assert-plus` updated: old version was missing
|
||||
some license information
|
||||
- Corrected examples in `http_signing.md`, added auto-tests to
|
||||
automatically validate these examples
|
||||
|
||||
## 1.1.0
|
||||
|
||||
- Bump version of `sshpk` dependency, remove peerDependency on it since
|
||||
it now supports exchanging objects between multiple versions of itself
|
||||
where possible
|
||||
|
||||
## 1.0.2
|
||||
|
||||
- Bump min version of `jsprim` dependency, to include fixes for using
|
||||
http-signature with `browserify`
|
||||
|
||||
## 1.0.1
|
||||
|
||||
- Bump minimum version of `sshpk` dependency, to include fixes for
|
||||
whitespace tolerance in key parsing.
|
||||
|
||||
## 1.0.0
|
||||
|
||||
- First semver release.
|
||||
- #36: Ensure verifySignature does not leak useful timing information
|
||||
- #42: Bring the library up to the latest version of the spec (including the
|
||||
request-target changes)
|
||||
- Support for ECDSA keys and signatures.
|
||||
- Now uses `sshpk` for key parsing, validation and conversion.
|
||||
- Fixes for #21, #47, #39 and compatibility with node 0.8
|
||||
|
||||
## 0.11.0
|
||||
|
||||
- Split up HMAC and Signature verification to avoid vulnerabilities where a
|
||||
key intended for use with one can be validated against the other method
|
||||
instead.
|
||||
|
||||
## 0.10.2
|
||||
|
||||
- Updated versions of most dependencies.
|
||||
- Utility functions exported for PEM => SSH-RSA conversion.
|
||||
- Improvements to tests and examples.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user