Skip to content

Commit

Permalink
Merge pull request #10 from romanbalayan/release-5.5.0
Browse files Browse the repository at this point in the history
Release 5.5.0
  • Loading branch information
romanbalayan authored Sep 30, 2022
2 parents a8828df + 4081b8f commit 966bbf8
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 53 deletions.
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
# node-oracledb-prebuilt-for-lambda

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

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

# Usage

```bash
npm install --save oracledb-prebuilt-for-lambda@5.4.0
npm install --save oracledb-prebuilt-for-lambda@5.5.0
```

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


# Releases
| node-oracledb | oracledb-prebuilt-for-lambda |
| ------------------- | ---------- |
| 5.5.0 | 5.5.0 |
| 5.4.0 | 5.4.0 |
| 5.3.0 | 5.3.0 |
| 5.2.0 | 5.2.0 |
Expand All @@ -32,6 +33,7 @@ npm install --save [email protected]


# Changelog
- 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)
- 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)
- 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)
- 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)
Expand All @@ -49,7 +51,7 @@ npm install --save [email protected]

| Name | Identifier | Operating System |
| ------------- | ---------- | ----------------- |
| Node.js 16 | nodejs14.x | AWS Linux 2 |
| Node.js 16 | nodejs16.x | AWS Linux 2 |
| Node.js 14 | nodejs14.x | AWS Linux 2 |
| Node.js 12 | nodejs12.x | AWS Linux 2 |

Expand Down
Binary file modified build/Release/oracledb.node
Binary file not shown.
180 changes: 136 additions & 44 deletions lib/oracledb.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class OracleDb {
this.shutdown = nodbUtil.callbackify(shutdown).bind(_oracledb);
this.startup = nodbUtil.callbackify(startup).bind(_oracledb);
this.initOracleClient = this.initOracleClient.bind(_oracledb);
this._accessTokenHandler = this._accessTokenHandler.bind(_oracledb);
}

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

// handler for access token callbacks
async _accessTokenHandler(userFn, externalObj, refresh) {
let accessToken;
try {
let result = userFn(refresh);
if (result instanceof Promise) {
result = await result;
}

_checkToken(result);
accessToken = result;
} finally {
this._returnAccessToken(externalObj, accessToken);
}
}

// retrieves a pool from the pool cache (synchronous method)
getPool(poolAlias) {
let pool;
Expand Down Expand Up @@ -175,6 +192,21 @@ async function createPool(poolAttrs) {
throw new Error(nodbUtil.getErrorMessage('NJS-046', poolAlias));
}

if (poolAttrs.accessToken !== undefined) {
// cannot set username or password for token based authentication
if (poolAttrs.user !== undefined ||
poolAttrs.password !== undefined) {
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
}

// homogeneous and externalAuth must be set to true for token based
// authentication
if (poolAttrs.homogeneous === false ||
poolAttrs.externalAuth === false) {
throw new Error(nodbUtil.getErrorMessage('NJS-085'));
}
}

// create an adjusted set of pool attributes to pass to the C layer; the
// session callback must be removed if it is a JavaScript function and the
// queue timeout is used to specify the maximum amount of time that the C
Expand All @@ -192,44 +224,33 @@ async function createPool(poolAttrs) {
adjustedPoolAttrs.queueTimeout = this.queueTimeout;
}

// Need to prevent another call in the same stack from succeeding, otherwise
// two pools could be created with the same poolAlias and the second one that
// comes back would overwrite the first in the cache.
if (poolAlias) {
tempUsedPoolAliases[poolAlias] = true;
}

if (adjustedPoolAttrs.accessToken !== undefined) {
// token and privateKey must be set for token based
// authentication
if (adjustedPoolAttrs.accessToken.token === undefined ||
adjustedPoolAttrs.accessToken.token === '' ||
adjustedPoolAttrs.accessToken.privateKey === undefined ||
adjustedPoolAttrs.accessToken.privateKey === '') {
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
// token based authentication
if (poolAttrs.accessToken !== undefined) {
// accessTokenCallback is depricated from node-oracledb 5.5
if (poolAttrs.accessTokenCallback !== undefined &&
typeof poolAttrs.accessToken === 'function') {
throw new Error(nodbUtil.getErrorMessage('NJS-088'));
}

// cannot set username or password for token based authentication
if (adjustedPoolAttrs.user !== undefined ||
adjustedPoolAttrs.password !== undefined) {
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
}
let accessToken;
if (typeof poolAttrs.accessToken === 'function') {
adjustedPoolAttrs.accessTokenCallback = poolAttrs.accessToken;
accessToken = await poolAttrs.accessToken(false);

// homogeneous and externalAuth must be set to true for token based
// authentication
if (adjustedPoolAttrs.homogeneous === false ||
adjustedPoolAttrs.externalAuth === false) {
throw new Error(nodbUtil.getErrorMessage('NJS-085'));
if (_isTokenExpired(accessToken)) {
accessToken = await poolAttrs.accessToken(true);
}
} else {
accessToken = poolAttrs.accessToken;
}

adjustedPoolAttrs.token = adjustedPoolAttrs.accessToken.token;
adjustedPoolAttrs.privateKey =
adjustedPoolAttrs.accessToken.privateKey;
_checkToken(accessToken, adjustedPoolAttrs);
}

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

try {
Expand Down Expand Up @@ -305,15 +326,6 @@ async function getConnection(a1) {
// otherwise, create a new standalone connection
} else {
if (connAttrs.accessToken !== undefined) {
// token and privateKey must be set for token based
// authentication
if (connAttrs.accessToken.token === undefined ||
connAttrs.accessToken.token === '' ||
connAttrs.accessToken.privateKey === undefined ||
connAttrs.accessToken.privateKey === '') {
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
}

// cannot set username or password for token based authentication
if (connAttrs.user !== undefined ||
connAttrs.password !== undefined) {
Expand All @@ -325,9 +337,17 @@ async function getConnection(a1) {
throw new Error(nodbUtil.getErrorMessage('NJS-086'));
}

connAttrs.token = connAttrs.accessToken.token;
connAttrs.privateKey =
connAttrs.accessToken.privateKey;
let accessToken;
if (typeof connAttrs.accessToken === 'function') {
accessToken = await connAttrs.accessToken(false);

if (_isTokenExpired(accessToken)) {
accessToken = await connAttrs.accessToken(true);
}
} else {
accessToken = connAttrs.accessToken;
}
_checkToken(accessToken, connAttrs);
}

try {
Expand Down Expand Up @@ -427,6 +447,78 @@ async function startup(a1, a2) {
}


//-----------------------------------------------------------------------------
// _isTokenExpiredUtil()
// Function to check validity and expiry of token
//-----------------------------------------------------------------------------
function _isTokenExpiredUtil(accessToken) {
nodbUtil.assert(typeof accessToken === 'string', 'NJS-084', 1);

if (accessToken.split('.')[1] === undefined) {
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
}

const base64Url = accessToken.split('.')[1];
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const buff = Buffer.from(base64, 'base64');
const payloadInit = buff.toString('ascii');

let expiry = JSON.parse(payloadInit).exp;
nodbUtil.assert(expiry != undefined, 'NJS-084');
expiry = expiry * 1000;

return (new Date().getTime() > expiry);
}


//-----------------------------------------------------------------------------
// _isTokenExpired()
// Function to check validity of token parameter
//-----------------------------------------------------------------------------
function _isTokenExpired(accessToken) {
switch (typeof accessToken) {
case 'string':
if (accessToken === '') {
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
}

return _isTokenExpiredUtil(accessToken);
case 'object':
if (accessToken.token === undefined ||
accessToken.token === '' ||
accessToken.privateKey === undefined ||
accessToken.privateKey === '') {
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
}

return _isTokenExpiredUtil(accessToken.token);
default:
throw new Error(nodbUtil.getErrorMessage('NJS-084'));
}
}


//-----------------------------------------------------------------------------
// _checkToken()
// Function to check validity of token parameter
//-----------------------------------------------------------------------------
function _checkToken(accessToken, attrs) {
if (_isTokenExpired(accessToken)) {
throw new Error(nodbUtil.getErrorMessage('NJS-087'));
}

if (attrs === undefined)
return;

if (typeof accessToken === 'string') {
attrs.token = accessToken;
} else {
attrs.token = accessToken.token;
attrs.privateKey = accessToken.privateKey;
}
}


// create instance which will be exported
let oracleDbInst = new OracleDb();

Expand Down
13 changes: 13 additions & 0 deletions lib/resultset.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,19 @@ class ResultSet {
return this._connection._getDbObjectClassJS(schema, name);
}

[Symbol.asyncIterator]() {
const resultSet = this;
return {
async next() {
const row = await resultSet.getRow();
return {value: row, done: row === undefined};
},
return() {
return {done: true};
}
};
}

toQueryStream() {
nodbUtil.checkArgCount(arguments, 0, 0);

Expand Down
6 changes: 4 additions & 2 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,11 @@ const errorMessages = {
'NJS-081': 'NJS-081: concurrent operations on a connection are disabled',
'NJS-082': 'NJS-082: connection pool is being reconfigured',
'NJS-083': 'NJS-083: pool statistics not enabled',
'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',
'NJS-084': 'NJS-084: invalid access token',
'NJS-085': 'NJS-085: invalid connection pool configuration with token based authentication. The homogeneous and externalAuth attributes must be set to true',
'NJS-086': 'NJS-086: invalid standalone configuration with token based authentication. The externalAuth attribute must be set to true'
'NJS-086': 'NJS-086: invalid standalone configuration with token based authentication. The externalAuth attribute must be set to true',
'NJS-087': 'NJS-087: access token has expired',
'NJS-088': 'NJS-088: accessTokenCallback cannot be specified when accessToken is a function'
};

// getInstallURL returns a string with installation URL
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "oracledb-prebuilt-for-lambda",
"version": "5.4.0",
"version": "5.5.0",
"description": "Node OracleDB Client, pre-built for AWS Lambda",
"main": "index.js",
"directories": {
Expand Down

0 comments on commit 966bbf8

Please sign in to comment.