pg 8.0.0 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +42 -31
- package/lib/connection-fast.js +50 -200
- package/lib/connection-parameters.js +14 -7
- package/lib/connection.js +32 -51
- package/lib/defaults.js +1 -1
- package/lib/index.js +3 -3
- package/lib/native/client.js +8 -8
- package/lib/native/query.js +27 -22
- package/lib/query.js +44 -24
- package/lib/sasl.js +34 -30
- package/lib/type-overrides.js +7 -4
- package/lib/utils.js +43 -27
- package/package.json +6 -13
package/lib/connection.js
CHANGED
|
@@ -35,7 +35,7 @@ var Connection = function (config) {
|
|
|
35
35
|
this._emitMessage = false
|
|
36
36
|
this._reader = new Reader({
|
|
37
37
|
headerSize: 1,
|
|
38
|
-
lengthPadding: -4
|
|
38
|
+
lengthPadding: -4,
|
|
39
39
|
})
|
|
40
40
|
var self = this
|
|
41
41
|
this.on('newListener', function (eventName) {
|
|
@@ -50,13 +50,10 @@ util.inherits(Connection, EventEmitter)
|
|
|
50
50
|
Connection.prototype.connect = function (port, host) {
|
|
51
51
|
var self = this
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
} else if (this.stream.readyState === 'open') {
|
|
56
|
-
this.emit('connect')
|
|
57
|
-
}
|
|
53
|
+
this._connecting = true
|
|
54
|
+
this.stream.connect(port, host)
|
|
58
55
|
|
|
59
|
-
this.stream.
|
|
56
|
+
this.stream.once('connect', function () {
|
|
60
57
|
if (self._keepAlive) {
|
|
61
58
|
self.stream.setKeepAlive(true, self._keepAliveInitialDelayMillis)
|
|
62
59
|
}
|
|
@@ -88,14 +85,18 @@ Connection.prototype.connect = function (port, host) {
|
|
|
88
85
|
case 'N': // Server does not support SSL connections
|
|
89
86
|
self.stream.end()
|
|
90
87
|
return self.emit('error', new Error('The server does not support SSL connections'))
|
|
91
|
-
default:
|
|
88
|
+
default:
|
|
89
|
+
// Any other response byte, including 'E' (ErrorResponse) indicating a server error
|
|
92
90
|
self.stream.end()
|
|
93
91
|
return self.emit('error', new Error('There was an error establishing an SSL connection'))
|
|
94
92
|
}
|
|
95
93
|
var tls = require('tls')
|
|
96
|
-
const options = Object.assign(
|
|
97
|
-
|
|
98
|
-
|
|
94
|
+
const options = Object.assign(
|
|
95
|
+
{
|
|
96
|
+
socket: self.stream,
|
|
97
|
+
},
|
|
98
|
+
self.ssl
|
|
99
|
+
)
|
|
99
100
|
if (net.isIP(host) === 0) {
|
|
100
101
|
options.servername = host
|
|
101
102
|
}
|
|
@@ -127,23 +128,16 @@ Connection.prototype.attachListeners = function (stream) {
|
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
Connection.prototype.requestSsl = function () {
|
|
130
|
-
var bodyBuffer = this.writer
|
|
131
|
-
.addInt16(0x04D2)
|
|
132
|
-
.addInt16(0x162F).flush()
|
|
131
|
+
var bodyBuffer = this.writer.addInt16(0x04d2).addInt16(0x162f).flush()
|
|
133
132
|
|
|
134
133
|
var length = bodyBuffer.length + 4
|
|
135
134
|
|
|
136
|
-
var buffer = new Writer()
|
|
137
|
-
.addInt32(length)
|
|
138
|
-
.add(bodyBuffer)
|
|
139
|
-
.join()
|
|
135
|
+
var buffer = new Writer().addInt32(length).add(bodyBuffer).join()
|
|
140
136
|
this.stream.write(buffer)
|
|
141
137
|
}
|
|
142
138
|
|
|
143
139
|
Connection.prototype.startup = function (config) {
|
|
144
|
-
var writer = this.writer
|
|
145
|
-
.addInt16(3)
|
|
146
|
-
.addInt16(0)
|
|
140
|
+
var writer = this.writer.addInt16(3).addInt16(0)
|
|
147
141
|
|
|
148
142
|
Object.keys(config).forEach(function (key) {
|
|
149
143
|
var val = config[key]
|
|
@@ -157,27 +151,16 @@ Connection.prototype.startup = function (config) {
|
|
|
157
151
|
|
|
158
152
|
var length = bodyBuffer.length + 4
|
|
159
153
|
|
|
160
|
-
var buffer = new Writer()
|
|
161
|
-
.addInt32(length)
|
|
162
|
-
.add(bodyBuffer)
|
|
163
|
-
.join()
|
|
154
|
+
var buffer = new Writer().addInt32(length).add(bodyBuffer).join()
|
|
164
155
|
this.stream.write(buffer)
|
|
165
156
|
}
|
|
166
157
|
|
|
167
158
|
Connection.prototype.cancel = function (processID, secretKey) {
|
|
168
|
-
var bodyBuffer = this.writer
|
|
169
|
-
.addInt16(1234)
|
|
170
|
-
.addInt16(5678)
|
|
171
|
-
.addInt32(processID)
|
|
172
|
-
.addInt32(secretKey)
|
|
173
|
-
.flush()
|
|
159
|
+
var bodyBuffer = this.writer.addInt16(1234).addInt16(5678).addInt32(processID).addInt32(secretKey).flush()
|
|
174
160
|
|
|
175
161
|
var length = bodyBuffer.length + 4
|
|
176
162
|
|
|
177
|
-
var buffer = new Writer()
|
|
178
|
-
.addInt32(length)
|
|
179
|
-
.add(bodyBuffer)
|
|
180
|
-
.join()
|
|
163
|
+
var buffer = new Writer().addInt32(length).add(bodyBuffer).join()
|
|
181
164
|
this.stream.write(buffer)
|
|
182
165
|
}
|
|
183
166
|
|
|
@@ -188,18 +171,14 @@ Connection.prototype.password = function (password) {
|
|
|
188
171
|
|
|
189
172
|
Connection.prototype.sendSASLInitialResponseMessage = function (mechanism, initialResponse) {
|
|
190
173
|
// 0x70 = 'p'
|
|
191
|
-
this.writer
|
|
192
|
-
.addCString(mechanism)
|
|
193
|
-
.addInt32(Buffer.byteLength(initialResponse))
|
|
194
|
-
.addString(initialResponse)
|
|
174
|
+
this.writer.addCString(mechanism).addInt32(Buffer.byteLength(initialResponse)).addString(initialResponse)
|
|
195
175
|
|
|
196
176
|
this._send(0x70)
|
|
197
177
|
}
|
|
198
178
|
|
|
199
179
|
Connection.prototype.sendSCRAMClientFinalMessage = function (additionalData) {
|
|
200
180
|
// 0x70 = 'p'
|
|
201
|
-
this.writer
|
|
202
|
-
.addString(additionalData)
|
|
181
|
+
this.writer.addString(additionalData)
|
|
203
182
|
|
|
204
183
|
this._send(0x70)
|
|
205
184
|
}
|
|
@@ -263,13 +242,17 @@ Connection.prototype.bind = function (config, more) {
|
|
|
263
242
|
var values = config.values || []
|
|
264
243
|
var len = values.length
|
|
265
244
|
var useBinary = false
|
|
266
|
-
for (var j = 0; j < len; j++) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
if (!useBinary) {
|
|
245
|
+
for (var j = 0; j < len; j++) {
|
|
246
|
+
useBinary |= values[j] instanceof Buffer
|
|
247
|
+
}
|
|
248
|
+
var buffer = this.writer.addCString(config.portal).addCString(config.statement)
|
|
249
|
+
if (!useBinary) {
|
|
250
|
+
buffer.addInt16(0)
|
|
251
|
+
} else {
|
|
271
252
|
buffer.addInt16(len)
|
|
272
|
-
for (j = 0; j < len; j++) {
|
|
253
|
+
for (j = 0; j < len; j++) {
|
|
254
|
+
buffer.addInt16(values[j] instanceof Buffer)
|
|
255
|
+
}
|
|
273
256
|
}
|
|
274
257
|
buffer.addInt16(len)
|
|
275
258
|
for (var i = 0; i < len; i++) {
|
|
@@ -301,9 +284,7 @@ Connection.prototype.execute = function (config, more) {
|
|
|
301
284
|
config = config || {}
|
|
302
285
|
config.portal = config.portal || ''
|
|
303
286
|
config.rows = config.rows || ''
|
|
304
|
-
this.writer
|
|
305
|
-
.addCString(config.portal)
|
|
306
|
-
.addInt32(config.rows)
|
|
287
|
+
this.writer.addCString(config.portal).addInt32(config.rows)
|
|
307
288
|
|
|
308
289
|
// 0x45 = 'E'
|
|
309
290
|
this._send(0x45, more)
|
|
@@ -332,7 +313,7 @@ Connection.prototype.end = function () {
|
|
|
332
313
|
// 0x58 = 'X'
|
|
333
314
|
this.writer.add(emptyBuffer)
|
|
334
315
|
this._ending = true
|
|
335
|
-
if (!this.stream.writable) {
|
|
316
|
+
if (!this._connecting || !this.stream.writable) {
|
|
336
317
|
this.stream.end()
|
|
337
318
|
return
|
|
338
319
|
}
|
package/lib/defaults.js
CHANGED
package/lib/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var Pool = require('pg-pool')
|
|
|
14
14
|
|
|
15
15
|
const poolFactory = (Client) => {
|
|
16
16
|
return class BoundPool extends Pool {
|
|
17
|
-
constructor
|
|
17
|
+
constructor(options) {
|
|
18
18
|
super(options, Client)
|
|
19
19
|
}
|
|
20
20
|
}
|
|
@@ -54,10 +54,10 @@ if (typeof process.env.NODE_PG_FORCE_NATIVE !== 'undefined') {
|
|
|
54
54
|
|
|
55
55
|
// overwrite module.exports.native so that getter is never called again
|
|
56
56
|
Object.defineProperty(module.exports, 'native', {
|
|
57
|
-
value: native
|
|
57
|
+
value: native,
|
|
58
58
|
})
|
|
59
59
|
|
|
60
60
|
return native
|
|
61
|
-
}
|
|
61
|
+
},
|
|
62
62
|
})
|
|
63
63
|
}
|
package/lib/native/client.js
CHANGED
|
@@ -22,7 +22,7 @@ assert(semver.gte(Native.version, pkg.minNativeVersion), msg)
|
|
|
22
22
|
|
|
23
23
|
var NativeQuery = require('./query')
|
|
24
24
|
|
|
25
|
-
var Client = module.exports = function (config) {
|
|
25
|
+
var Client = (module.exports = function (config) {
|
|
26
26
|
EventEmitter.call(this)
|
|
27
27
|
config = config || {}
|
|
28
28
|
|
|
@@ -30,7 +30,7 @@ var Client = module.exports = function (config) {
|
|
|
30
30
|
this._types = new TypeOverrides(config.types)
|
|
31
31
|
|
|
32
32
|
this.native = new Native({
|
|
33
|
-
types: this._types
|
|
33
|
+
types: this._types,
|
|
34
34
|
})
|
|
35
35
|
|
|
36
36
|
this._queryQueue = []
|
|
@@ -41,7 +41,7 @@ var Client = module.exports = function (config) {
|
|
|
41
41
|
|
|
42
42
|
// keep these on the object for legacy reasons
|
|
43
43
|
// for the time being. TODO: deprecate all this jazz
|
|
44
|
-
var cp = this.connectionParameters = new ConnectionParameters(config)
|
|
44
|
+
var cp = (this.connectionParameters = new ConnectionParameters(config))
|
|
45
45
|
this.user = cp.user
|
|
46
46
|
|
|
47
47
|
// "hiding" the password so it doesn't show up in stack traces
|
|
@@ -50,7 +50,7 @@ var Client = module.exports = function (config) {
|
|
|
50
50
|
configurable: true,
|
|
51
51
|
enumerable: false,
|
|
52
52
|
writable: true,
|
|
53
|
-
value: cp.password
|
|
53
|
+
value: cp.password,
|
|
54
54
|
})
|
|
55
55
|
this.database = cp.database
|
|
56
56
|
this.host = cp.host
|
|
@@ -58,7 +58,7 @@ var Client = module.exports = function (config) {
|
|
|
58
58
|
|
|
59
59
|
// a hash to hold named queries
|
|
60
60
|
this.namedQueries = {}
|
|
61
|
-
}
|
|
61
|
+
})
|
|
62
62
|
|
|
63
63
|
Client.Query = NativeQuery
|
|
64
64
|
|
|
@@ -115,7 +115,7 @@ Client.prototype._connect = function (cb) {
|
|
|
115
115
|
self.native.on('notification', function (msg) {
|
|
116
116
|
self.emit('notification', {
|
|
117
117
|
channel: msg.relname,
|
|
118
|
-
payload: msg.extra
|
|
118
|
+
payload: msg.extra,
|
|
119
119
|
})
|
|
120
120
|
})
|
|
121
121
|
|
|
@@ -180,7 +180,7 @@ Client.prototype.query = function (config, values, callback) {
|
|
|
180
180
|
resolveOut = resolve
|
|
181
181
|
rejectOut = reject
|
|
182
182
|
})
|
|
183
|
-
query.callback = (err, res) => err ? rejectOut(err) : resolveOut(res)
|
|
183
|
+
query.callback = (err, res) => (err ? rejectOut(err) : resolveOut(res))
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
|
|
@@ -248,7 +248,7 @@ Client.prototype.end = function (cb) {
|
|
|
248
248
|
var result
|
|
249
249
|
if (!cb) {
|
|
250
250
|
result = new this._Promise(function (resolve, reject) {
|
|
251
|
-
cb = (err) => err ? reject(err) : resolve()
|
|
251
|
+
cb = (err) => (err ? reject(err) : resolve())
|
|
252
252
|
})
|
|
253
253
|
}
|
|
254
254
|
this.native.end(function () {
|
package/lib/native/query.js
CHANGED
|
@@ -11,7 +11,7 @@ var EventEmitter = require('events').EventEmitter
|
|
|
11
11
|
var util = require('util')
|
|
12
12
|
var utils = require('../utils')
|
|
13
13
|
|
|
14
|
-
var NativeQuery = module.exports = function (config, values, callback) {
|
|
14
|
+
var NativeQuery = (module.exports = function (config, values, callback) {
|
|
15
15
|
EventEmitter.call(this)
|
|
16
16
|
config = utils.normalizeQueryConfig(config, values, callback)
|
|
17
17
|
this.text = config.text
|
|
@@ -27,27 +27,30 @@ var NativeQuery = module.exports = function (config, values, callback) {
|
|
|
27
27
|
// this has almost no meaning because libpq
|
|
28
28
|
// reads all rows into memory befor returning any
|
|
29
29
|
this._emitRowEvents = false
|
|
30
|
-
this.on(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
this.on(
|
|
31
|
+
'newListener',
|
|
32
|
+
function (event) {
|
|
33
|
+
if (event === 'row') this._emitRowEvents = true
|
|
34
|
+
}.bind(this)
|
|
35
|
+
)
|
|
36
|
+
})
|
|
34
37
|
|
|
35
38
|
util.inherits(NativeQuery, EventEmitter)
|
|
36
39
|
|
|
37
40
|
var errorFieldMap = {
|
|
38
41
|
/* eslint-disable quote-props */
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
sqlState: 'code',
|
|
43
|
+
statementPosition: 'position',
|
|
44
|
+
messagePrimary: 'message',
|
|
45
|
+
context: 'where',
|
|
46
|
+
schemaName: 'schema',
|
|
47
|
+
tableName: 'table',
|
|
48
|
+
columnName: 'column',
|
|
49
|
+
dataTypeName: 'dataType',
|
|
50
|
+
constraintName: 'constraint',
|
|
51
|
+
sourceFile: 'file',
|
|
52
|
+
sourceLine: 'line',
|
|
53
|
+
sourceFunction: 'routine',
|
|
51
54
|
}
|
|
52
55
|
|
|
53
56
|
NativeQuery.prototype.handleError = function (err) {
|
|
@@ -77,10 +80,12 @@ NativeQuery.prototype.catch = function (callback) {
|
|
|
77
80
|
|
|
78
81
|
NativeQuery.prototype._getPromise = function () {
|
|
79
82
|
if (this._promise) return this._promise
|
|
80
|
-
this._promise = new Promise(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
this._promise = new Promise(
|
|
84
|
+
function (resolve, reject) {
|
|
85
|
+
this._once('end', resolve)
|
|
86
|
+
this._once('error', reject)
|
|
87
|
+
}.bind(this)
|
|
88
|
+
)
|
|
84
89
|
return this._promise
|
|
85
90
|
}
|
|
86
91
|
|
|
@@ -105,7 +110,7 @@ NativeQuery.prototype.submit = function (client) {
|
|
|
105
110
|
if (self._emitRowEvents) {
|
|
106
111
|
if (results.length > 1) {
|
|
107
112
|
rows.forEach((rowOfRows, i) => {
|
|
108
|
-
rowOfRows.forEach(row => {
|
|
113
|
+
rowOfRows.forEach((row) => {
|
|
109
114
|
self.emit('row', row, results[i])
|
|
110
115
|
})
|
|
111
116
|
})
|
package/lib/query.js
CHANGED
|
@@ -42,14 +42,22 @@ class Query extends EventEmitter {
|
|
|
42
42
|
|
|
43
43
|
requiresPreparation() {
|
|
44
44
|
// named queries must always be prepared
|
|
45
|
-
if (this.name) {
|
|
45
|
+
if (this.name) {
|
|
46
|
+
return true
|
|
47
|
+
}
|
|
46
48
|
// always prepare if there are max number of rows expected per
|
|
47
49
|
// portal execution
|
|
48
|
-
if (this.rows) {
|
|
50
|
+
if (this.rows) {
|
|
51
|
+
return true
|
|
52
|
+
}
|
|
49
53
|
// don't prepare empty text queries
|
|
50
|
-
if (!this.text) {
|
|
54
|
+
if (!this.text) {
|
|
55
|
+
return false
|
|
56
|
+
}
|
|
51
57
|
// prepare if there are values
|
|
52
|
-
if (!this.values) {
|
|
58
|
+
if (!this.values) {
|
|
59
|
+
return false
|
|
60
|
+
}
|
|
53
61
|
return this.values.length > 0
|
|
54
62
|
}
|
|
55
63
|
|
|
@@ -168,10 +176,13 @@ class Query extends EventEmitter {
|
|
|
168
176
|
}
|
|
169
177
|
|
|
170
178
|
_getRows(connection, rows) {
|
|
171
|
-
connection.execute(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
179
|
+
connection.execute(
|
|
180
|
+
{
|
|
181
|
+
portal: this.portal,
|
|
182
|
+
rows: rows,
|
|
183
|
+
},
|
|
184
|
+
true
|
|
185
|
+
)
|
|
175
186
|
connection.flush()
|
|
176
187
|
}
|
|
177
188
|
|
|
@@ -181,11 +192,14 @@ class Query extends EventEmitter {
|
|
|
181
192
|
this.isPreparedStatement = true
|
|
182
193
|
// TODO refactor this poor encapsulation
|
|
183
194
|
if (!this.hasBeenParsed(connection)) {
|
|
184
|
-
connection.parse(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
195
|
+
connection.parse(
|
|
196
|
+
{
|
|
197
|
+
text: this.text,
|
|
198
|
+
name: this.name,
|
|
199
|
+
types: this.types,
|
|
200
|
+
},
|
|
201
|
+
true
|
|
202
|
+
)
|
|
189
203
|
}
|
|
190
204
|
|
|
191
205
|
if (this.values) {
|
|
@@ -198,17 +212,23 @@ class Query extends EventEmitter {
|
|
|
198
212
|
}
|
|
199
213
|
|
|
200
214
|
// http://developer.postgresql.org/pgdocs/postgres/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY
|
|
201
|
-
connection.bind(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
215
|
+
connection.bind(
|
|
216
|
+
{
|
|
217
|
+
portal: this.portal,
|
|
218
|
+
statement: this.name,
|
|
219
|
+
values: this.values,
|
|
220
|
+
binary: this.binary,
|
|
221
|
+
},
|
|
222
|
+
true
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
connection.describe(
|
|
226
|
+
{
|
|
227
|
+
type: 'P',
|
|
228
|
+
name: this.portal || '',
|
|
229
|
+
},
|
|
230
|
+
true
|
|
231
|
+
)
|
|
212
232
|
|
|
213
233
|
this._getRows(connection, this.rows)
|
|
214
234
|
}
|
package/lib/sasl.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
const crypto = require('crypto')
|
|
3
3
|
|
|
4
|
-
function startSession
|
|
4
|
+
function startSession(mechanisms) {
|
|
5
5
|
if (mechanisms.indexOf('SCRAM-SHA-256') === -1) {
|
|
6
6
|
throw new Error('SASL: Only mechanism SCRAM-SHA-256 is currently supported')
|
|
7
7
|
}
|
|
@@ -12,11 +12,11 @@ function startSession (mechanisms) {
|
|
|
12
12
|
mechanism: 'SCRAM-SHA-256',
|
|
13
13
|
clientNonce,
|
|
14
14
|
response: 'n,,n=*,r=' + clientNonce,
|
|
15
|
-
message: 'SASLInitialResponse'
|
|
15
|
+
message: 'SASLInitialResponse',
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
function continueSession
|
|
19
|
+
function continueSession(session, password, serverData) {
|
|
20
20
|
if (session.message !== 'SASLInitialResponse') {
|
|
21
21
|
throw new Error('SASL: Last message was not SASLInitialResponse')
|
|
22
22
|
}
|
|
@@ -53,42 +53,46 @@ function continueSession (session, password, serverData) {
|
|
|
53
53
|
session.response = clientFinalMessageWithoutProof + ',p=' + clientProof
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
function finalizeSession
|
|
56
|
+
function finalizeSession(session, serverData) {
|
|
57
57
|
if (session.message !== 'SASLResponse') {
|
|
58
58
|
throw new Error('SASL: Last message was not SASLResponse')
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
var serverSignature
|
|
62
62
|
|
|
63
|
-
String(serverData)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
63
|
+
String(serverData)
|
|
64
|
+
.split(',')
|
|
65
|
+
.forEach(function (part) {
|
|
66
|
+
switch (part[0]) {
|
|
67
|
+
case 'v':
|
|
68
|
+
serverSignature = part.substr(2)
|
|
69
|
+
break
|
|
70
|
+
}
|
|
71
|
+
})
|
|
70
72
|
|
|
71
73
|
if (serverSignature !== session.serverSignature) {
|
|
72
74
|
throw new Error('SASL: SCRAM-SERVER-FINAL-MESSAGE: server signature does not match')
|
|
73
75
|
}
|
|
74
76
|
}
|
|
75
77
|
|
|
76
|
-
function extractVariablesFromFirstServerMessage
|
|
78
|
+
function extractVariablesFromFirstServerMessage(data) {
|
|
77
79
|
var nonce, salt, iteration
|
|
78
80
|
|
|
79
|
-
String(data)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
81
|
+
String(data)
|
|
82
|
+
.split(',')
|
|
83
|
+
.forEach(function (part) {
|
|
84
|
+
switch (part[0]) {
|
|
85
|
+
case 'r':
|
|
86
|
+
nonce = part.substr(2)
|
|
87
|
+
break
|
|
88
|
+
case 's':
|
|
89
|
+
salt = part.substr(2)
|
|
90
|
+
break
|
|
91
|
+
case 'i':
|
|
92
|
+
iteration = parseInt(part.substr(2), 10)
|
|
93
|
+
break
|
|
94
|
+
}
|
|
95
|
+
})
|
|
92
96
|
|
|
93
97
|
if (!nonce) {
|
|
94
98
|
throw new Error('SASL: SCRAM-SERVER-FIRST-MESSAGE: nonce missing')
|
|
@@ -105,11 +109,11 @@ function extractVariablesFromFirstServerMessage (data) {
|
|
|
105
109
|
return {
|
|
106
110
|
nonce,
|
|
107
111
|
salt,
|
|
108
|
-
iteration
|
|
112
|
+
iteration,
|
|
109
113
|
}
|
|
110
114
|
}
|
|
111
115
|
|
|
112
|
-
function xorBuffers
|
|
116
|
+
function xorBuffers(a, b) {
|
|
113
117
|
if (!Buffer.isBuffer(a)) a = Buffer.from(a)
|
|
114
118
|
if (!Buffer.isBuffer(b)) b = Buffer.from(b)
|
|
115
119
|
var res = []
|
|
@@ -125,11 +129,11 @@ function xorBuffers (a, b) {
|
|
|
125
129
|
return Buffer.from(res)
|
|
126
130
|
}
|
|
127
131
|
|
|
128
|
-
function createHMAC
|
|
132
|
+
function createHMAC(key, msg) {
|
|
129
133
|
return crypto.createHmac('sha256', key).update(msg).digest()
|
|
130
134
|
}
|
|
131
135
|
|
|
132
|
-
function Hi
|
|
136
|
+
function Hi(password, saltBytes, iterations) {
|
|
133
137
|
var ui1 = createHMAC(password, Buffer.concat([saltBytes, Buffer.from([0, 0, 0, 1])]))
|
|
134
138
|
var ui = ui1
|
|
135
139
|
for (var i = 0; i < iterations - 1; i++) {
|
|
@@ -143,5 +147,5 @@ function Hi (password, saltBytes, iterations) {
|
|
|
143
147
|
module.exports = {
|
|
144
148
|
startSession,
|
|
145
149
|
continueSession,
|
|
146
|
-
finalizeSession
|
|
150
|
+
finalizeSession,
|
|
147
151
|
}
|
package/lib/type-overrides.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
var types = require('pg-types')
|
|
11
11
|
|
|
12
|
-
function TypeOverrides
|
|
12
|
+
function TypeOverrides(userTypes) {
|
|
13
13
|
this._types = userTypes || types
|
|
14
14
|
this.text = {}
|
|
15
15
|
this.binary = {}
|
|
@@ -17,9 +17,12 @@ function TypeOverrides (userTypes) {
|
|
|
17
17
|
|
|
18
18
|
TypeOverrides.prototype.getOverrides = function (format) {
|
|
19
19
|
switch (format) {
|
|
20
|
-
case 'text':
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
case 'text':
|
|
21
|
+
return this.text
|
|
22
|
+
case 'binary':
|
|
23
|
+
return this.binary
|
|
24
|
+
default:
|
|
25
|
+
return {}
|
|
23
26
|
}
|
|
24
27
|
}
|
|
25
28
|
|