Skip to content

Commit e9d75dc

Browse files
committed
Fixed failing tests
1 parent 063c460 commit e9d75dc

18 files changed

+36996
-32957
lines changed

lib/browser/neo4j-web.js

+17,169-16,416
Large diffs are not rendered by default.

lib/browser/neo4j-web.min.js

+14-14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/browser/neo4j-web.test.js

+19,634-16,490
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/v1/driver.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,11 @@ var USER_AGENT = "neo4j-javascript/" + _version.VERSION;
230230
* options are as follows:
231231
*
232232
* {
233-
* // Enable TLS encryption. This is on by default in modern NodeJS installs,
233+
* // Encryption level: one of ENCRYPTION_ON, ENCRYPTION_OFF or ENCRYPTION_NON_LOCAL.
234+
* // ENCRYPTION_NON_LOCAL is on by default in modern NodeJS installs,
234235
* // but off by default in the Web Bundle and old (<=1.0.0) NodeJS installs
235236
* // due to technical limitations on those platforms.
236-
* encrypted: true|false,
237+
* encrypted: ENCRYPTION_ON|ENCRYPTION_OFF|ENCRYPTION_NON_LOCAL
237238
*
238239
* // Trust strategy to use if encryption is enabled. There is no mode to disable
239240
* // trust other than disabling encryption altogether. The reason for

lib/v1/internal/ch-dummy.js

+5
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ var DummyChannel = (function () {
4444
}
4545

4646
_createClass(DummyChannel, [{
47+
key: "isEncrypted",
48+
value: function isEncrypted() {
49+
return false;
50+
}
51+
}, {
4752
key: "write",
4853
value: function write(buf) {
4954
this.written.push(buf);

lib/v1/internal/ch-node.js

+20-7
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ var _os = require('os');
4949

5050
var _buf = require('./buf');
5151

52+
var _util = require('./util');
53+
5254
var _error = require('./../error');
5355

5456
var _CONNECTION_IDGEN = 0;
@@ -83,13 +85,17 @@ function loadFingerprint(serverId, knownHostsPath, cb) {
8385
}
8486

8587
function storeFingerprint(serverId, knownHostsPath, fingerprint) {
86-
_fs2['default'].appendFile(knownHostsPath, serverId + " " + fingerprint + _os.EOL, "utf8");
88+
_fs2['default'].appendFile(knownHostsPath, serverId + " " + fingerprint + _os.EOL, "utf8", function (err) {
89+
if (err) {
90+
console.log(err);
91+
}
92+
});
8793
}
8894

8995
var TrustStrategy = {
9096
TRUST_SIGNED_CERTIFICATES: function TRUST_SIGNED_CERTIFICATES(opts, onSuccess, onFailure) {
9197
if (!opts.trustedCertificates || opts.trustedCertificates.length == 0) {
92-
onFailure((0, _error.newError)("You are using TRUST_SIGNED_CERTIFICATES as the method " + "to verify trust for encrypted connections, but have not configured any " + "trustedCertificates. You must specify the path to at least one trusted " + "X.509 certificate for this to work. Two other alternatives is to use " + "TRUST_ON_FIRST_USE or to disable encryption by setting encrypted=false " + "in your driver configuration."));
98+
onFailure((0, _error.newError)("You are using TRUST_SIGNED_CERTIFICATES as the method " + "to verify trust for encrypted connections, but have not configured any " + "trustedCertificates. You must specify the path to at least one trusted " + "X.509 certificate for this to work. Two other alternatives is to use " + "TRUST_ON_FIRST_USE or to disable encryption by setting encrypted=\"" + _util.ENCRYPTION_OFF + "\"" + "in your driver configuration."));
9399
return;
94100
}
95101

@@ -102,7 +108,7 @@ var TrustStrategy = {
102108

103109
var socket = _tls2['default'].connect(opts.port, opts.host, tlsOpts, function () {
104110
if (!socket.authorized) {
105-
onFailure((0, _error.newError)("Server certificate is not trusted. If you trust the database you are connecting to, add" + " the signing certificate, or the server certificate, to the list of certificates trusted by this driver" + " using `neo4j.v1.driver(.., { trustedCertificates:['path/to/certificate.crt']}). This " + " is a security measure to protect against man-in-the-middle attacks. If you are just trying " + " Neo4j out and are not concerned about encryption, simply disable it using `encrypted=false` in the driver" + " options."));
111+
onFailure((0, _error.newError)("Server certificate is not trusted. If you trust the database you are connecting to, add" + " the signing certificate, or the server certificate, to the list of certificates trusted by this driver" + " using `neo4j.v1.driver(.., { trustedCertificates:['path/to/certificate.crt']}). This " + " is a security measure to protect against man-in-the-middle attacks. If you are just trying " + " Neo4j out and are not concerned about encryption, simply disable it using `encrypted=\"" + _util.ENCRYPTION_OFF + "\"` in the driver" + " options."));
106112
} else {
107113
onSuccess();
108114
}
@@ -124,7 +130,7 @@ var TrustStrategy = {
124130
// the raw cert cannot be accessed (or, at least I couldn't find a way to)
125131
// therefore, we can't generate a SHA512 fingerprint, meaning we can't
126132
// do TOFU, and the safe approach is to fail.
127-
onFailure((0, _error.newError)("You are using a version of NodeJS that does not " + "support trust-on-first use encryption. You can either upgrade NodeJS to " + "a newer version, use `trust:TRUST_SIGNED_CERTIFICATES` in your driver " + "config instead, or disable encryption using `encrypted:false`."));
133+
onFailure((0, _error.newError)("You are using a version of NodeJS that does not " + "support trust-on-first use encryption. You can either upgrade NodeJS to " + "a newer version, use `trust:TRUST_SIGNED_CERTIFICATES` in your driver " + "config instead, or disable encryption using `encrypted:\"" + _util.ENCRYPTION_OFF + "\"`."));
128134
return;
129135
}
130136

@@ -139,7 +145,7 @@ var TrustStrategy = {
139145
storeFingerprint(serverId, knownHostsPath, serverFingerprint);
140146
onSuccess();
141147
} else {
142-
onFailure((0, _error.newError)("Database encryption certificate has changed, and no longer " + "matches the certificate stored for " + serverId + " in `" + knownHostsPath + "`. As a security precaution, this driver will not automatically trust the new " + "certificate, because doing so would allow an attacker to pretend to be the Neo4j " + "instance we want to connect to. The certificate provided by the server looks like: " + serverCert + ". If you trust that this certificate is valid, simply remove the line " + "starting with " + serverId + " in `" + knownHostsPath + "`, and the driver will " + "update the file with the new certificate. You can configure which file the driver " + "should use to store this information by setting `knownHosts` to another path in " + "your driver configuration - and you can disable encryption there as well using " + "`encrypted:false`."));
148+
onFailure((0, _error.newError)("Database encryption certificate has changed, and no longer " + "matches the certificate stored for " + serverId + " in `" + knownHostsPath + "`. As a security precaution, this driver will not automatically trust the new " + "certificate, because doing so would allow an attacker to pretend to be the Neo4j " + "instance we want to connect to. The certificate provided by the server looks like: " + serverCert + ". If you trust that this certificate is valid, simply remove the line " + "starting with " + serverId + " in `" + knownHostsPath + "`, and the driver will " + "update the file with the new certificate. You can configure which file the driver " + "should use to store this information by setting `knownHosts` to another path in " + "your driver configuration - and you can disable encryption there as well using " + "`encrypted:\"" + _util.ENCRYPTION_OFF + "\"`."));
143149
}
144150
});
145151
});
@@ -153,14 +159,15 @@ function connect(opts, onSuccess) {
153159
return null;
154160
} : arguments[2];
155161

156-
if (opts.encrypted === false) {
162+
//still allow boolean for backwards compatibility
163+
if (opts.encrypted === false || opts.encrypted === _util.ENCRYPTION_OFF || opts.encrypted === _util.ENCRYPTION_NON_LOCAL && (0, _util.isLocalHost)(opts.host)) {
157164
var conn = _net2['default'].connect(opts.port, opts.host, onSuccess);
158165
conn.on('error', onFailure);
159166
return conn;
160167
} else if (TrustStrategy[opts.trust]) {
161168
return TrustStrategy[opts.trust](opts, onSuccess, onFailure);
162169
} else {
163-
onFailure((0, _error.newError)("Unknown trust strategy: " + opts.trust + ". Please use either " + "trust:'TRUST_SIGNED_CERTIFICATES' or trust:'TRUST_ON_FIRST_USE' in your driver " + "configuration. Alternatively, you can disable encryption by setting " + "`encrypted:false`. There is no mechanism to use encryption without trust verification, " + "because this incurs the overhead of encryption without improving security. If " + "the driver does not verify that the peer it is connected to is really Neo4j, it " + "is very easy for an attacker to bypass the encryption by pretending to be Neo4j."));
170+
onFailure((0, _error.newError)("Unknown trust strategy: " + opts.trust + ". Please use either " + "trust:'TRUST_SIGNED_CERTIFICATES' or trust:'TRUST_ON_FIRST_USE' in your driver " + "configuration. Alternatively, you can disable encryption by setting " + "`encrypted:\"" + _util.ENCRYPTION_OFF + "\"`. There is no mechanism to use encryption without trust verification, " + "because this incurs the overhead of encryption without improving security. If " + "the driver does not verify that the peer it is connected to is really Neo4j, it " + "is very easy for an attacker to bypass the encryption by pretending to be Neo4j."));
164171
}
165172
}
166173

@@ -191,6 +198,7 @@ var NodeChannel = (function () {
191198
this._error = null;
192199
this._handleConnectionError = this._handleConnectionError.bind(this);
193200

201+
this._encrypted = opts.encrypted;
194202
this._conn = connect(opts, function () {
195203
if (!self._open) {
196204
return;
@@ -221,6 +229,11 @@ var NodeChannel = (function () {
221229
this.onerror(err);
222230
}
223231
}
232+
}, {
233+
key: 'isEncrypted',
234+
value: function isEncrypted() {
235+
return this._encrypted;
236+
}
224237

225238
/**
226239
* Write the passed in buffer to connection

lib/v1/internal/ch-websocket.js

+12-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ var _buf = require("./buf");
3333

3434
var _error = require('./../error');
3535

36+
var _util = require('./util');
37+
3638
/**
3739
* Create a new WebSocketChannel to be used in web browsers.
3840
* @access private
@@ -55,12 +57,15 @@ var WebSocketChannel = (function () {
5557
this._error = null;
5658
this._handleConnectionError = this._handleConnectionError.bind(this);
5759

60+
this._encrypted = opts.encrypted;
61+
5862
var scheme = "ws";
59-
if (opts.encrypted) {
63+
//Allow boolean for backwards compatibility
64+
if (opts.encrypted === true || opts.encrypted === _util.ENCRYPTION_ON || opts.encrypted === _util.ENCRYPTION_NON_LOCAL && !(0, _util.isLocalHost)(opts.host)) {
6065
if (!opts.trust || opts.trust === "TRUST_SIGNED_CERTIFICATES") {
6166
scheme = "wss";
6267
} else {
63-
this._error = (0, _error.newError)("The browser version of this driver only supports one trust " + "strategy, 'TRUST_SIGNED_CERTIFICATES'. " + opts.trust + " is not supported. Please " + "either use TRUST_SIGNED_CERTIFICATES or disable encryption by setting " + "`encrypted:false` in the driver configuration.");
68+
this._error = (0, _error.newError)("The browser version of this driver only supports one trust " + "strategy, 'TRUST_SIGNED_CERTIFICATES'. " + opts.trust + " is not supported. Please " + "either use TRUST_SIGNED_CERTIFICATES or disable encryption by setting " + "`encrypted:\"" + _util.ENCRYPTION_OFF + "\"` in the driver configuration.");
6469
return;
6570
}
6671
}
@@ -106,6 +111,11 @@ var WebSocketChannel = (function () {
106111
}
107112
}
108113
}
114+
}, {
115+
key: "isEncrypted",
116+
value: function isEncrypted() {
117+
return this._encrypted;
118+
}
109119

110120
/**
111121
* Write the passed in buffer to connection

lib/v1/internal/connector.js

+10-3
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ var _integer = require('../integer');
5959

6060
var _error = require('./../error');
6161

62+
var _util = require('./util');
63+
6264
var Channel = undefined;
6365
if (_chWebsocket2["default"].available) {
6466
Channel = _chWebsocket2["default"].channel;
@@ -467,6 +469,11 @@ var Connection = (function () {
467469
value: function isOpen() {
468470
return !this._isBroken && this._ch._open;
469471
}
472+
}, {
473+
key: "isEncrypted",
474+
value: function isEncrypted() {
475+
return this._ch.isEncrypted();
476+
}
470477

471478
/**
472479
* Call close on the channel.
@@ -489,9 +496,9 @@ function connect(url) {
489496
return new Connection(new Ch({
490497
host: host(url),
491498
port: port(url) || 7687,
492-
// Default to using encryption if trust-on-first-use is available
493-
encrypted: config.encrypted == null ? (0, _features2["default"])("trust_on_first_use") : config.encrypted,
494-
// Default to using trust-on-first-use if it is available
499+
// Default to using ENCRYPTION_NON_LOCAL if trust-on-first-use is available
500+
encrypted: (0, _util.shouldEncrypt)(config.encrypted, (0, _features2["default"])("trust_on_first_use") ? _util.ENCRYPTION_NON_LOCAL : _util.ENCRYPTION_OFF, host(url)),
501+
// Default to using TRUST_ON_FIRST_USE if it is available
495502
trust: config.trust || ((0, _features2["default"])("trust_on_first_use") ? "TRUST_ON_FIRST_USE" : "TRUST_SIGNED_CERTIFICATES"),
496503
trustedCertificates: config.trustedCertificates || [],
497504
knownHosts: config.knownHosts

lib/v1/internal/util.js

+30-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
/**
32
* Copyright (c) 2002-2016 "Neo Technology,"
43
* Network Engine for Objects in Lund AB [http://neotechnology.com]
@@ -32,7 +31,37 @@ function isLocalHost(host) {
3231
return LOCALHOST_MATCHER.test(host);
3332
}
3433

34+
/* Coerce an encryption setting to a definitive boolean value,
35+
* given a valid default and a target host. If encryption is
36+
* explicitly set on or off, then the mapping is a simple
37+
* conversion to true or false respectively. If set to
38+
* ENCRYPTION_NON_LOCAL then respond according to whether or
39+
* not the host is localhost/127.x.x.x. In all other cases
40+
* (including undefined) then fall back to the default and
41+
* re-evaluate.
42+
*/
43+
function shouldEncrypt(_x, _x2, _x3) {
44+
var _again = true;
45+
46+
_function: while (_again) {
47+
var encryption = _x,
48+
encryptionDefault = _x2,
49+
host = _x3;
50+
_again = false;
51+
52+
if (encryption === ENCRYPTION_ON || encryption === true) return true;
53+
if (encryption === ENCRYPTION_OFF || encryption === false) return false;
54+
if (encryption === ENCRYPTION_NON_LOCAL) return !isLocalHost(host);
55+
_x = encryptionDefault;
56+
_x2 = ENCRYPTION_OFF;
57+
_x3 = host;
58+
_again = true;
59+
continue _function;
60+
}
61+
}
62+
3563
exports.isLocalHost = isLocalHost;
64+
exports.shouldEncrypt = shouldEncrypt;
3665
exports.ENCRYPTION_ON = ENCRYPTION_ON;
3766
exports.ENCRYPTION_OFF = ENCRYPTION_OFF;
3867
exports.ENCRYPTION_NON_LOCAL = ENCRYPTION_NON_LOCAL;

lib/v1/record.js

+34
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,22 @@ var Record = (function () {
9797
}
9898
}
9999

100+
/**
101+
* Generates an object out of the current Record
102+
*
103+
* @returns {Object}
104+
*/
105+
}, {
106+
key: "toObject",
107+
value: function toObject() {
108+
var object = {};
109+
this.forEach(function (value, key) {
110+
object[key] = value;
111+
});
112+
113+
return object;
114+
}
115+
100116
/**
101117
* Get a value from this record, either by index or by field key.
102118
*
@@ -122,6 +138,24 @@ var Record = (function () {
122138

123139
return this._fields[index];
124140
}
141+
142+
/**
143+
* Check if a value from this record, either by index or by field key, exists.
144+
*
145+
* @param {string|Number} key Field key, or the index of the field.
146+
* @returns {boolean}
147+
*/
148+
}, {
149+
key: "has",
150+
value: function has(key) {
151+
// if key is a number, we check if it is in the _fields array
152+
if (typeof key === "number") {
153+
return key >= 0 && key < this._fields.length;
154+
}
155+
156+
// if it's not a number, we check _fieldLookup dictionary directly
157+
return this._fieldLookup[key] !== undefined;
158+
}
125159
}]);
126160

127161
return Record;

lib/v1/session.js

+14-9
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,21 @@ var Session = (function () {
6464
this._hasTx = false;
6565
}
6666

67-
/**
68-
* Run Cypher statement
69-
* Could be called with a statement object i.e.: {statement: "MATCH ...", parameters: {param: 1}}
70-
* or with the statement and parameters as separate arguments.
71-
* @param {mixed} statement - Cypher statement to execute
72-
* @param {Object} parameters - Map with parameters to use in statement
73-
* @return {Result} - New Result
74-
*/
75-
7667
_createClass(Session, [{
68+
key: 'isEncrypted',
69+
value: function isEncrypted() {
70+
return this._conn.isEncrypted();
71+
}
72+
73+
/**
74+
* Run Cypher statement
75+
* Could be called with a statement object i.e.: {statement: "MATCH ...", parameters: {param: 1}}
76+
* or with the statement and parameters as separate arguments.
77+
* @param {mixed} statement - Cypher statement to execute
78+
* @param {Object} parameters - Map with parameters to use in statement
79+
* @return {Result} - New Result
80+
*/
81+
}, {
7782
key: 'run',
7883
value: function run(statement) {
7984
var parameters = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];

src/v1/internal/ch-dummy.js

+3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ class DummyChannel {
2929
constructor(opts) {
3030
this.written = [];
3131
}
32+
isEncrypted() {
33+
return false;
34+
}
3235
write( buf ) {
3336
this.written.push(buf);
3437
observer.updateInstance(this);

src/v1/internal/ch-node.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import fs from 'fs';
2323
import path from 'path';
2424
import {EOL} from 'os';
2525
import {NodeBuffer} from './buf';
26-
import {isLocalHost, ENCRYPTION_NON_LOCAL, ENCRYPTION_ON, ENCRYPTION_OFF} from './util';
26+
import {isLocalHost, ENCRYPTION_NON_LOCAL, ENCRYPTION_OFF} from './util';
2727
import {newError} from './../error';
2828

2929
let _CONNECTION_IDGEN = 0;
@@ -194,6 +194,7 @@ class NodeChannel {
194194
this._error = null;
195195
this._handleConnectionError = this._handleConnectionError.bind(this);
196196

197+
this._encrypted = opts.encrypted;
197198
this._conn = connect(opts, () => {
198199
if(!self._open) {
199200
return;
@@ -223,6 +224,10 @@ class NodeChannel {
223224
}
224225
}
225226

227+
isEncrypted() {
228+
return this._encrypted;
229+
}
230+
226231
/**
227232
* Write the passed in buffer to connection
228233
* @param {NodeBuffer} buffer - Buffer to write

src/v1/internal/ch-websocket.js

+6
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class WebSocketChannel {
4141
this._error = null;
4242
this._handleConnectionError = this._handleConnectionError.bind(this);
4343

44+
this._encrypted = opts.encrypted;
45+
4446
let scheme = "ws";
4547
//Allow boolean for backwards compatibility
4648
if( opts.encrypted === true || opts.encrypted === ENCRYPTION_ON ||
@@ -101,6 +103,10 @@ class WebSocketChannel {
101103
}
102104
}
103105
}
106+
107+
isEncrypted() {
108+
return this._encrypted;
109+
}
104110

105111
/**
106112
* Write the passed in buffer to connection

0 commit comments

Comments
 (0)