Skip to content

Commit 966bbf8

Browse files
authored
Merge pull request #10 from romanbalayan/release-5.5.0
Release 5.5.0
2 parents a8828df + 4081b8f commit 966bbf8

File tree

6 files changed

+162
-53
lines changed

6 files changed

+162
-53
lines changed

README.md

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
11
# node-oracledb-prebuilt-for-lambda
22

33
- This module is forked from the currently un-maintained [node-oracledb-for-lambda](https://github.com/nalbion/node-oracledb-for-lambda).
4-
- Core oracledb libraries are derived from [node-oracledb](https://github.com/oracle/node-oracledb) v5.4.0
5-
- 5.4.0: Prebuilt for use with AWS Lambda nodejs12.x Runtime (Built using nodejsv12.18.3)
6-
- Also tested to work with AWS Lambda nodejs14.x and nodejs16.x Runtime
4+
- Core oracledb libraries are derived from [node-oracledb](https://github.com/oracle/node-oracledb) v5.5.0
5+
- 5.5.0: Prebuilt for use with AWS Lambda nodejs14.x Runtime (Built using nodejsv14.20.0 (LTS))
6+
- Also tested to work with AWS Lambda nodejs12.x and nodejs16.x Runtime
77

88
The scripts to reproduce the build process can be found at [node-oracledb-lambda-test](https://github.com/romanbalayan/node-oracledb-lambda-test).
99

1010
# Usage
1111

1212
```bash
13-
npm install --save oracledb-prebuilt-for-lambda@5.4.0
13+
npm install --save oracledb-prebuilt-for-lambda@5.5.0
1414
```
1515

1616
# Versioning
1717
- Changed release version to match that of underlying node-oracledb version.
18-
- i.e. for release based on oracledb 5.4.0, release will be oracledb-prebuilt-for-lambda@5.4.0
18+
- i.e. for release based on oracledb 5.5.0, release will be oracledb-prebuilt-for-lambda@5.5.0
1919

2020

2121
# Releases
2222
| node-oracledb | oracledb-prebuilt-for-lambda |
2323
| ------------------- | ---------- |
24+
| 5.5.0 | 5.5.0 |
2425
| 5.4.0 | 5.4.0 |
2526
| 5.3.0 | 5.3.0 |
2627
| 5.2.0 | 5.2.0 |
@@ -32,6 +33,7 @@ npm install --save [email protected]
3233

3334

3435
# Changelog
36+
- v5.5.0: [node-oracledb v5.5.0 changelog](https://github.com/oracle/node-oracledb/blob/main/CHANGELOG.md#node-oracledb-v550-7-sep-2022)
3537
- v5.4.0: [node-oracledb v5.4.0 changelog](https://github.com/oracle/node-oracledb/blob/main/CHANGELOG.md#node-oracledb-v540-9-jun-2022)
3638
- v5.3.0: [node-oracledb v5.3.0 changelog](https://github.com/oracle/node-oracledb/blob/main/CHANGELOG.md#node-oracledb-v530-22-oct-2021)
3739
- v5.2.0: [node-oracledb v5.2.0 changelog](https://github.com/oracle/node-oracledb/blob/main/CHANGELOG.md#node-oracledb-v520-7-jun-2021)
@@ -49,7 +51,7 @@ npm install --save [email protected]
4951

5052
| Name | Identifier | Operating System |
5153
| ------------- | ---------- | ----------------- |
52-
| Node.js 16 | nodejs14.x | AWS Linux 2 |
54+
| Node.js 16 | nodejs16.x | AWS Linux 2 |
5355
| Node.js 14 | nodejs14.x | AWS Linux 2 |
5456
| Node.js 12 | nodejs12.x | AWS Linux 2 |
5557

build/Release/oracledb.node

686 Bytes
Binary file not shown.

lib/oracledb.js

+136-44
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class OracleDb {
106106
this.shutdown = nodbUtil.callbackify(shutdown).bind(_oracledb);
107107
this.startup = nodbUtil.callbackify(startup).bind(_oracledb);
108108
this.initOracleClient = this.initOracleClient.bind(_oracledb);
109+
this._accessTokenHandler = this._accessTokenHandler.bind(_oracledb);
109110
}
110111

111112
// temporary method for determining if an object is a date until
@@ -114,6 +115,22 @@ class OracleDb {
114115
return util.isDate(val);
115116
}
116117

118+
// handler for access token callbacks
119+
async _accessTokenHandler(userFn, externalObj, refresh) {
120+
let accessToken;
121+
try {
122+
let result = userFn(refresh);
123+
if (result instanceof Promise) {
124+
result = await result;
125+
}
126+
127+
_checkToken(result);
128+
accessToken = result;
129+
} finally {
130+
this._returnAccessToken(externalObj, accessToken);
131+
}
132+
}
133+
117134
// retrieves a pool from the pool cache (synchronous method)
118135
getPool(poolAlias) {
119136
let pool;
@@ -175,6 +192,21 @@ async function createPool(poolAttrs) {
175192
throw new Error(nodbUtil.getErrorMessage('NJS-046', poolAlias));
176193
}
177194

195+
if (poolAttrs.accessToken !== undefined) {
196+
// cannot set username or password for token based authentication
197+
if (poolAttrs.user !== undefined ||
198+
poolAttrs.password !== undefined) {
199+
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
200+
}
201+
202+
// homogeneous and externalAuth must be set to true for token based
203+
// authentication
204+
if (poolAttrs.homogeneous === false ||
205+
poolAttrs.externalAuth === false) {
206+
throw new Error(nodbUtil.getErrorMessage('NJS-085'));
207+
}
208+
}
209+
178210
// create an adjusted set of pool attributes to pass to the C layer; the
179211
// session callback must be removed if it is a JavaScript function and the
180212
// queue timeout is used to specify the maximum amount of time that the C
@@ -192,44 +224,33 @@ async function createPool(poolAttrs) {
192224
adjustedPoolAttrs.queueTimeout = this.queueTimeout;
193225
}
194226

195-
// Need to prevent another call in the same stack from succeeding, otherwise
196-
// two pools could be created with the same poolAlias and the second one that
197-
// comes back would overwrite the first in the cache.
198-
if (poolAlias) {
199-
tempUsedPoolAliases[poolAlias] = true;
200-
}
201-
202-
if (adjustedPoolAttrs.accessToken !== undefined) {
203-
// token and privateKey must be set for token based
204-
// authentication
205-
if (adjustedPoolAttrs.accessToken.token === undefined ||
206-
adjustedPoolAttrs.accessToken.token === '' ||
207-
adjustedPoolAttrs.accessToken.privateKey === undefined ||
208-
adjustedPoolAttrs.accessToken.privateKey === '') {
209-
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
227+
// token based authentication
228+
if (poolAttrs.accessToken !== undefined) {
229+
// accessTokenCallback is depricated from node-oracledb 5.5
230+
if (poolAttrs.accessTokenCallback !== undefined &&
231+
typeof poolAttrs.accessToken === 'function') {
232+
throw new Error(nodbUtil.getErrorMessage('NJS-088'));
210233
}
211234

212-
// cannot set username or password for token based authentication
213-
if (adjustedPoolAttrs.user !== undefined ||
214-
adjustedPoolAttrs.password !== undefined) {
215-
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
216-
}
235+
let accessToken;
236+
if (typeof poolAttrs.accessToken === 'function') {
237+
adjustedPoolAttrs.accessTokenCallback = poolAttrs.accessToken;
238+
accessToken = await poolAttrs.accessToken(false);
217239

218-
// homogeneous and externalAuth must be set to true for token based
219-
// authentication
220-
if (adjustedPoolAttrs.homogeneous === false ||
221-
adjustedPoolAttrs.externalAuth === false) {
222-
throw new Error(nodbUtil.getErrorMessage('NJS-085'));
240+
if (_isTokenExpired(accessToken)) {
241+
accessToken = await poolAttrs.accessToken(true);
242+
}
243+
} else {
244+
accessToken = poolAttrs.accessToken;
223245
}
224-
225-
adjustedPoolAttrs.token = adjustedPoolAttrs.accessToken.token;
226-
adjustedPoolAttrs.privateKey =
227-
adjustedPoolAttrs.accessToken.privateKey;
246+
_checkToken(accessToken, adjustedPoolAttrs);
228247
}
229248

230-
if (adjustedPoolAttrs.accessToken === undefined &&
231-
adjustedPoolAttrs.accessTokenCallback !== undefined) {
232-
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
249+
// Need to prevent another call in the same stack from succeeding, otherwise
250+
// two pools could be created with the same poolAlias and the second one that
251+
// comes back would overwrite the first in the cache.
252+
if (poolAlias) {
253+
tempUsedPoolAliases[poolAlias] = true;
233254
}
234255

235256
try {
@@ -305,15 +326,6 @@ async function getConnection(a1) {
305326
// otherwise, create a new standalone connection
306327
} else {
307328
if (connAttrs.accessToken !== undefined) {
308-
// token and privateKey must be set for token based
309-
// authentication
310-
if (connAttrs.accessToken.token === undefined ||
311-
connAttrs.accessToken.token === '' ||
312-
connAttrs.accessToken.privateKey === undefined ||
313-
connAttrs.accessToken.privateKey === '') {
314-
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
315-
}
316-
317329
// cannot set username or password for token based authentication
318330
if (connAttrs.user !== undefined ||
319331
connAttrs.password !== undefined) {
@@ -325,9 +337,17 @@ async function getConnection(a1) {
325337
throw new Error(nodbUtil.getErrorMessage('NJS-086'));
326338
}
327339

328-
connAttrs.token = connAttrs.accessToken.token;
329-
connAttrs.privateKey =
330-
connAttrs.accessToken.privateKey;
340+
let accessToken;
341+
if (typeof connAttrs.accessToken === 'function') {
342+
accessToken = await connAttrs.accessToken(false);
343+
344+
if (_isTokenExpired(accessToken)) {
345+
accessToken = await connAttrs.accessToken(true);
346+
}
347+
} else {
348+
accessToken = connAttrs.accessToken;
349+
}
350+
_checkToken(accessToken, connAttrs);
331351
}
332352

333353
try {
@@ -427,6 +447,78 @@ async function startup(a1, a2) {
427447
}
428448

429449

450+
//-----------------------------------------------------------------------------
451+
// _isTokenExpiredUtil()
452+
// Function to check validity and expiry of token
453+
//-----------------------------------------------------------------------------
454+
function _isTokenExpiredUtil(accessToken) {
455+
nodbUtil.assert(typeof accessToken === 'string', 'NJS-084', 1);
456+
457+
if (accessToken.split('.')[1] === undefined) {
458+
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
459+
}
460+
461+
const base64Url = accessToken.split('.')[1];
462+
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
463+
const buff = Buffer.from(base64, 'base64');
464+
const payloadInit = buff.toString('ascii');
465+
466+
let expiry = JSON.parse(payloadInit).exp;
467+
nodbUtil.assert(expiry != undefined, 'NJS-084');
468+
expiry = expiry * 1000;
469+
470+
return (new Date().getTime() > expiry);
471+
}
472+
473+
474+
//-----------------------------------------------------------------------------
475+
// _isTokenExpired()
476+
// Function to check validity of token parameter
477+
//-----------------------------------------------------------------------------
478+
function _isTokenExpired(accessToken) {
479+
switch (typeof accessToken) {
480+
case 'string':
481+
if (accessToken === '') {
482+
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
483+
}
484+
485+
return _isTokenExpiredUtil(accessToken);
486+
case 'object':
487+
if (accessToken.token === undefined ||
488+
accessToken.token === '' ||
489+
accessToken.privateKey === undefined ||
490+
accessToken.privateKey === '') {
491+
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
492+
}
493+
494+
return _isTokenExpiredUtil(accessToken.token);
495+
default:
496+
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
497+
}
498+
}
499+
500+
501+
//-----------------------------------------------------------------------------
502+
// _checkToken()
503+
// Function to check validity of token parameter
504+
//-----------------------------------------------------------------------------
505+
function _checkToken(accessToken, attrs) {
506+
if (_isTokenExpired(accessToken)) {
507+
throw new Error(nodbUtil.getErrorMessage('NJS-087'));
508+
}
509+
510+
if (attrs === undefined)
511+
return;
512+
513+
if (typeof accessToken === 'string') {
514+
attrs.token = accessToken;
515+
} else {
516+
attrs.token = accessToken.token;
517+
attrs.privateKey = accessToken.privateKey;
518+
}
519+
}
520+
521+
430522
// create instance which will be exported
431523
let oracleDbInst = new OracleDb();
432524

lib/resultset.js

+13
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,19 @@ class ResultSet {
225225
return this._connection._getDbObjectClassJS(schema, name);
226226
}
227227

228+
[Symbol.asyncIterator]() {
229+
const resultSet = this;
230+
return {
231+
async next() {
232+
const row = await resultSet.getRow();
233+
return {value: row, done: row === undefined};
234+
},
235+
return() {
236+
return {done: true};
237+
}
238+
};
239+
}
240+
228241
toQueryStream() {
229242
nodbUtil.checkArgCount(arguments, 0, 0);
230243

lib/util.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,11 @@ const errorMessages = {
6767
'NJS-081': 'NJS-081: concurrent operations on a connection are disabled',
6868
'NJS-082': 'NJS-082: connection pool is being reconfigured',
6969
'NJS-083': 'NJS-083: pool statistics not enabled',
70-
'NJS-084': 'NJS-084: invalid or missing parameter with token based authentication. The token and privateKey attributes must contain values. Other credentials cannot be specified',
70+
'NJS-084': 'NJS-084: invalid access token',
7171
'NJS-085': 'NJS-085: invalid connection pool configuration with token based authentication. The homogeneous and externalAuth attributes must be set to true',
72-
'NJS-086': 'NJS-086: invalid standalone configuration with token based authentication. The externalAuth attribute must be set to true'
72+
'NJS-086': 'NJS-086: invalid standalone configuration with token based authentication. The externalAuth attribute must be set to true',
73+
'NJS-087': 'NJS-087: access token has expired',
74+
'NJS-088': 'NJS-088: accessTokenCallback cannot be specified when accessToken is a function'
7375
};
7476

7577
// getInstallURL returns a string with installation URL

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "oracledb-prebuilt-for-lambda",
3-
"version": "5.4.0",
3+
"version": "5.5.0",
44
"description": "Node OracleDB Client, pre-built for AWS Lambda",
55
"main": "index.js",
66
"directories": {

0 commit comments

Comments
 (0)