Skip to content

Commit 0cc5366

Browse files
authored
Merge pull request #1175 from dhensby/pulls/connection-string
Add support for TrustedServerCertificate to connection string parsing
2 parents cb99de0 + b41eaa1 commit 0cc5366

File tree

5 files changed

+197
-3
lines changed

5 files changed

+197
-3
lines changed

lib/base/connection-pool.js

Lines changed: 183 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
const { EventEmitter } = require('events')
44
const debug = require('debug')('mssql:base')
5+
const { parseSqlConnectionString } = require('@tediousjs/connection-string')
56
const tarn = require('tarn')
67
const { IDS } = require('../utils')
7-
const ConnectionString = require('../connectionstring')
88
const ConnectionError = require('../error/connection-error')
99
const shared = require('../shared')
1010

@@ -43,7 +43,7 @@ class ConnectionPool extends EventEmitter {
4343

4444
if (typeof config === 'string') {
4545
try {
46-
this.config = ConnectionString.resolve(config, shared.driver.name)
46+
this.config = this.parseConnectionString(config)
4747
} catch (ex) {
4848
if (typeof callback === 'function') {
4949
return setImmediate(callback, ex)
@@ -83,6 +83,187 @@ class ConnectionPool extends EventEmitter {
8383
return this._healthy
8484
}
8585

86+
parseConnectionString (connectionString) {
87+
return this._parseConnectionString(connectionString)
88+
}
89+
90+
_parseConnectionString (connectionString) {
91+
const parsed = parseSqlConnectionString(connectionString, true, true)
92+
return Object.entries(parsed).reduce((config, [key, value]) => {
93+
switch (key) {
94+
case 'application name':
95+
break
96+
case 'applicationintent':
97+
Object.assign(config.options, {
98+
readOnlyIntent: value === 'readonly'
99+
})
100+
break
101+
case 'asynchronous processing':
102+
break
103+
case 'attachdbfilename':
104+
break
105+
case 'authentication':
106+
break
107+
case 'column encryption setting':
108+
break
109+
case 'connection timeout':
110+
Object.assign(config, {
111+
connectionTimeout: value * 1000
112+
})
113+
break
114+
case 'connection lifetime':
115+
break
116+
case 'connectretrycount':
117+
break
118+
case 'connectretryinterval':
119+
Object.assign(config.options, {
120+
connectionRetryInterval: value * 1000
121+
})
122+
break
123+
case 'context connection':
124+
break
125+
case 'current language':
126+
Object.assign(config.options, {
127+
language: value
128+
})
129+
break
130+
case 'data source':
131+
{
132+
let server = value
133+
let instanceName
134+
let port = 1433
135+
if (/^np:/i.test(server)) {
136+
throw new Error('Connection via Named Pipes is not supported.')
137+
}
138+
if (/^tcp:/i.test(server)) {
139+
server = server.substr(4)
140+
}
141+
if (/^(.*)\\(.*)$/.exec(server)) {
142+
server = RegExp.$1
143+
instanceName = RegExp.$2
144+
}
145+
if (/^(.*),(.*)$/.exec(server)) {
146+
server = RegExp.$1.trim()
147+
port = parseInt(RegExp.$2.trim(), 10)
148+
}
149+
if (server === '.' || server === '(.)' || server.toLowerCase() === '(localdb)' || server.toLowerCase() === '(local)') {
150+
server = 'localhost'
151+
}
152+
Object.assign(config, {
153+
port,
154+
server
155+
})
156+
Object.assign(config.options, {
157+
instanceName
158+
})
159+
break
160+
}
161+
case 'encrypt':
162+
Object.assign(config.options, {
163+
encrypt: true
164+
})
165+
break
166+
case 'enlist':
167+
break
168+
case 'failover partner':
169+
break
170+
case 'initial catalog':
171+
Object.assign(config, {
172+
database: value
173+
})
174+
break
175+
case 'integrated security':
176+
break
177+
case 'max pool size':
178+
Object.assign(config.pool, {
179+
max: value
180+
})
181+
break
182+
case 'min pool size':
183+
Object.assign(config.pool, {
184+
min: value
185+
})
186+
break
187+
case 'multipleactiveresultsets':
188+
break
189+
case 'multisubnetfailover':
190+
Object.assign(config.options, {
191+
multiSubnetFailover: value
192+
})
193+
break
194+
case 'network library':
195+
break
196+
case 'packet size':
197+
Object.assign(config.options, {
198+
packetSize: value
199+
})
200+
break
201+
case 'password':
202+
Object.assign(config, {
203+
password: value
204+
})
205+
break
206+
case 'persist security info':
207+
break
208+
case 'poolblockingperiod':
209+
break
210+
case 'pooling':
211+
break
212+
case 'replication':
213+
break
214+
case 'transaction binding':
215+
Object.assign(config.options, {
216+
enableImplicitTransactions: value.toLowerCase() === 'Implicit Unbind'
217+
})
218+
break
219+
case 'transparentnetworkipresolution':
220+
break
221+
case 'trustservercertificate':
222+
Object.assign(config.options, {
223+
trustServerCertificate: value
224+
})
225+
break
226+
case 'type system version':
227+
break
228+
case 'user id': {
229+
let user = value
230+
let domain
231+
if (/^(.*)\\(.*)$/.exec(user)) {
232+
domain = RegExp.$1
233+
user = RegExp.$2
234+
}
235+
Object.assign(config, {
236+
domain,
237+
user
238+
})
239+
break
240+
}
241+
case 'user instance':
242+
break
243+
case 'workstation id':
244+
Object.assign(config.options, {
245+
workstationId: value
246+
})
247+
break
248+
case 'requesttimeout':
249+
Object.assign(config, {
250+
requestTimeout: parseInt(value, 10)
251+
})
252+
break
253+
case 'stream':
254+
Object.assign(config, {
255+
stream: !!value
256+
})
257+
break
258+
case 'useutc':
259+
Object.assign(config.options, {
260+
useUTC: !!value
261+
})
262+
}
263+
return config
264+
}, { options: {}, pool: {} })
265+
}
266+
86267
/**
87268
* Acquire connection from this connection pool.
88269
*

lib/connectionstring.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,12 @@ const resolveConnectionString = function (string, driver) {
226226
}
227227
}
228228

229+
if (parsed.trustservercertificate && ['true', '1', 'yes'].includes(parsed.trustservercertificate.toLowerCase())) {
230+
Object.assign(config.options, {
231+
trustServerCertificate: true
232+
})
233+
}
234+
229235
if (parsed.useUTC != null) {
230236
const utc = parsed.useUTC.toLowerCase()
231237
config.options.useUTC = utc === 'true' || utc === 'yes' || utc === '1'

package-lock.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"repository": "github:tediousjs/node-mssql",
2727
"license": "MIT",
2828
"dependencies": {
29+
"@tediousjs/connection-string": "^0.3.0",
2930
"debug": "^4",
3031
"tarn": "^3.0.1",
3132
"tedious": "^9.2.3"

test/common/unit.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@ describe('Connection String', () => {
2121
})
2222

2323
it('Connection String #2', done => {
24-
const cfg = cs.resolve('Server=tcp:192.168.0.1,1433;Database=testdb;User Id=testuser;Password=testpwd')
24+
const cfg = cs.resolve('Server=tcp:192.168.0.1,1433;Database=testdb;User Id=testuser;Password=testpwd;TrustServerCertificate=true')
2525

2626
assert.strictEqual(cfg.user, 'testuser')
2727
assert.strictEqual(cfg.password, 'testpwd')
2828
assert.strictEqual(cfg.database, 'testdb')
2929
assert.strictEqual(cfg.server, '192.168.0.1')
3030
assert.strictEqual(cfg.port, 1433)
31+
assert.strictEqual(cfg.options.trustServerCertificate, true)
3132

3233
return done()
3334
})

0 commit comments

Comments
 (0)