oracledb 6.8.0 → 6.10.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.
Files changed (85) hide show
  1. package/README.md +39 -3
  2. package/build/Release/oracledb-6.10.0-darwin-arm64.node +0 -0
  3. package/build/Release/oracledb-6.10.0-darwin-arm64.node-buildinfo.txt +1 -0
  4. package/build/Release/oracledb-6.10.0-darwin-x64.node +0 -0
  5. package/build/Release/oracledb-6.10.0-darwin-x64.node-buildinfo.txt +1 -0
  6. package/build/Release/oracledb-6.10.0-js-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-6.10.0-linux-arm64.node +0 -0
  8. package/build/Release/oracledb-6.10.0-linux-arm64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.10.0-linux-x64.node +0 -0
  10. package/build/Release/oracledb-6.10.0-linux-x64.node-buildinfo.txt +1 -0
  11. package/build/Release/oracledb-6.10.0-win32-x64.node +0 -0
  12. package/build/Release/oracledb-6.10.0-win32-x64.node-buildinfo.txt +1 -0
  13. package/lib/aqDeqOptions.js +18 -1
  14. package/lib/aqMessage.js +10 -1
  15. package/lib/aqQueue.js +10 -6
  16. package/lib/configProviders/file.js +72 -0
  17. package/lib/connection.js +93 -4
  18. package/lib/dbObject.js +34 -4
  19. package/lib/errors.js +70 -35
  20. package/lib/impl/aqDeqOptions.js +10 -1
  21. package/lib/impl/connection.js +9 -0
  22. package/lib/impl/datahandlers/buffer.js +49 -0
  23. package/lib/impl/datahandlers/oson.js +7 -2
  24. package/lib/impl/pool.js +10 -1
  25. package/lib/impl/resultset.js +5 -4
  26. package/lib/impl/sodaDocument.js +5 -14
  27. package/lib/lob.js +9 -1
  28. package/lib/oracledb.js +152 -30
  29. package/lib/pool.js +199 -147
  30. package/lib/poolStatistics.js +4 -2
  31. package/lib/sodaCollection.js +12 -8
  32. package/lib/sodaDatabase.js +35 -8
  33. package/lib/sodaDocument.js +24 -6
  34. package/lib/sodaOperation.js +7 -6
  35. package/lib/thin/aq.js +475 -0
  36. package/lib/thin/connection.js +171 -14
  37. package/lib/thin/dbObject.js +8 -6
  38. package/lib/thin/lob.js +2 -3
  39. package/lib/thin/pool.js +105 -28
  40. package/lib/thin/protocol/capabilities.js +10 -4
  41. package/lib/thin/protocol/constants.js +90 -1
  42. package/lib/thin/protocol/encryptDecrypt.js +2 -2
  43. package/lib/thin/protocol/messages/aqArray.js +238 -0
  44. package/lib/thin/protocol/messages/aqBase.js +305 -0
  45. package/lib/thin/protocol/messages/aqDeq.js +164 -0
  46. package/lib/thin/protocol/messages/aqEnq.js +135 -0
  47. package/lib/thin/protocol/messages/auth.js +25 -27
  48. package/lib/thin/protocol/messages/base.js +98 -9
  49. package/lib/thin/protocol/messages/dataType.js +2 -1
  50. package/lib/thin/protocol/messages/execute.js +46 -4
  51. package/lib/thin/protocol/messages/lobOp.js +5 -22
  52. package/lib/thin/protocol/messages/logOff.js +0 -1
  53. package/lib/thin/protocol/messages/sessionRelease.js +0 -1
  54. package/lib/thin/protocol/messages/transactionSwitch.js +12 -4
  55. package/lib/thin/protocol/messages/withData.js +3 -3
  56. package/lib/thin/protocol/packet.js +6 -5
  57. package/lib/thin/protocol/protocol.js +2 -1
  58. package/lib/thin/sqlnet/connStrategy.js +2 -1
  59. package/lib/thin/sqlnet/navNodes.js +1 -1
  60. package/lib/thin/sqlnet/networkSession.js +10 -4
  61. package/lib/thin/sqlnet/packet.js +2 -1
  62. package/lib/thin/sqlnet/sessionAtts.js +2 -3
  63. package/lib/types.js +6 -11
  64. package/lib/util.js +72 -11
  65. package/lib/version.js +1 -1
  66. package/package/install.js +3 -3
  67. package/package/prunebinaries.js +6 -12
  68. package/package.json +2 -2
  69. package/{lib/configProviders/azure.js → plugins/configProviders/azure/index.js} +73 -63
  70. package/plugins/configProviders/azurevault/index.js +84 -0
  71. package/{lib → plugins}/configProviders/base.js +13 -3
  72. package/{lib/configProviders/ociobject.js → plugins/configProviders/ociobject/index.js} +43 -78
  73. package/plugins/configProviders/ocivault/index.js +100 -0
  74. package/plugins/token/extensionOci/index.js +71 -35
  75. package/build/Release/oracledb-6.8.0-darwin-arm64.node +0 -0
  76. package/build/Release/oracledb-6.8.0-darwin-arm64.node-buildinfo.txt +0 -1
  77. package/build/Release/oracledb-6.8.0-darwin-x64.node +0 -0
  78. package/build/Release/oracledb-6.8.0-darwin-x64.node-buildinfo.txt +0 -1
  79. package/build/Release/oracledb-6.8.0-js-buildinfo.txt +0 -1
  80. package/build/Release/oracledb-6.8.0-linux-arm64.node +0 -0
  81. package/build/Release/oracledb-6.8.0-linux-arm64.node-buildinfo.txt +0 -1
  82. package/build/Release/oracledb-6.8.0-linux-x64.node +0 -0
  83. package/build/Release/oracledb-6.8.0-linux-x64.node-buildinfo.txt +0 -1
  84. package/build/Release/oracledb-6.8.0-win32-x64.node +0 -0
  85. package/build/Release/oracledb-6.8.0-win32-x64.node-buildinfo.txt +0 -1
package/lib/oracledb.js CHANGED
@@ -34,15 +34,15 @@ const impl = require('./impl');
34
34
  const process = require('process');
35
35
  const util = require('util');
36
36
 
37
- // This version of node-oracledb works with Node.js 14.6 or later.
37
+ // This version of node-oracledb works with Node.js 14.17 or later.
38
38
  // Note: the checked version is the minimum required for Node-API
39
39
  // compatibility. When new Node.js versions are released, older Node.js
40
40
  // versions are dropped from the node-oracledb test plan.
41
41
  //
42
42
  // Keep this code in sync with package/install.js
43
43
  const vs = process.version.substring(1).split(".").map(Number);
44
- errors.assert(vs[0] > 14 || (vs[0] === 14 && vs[1] >= 6),
45
- errors.ERR_NODE_TOO_OLD, nodbUtil.PACKAGE_JSON_VERSION, "14.6");
44
+ errors.assert(vs[0] > 14 || (vs[0] === 14 && vs[1] >= 17),
45
+ errors.ERR_NODE_TOO_OLD, nodbUtil.PACKAGE_JSON_VERSION, "14.17");
46
46
 
47
47
  const AqDeqOptions = require('./aqDeqOptions.js');
48
48
  const AqEnqOptions = require('./aqEnqOptions.js');
@@ -68,6 +68,7 @@ const poolCache = {};
68
68
  const tempUsedPoolAliases = {};
69
69
  const defaultPoolAlias = 'default';
70
70
  const registeredHooks = [];
71
+ const registeredConfigProviderHooks = new Map();
71
72
  let configProviderCache;
72
73
 
73
74
  // save arguments for call to initOracleClient()
@@ -382,6 +383,15 @@ async function _verifyOptions(options, inCreatePool) {
382
383
  outOptions.useSNI = options.useSNI;
383
384
  }
384
385
 
386
+ // appContext must be an array of array values. The element arrays should
387
+ // have 3 string values (namespace, name and value).
388
+ if (options.appContext !== undefined) {
389
+ const value = options.appContext;
390
+ errors.assertParamPropValue(nodbUtil.isAppContext(value), 1,
391
+ "appContext");
392
+ outOptions.appContext = options.appContext;
393
+ }
394
+
385
395
  // check pool specific options
386
396
  if (inCreatePool) {
387
397
 
@@ -435,6 +445,13 @@ async function _verifyOptions(options, inCreatePool) {
435
445
  outOptions.poolPingTimeout = options.poolPingTimeout;
436
446
  }
437
447
 
448
+ // maxLifeTime must be an unsigned integer
449
+ if (options.maxLifetimeSession !== undefined) {
450
+ errors.assertParamPropValue(Number.isInteger(options.maxLifetimeSession) &&
451
+ options.maxLifetimeSession >= 0, 1, "maxLifetimeSession");
452
+ outOptions.maxLifetimeSession = options.maxLifetimeSession;
453
+ }
454
+
438
455
  // homogeneous must be a boolean (and defaults to True)
439
456
  outOptions.homogeneous = true;
440
457
  if (options.homogeneous !== undefined) {
@@ -568,7 +585,10 @@ async function _verifyOptions(options, inCreatePool) {
568
585
  errors.throwErr(errors.ERR_WRONG_CRED_FOR_EXTAUTH);
569
586
  }
570
587
  if (outOptions.user) {
571
- if (inCreatePool) {
588
+
589
+ if (inCreatePool && !settings.thin) {
590
+ // Thick mode currently does not allow proxy users to specified
591
+ // during pool creation.
572
592
  errors.throwErr(errors.ERR_WRONG_CRED_FOR_EXTAUTH);
573
593
  } else if (outOptions.user[0] !== '[' || outOptions.user.slice(-1) !== ']') {
574
594
  // username is not enclosed in [].
@@ -888,35 +908,119 @@ async function shutdown(a1, a2) {
888
908
  await conn.close();
889
909
  }
890
910
 
911
+ async function _setConfigParameters(obj, credential, configProvider) {
912
+ const configObject = {};
913
+ const pmSection = 'njs';
914
+ const params = obj[pmSection];
915
+ for (const key in params) {
916
+ const val = params[key];
917
+ configObject[key] = val;
918
+ }
919
+ configObject.connectString = obj.connect_descriptor;
920
+ configObject.configTTL = obj.config_time_to_live;
921
+ if (!configObject.connectString)
922
+ errors.throwErr(errors.ERR_CONFIG_PROVIDER_FAILED_TO_RETRIEVE_CONFIG, 'connect_descriptor must be set');
923
+
924
+ configObject.user = obj.user;
925
+ if (obj.password) {
926
+ configObject.password = await _retrieveParamValueFromVault(obj['password'], credential, configProvider);
927
+ }
928
+ if (obj.wallet_location) {
929
+ // retrieve wallet_location
930
+ configObject.walletContent = await _retrieveParamValueFromVault(obj['wallet_location'], credential, configProvider);
931
+ //only Pem file supported
932
+ if (!nodbUtil.isPemFile(configObject.walletContent))
933
+ errors.throwErr(errors.ERR_WALLET_TYPE_NOT_SUPPORTED);
934
+ }
935
+ return configObject;
936
+ }
937
+
938
+ async function _retrieveParamValueFromVault(paramObj, credential, configProvider) {
939
+ const paramMap = new Map();
940
+ const auth = paramObj.authentication;
941
+ if (auth) {
942
+ for (const key in auth) {
943
+ if (key == 'method')
944
+ paramMap.set('authentication', auth[key]);
945
+ const val = auth[key];
946
+ paramMap.set(key.toLowerCase(), val);
947
+ }
948
+ }
949
+ const args = {};
950
+ if (paramObj.type == "base64") {
951
+ console.log("WARNING: Base64 Encoding in a JSON Password should only be used in development environments");
952
+ return Buffer.from(paramObj.value, "base64").toString("utf-8");
953
+ } else if (paramObj.type == "text") {
954
+ if (configProvider == 'azurevault' || configProvider == 'ocivault') {
955
+ console.log("WARNING: Plain Text in a JSON Password should only be used in development environments");
956
+ return paramObj.value;
957
+ } else
958
+ errors.throwErr(errors.ERR_CONFIG_PROVIDER_PARAM_TYPE, 'password type text is only allowed in ocivault and azurevault');
959
+ } else if (paramObj.type == "azurevault") {
960
+ paramMap.set('azuresecreturl', paramObj.value);
961
+ if (!(configProvider == 'azure' || configProvider == 'azurevault'))
962
+ credential = null;
963
+ const hookFn = registeredConfigProviderHooks['azurevault'];
964
+ if (hookFn == undefined)
965
+ errors.throwErr(errors.ERR_REGISTER_HOOKFN_CONFIGPROVIDER, 'azurevault');
966
+ args.credential = credential;
967
+ args.paramMap = paramMap;
968
+ const vaultReturn = await hookFn(args);
969
+ const paramValue = vaultReturn[0];
970
+ return paramValue;
971
+
972
+ } else if (paramObj.type == "ocivault") {
973
+
974
+ paramMap.set('ocidvault', paramObj.value);
975
+ if (!(configProvider == 'ociobject' || configProvider == 'ocivault'))
976
+ credential = null;
977
+ const hookFn = registeredConfigProviderHooks['ocivault'];
978
+ if (hookFn == undefined)
979
+ errors.throwErr(errors.ERR_REGISTER_HOOKFN_CONFIGPROVIDER, 'ocivault');
980
+ const args = {};
981
+ args.credential = credential;
982
+ args.paramMap = paramMap;
983
+ const vaultReturn = await hookFn(args);
984
+ const paramValue = vaultReturn[0];
985
+ return paramValue;
986
+ } else {
987
+ errors.throwErr(errors.ERR_CONFIG_PROVIDER_PARAM_TYPE, 'password/wallet_location');
988
+ }
989
+ }
891
990
  //-----------------------------------------------------------------------------
892
991
  // _checkConfigProvider()
893
992
  //
894
- // Look for the config provider in the connection string and retreives
993
+ // Look for the config provider in the connection string and retrieves
895
994
  // object stored in the config Provider.
896
995
  // Returns object based on precedence between input object and the one retrieved
897
996
  // from Config Provider.
898
997
  //-----------------------------------------------------------------------------
899
998
  async function _checkConfigProvider(options) {
900
999
  // Time for Cache entries to be deleted in milliseconds
901
- const cacheEntriesDuration = settings.configProviderCacheTimeout * 1000;
902
- let secondOpts;
1000
+ let cacheEntriesDuration = settings.configProviderCacheTimeout * 1000;
1001
+ let secondOpts, cachedConfigEntry;
903
1002
  const url = options.connectString || options.connectionString;
904
1003
  if (!url)
905
1004
  return options;
906
1005
 
907
- if (configProviderCache && configProviderCache.has(url) && ((Date.now() - configProviderCache.get(url).timeAdded) < cacheEntriesDuration)) {
908
- const cacheOpts1 = configProviderCache.get(url).cacheOpts;
909
- secondOpts = { ...cacheOpts1};
1006
+ if (configProviderCache && (cachedConfigEntry = configProviderCache.get(url))) {
1007
+ const config = cachedConfigEntry.cacheOpts;
1008
+ if (config.configTTL)
1009
+ cacheEntriesDuration = config.configTTL * 1000;
910
1010
 
911
- //deobfuscate password
912
- if (secondOpts.password)
913
- secondOpts.password = protocolUtil.getDeobfuscatedValue(secondOpts.password.value, secondOpts.password.obfuscatedValue);
1011
+ if ((Date.now() - cachedConfigEntry.timeAdded) < cacheEntriesDuration) {
1012
+ secondOpts = { ...config};
914
1013
 
915
- //deobfuscate walletContent
916
- if (secondOpts.walletContent)
917
- secondOpts.walletContent = protocolUtil.getDeobfuscatedValue(secondOpts.walletContent.value, secondOpts.walletContent.obfuscatedValue);
1014
+ //deobfuscate password
1015
+ if (secondOpts.password)
1016
+ secondOpts.password = protocolUtil.getDeobfuscatedValue(secondOpts.password.value, secondOpts.password.obfuscatedValue);
918
1017
 
919
- } else {
1018
+ //deobfuscate walletContent
1019
+ if (secondOpts.walletContent)
1020
+ secondOpts.walletContent = protocolUtil.getDeobfuscatedValue(secondOpts.walletContent.value, secondOpts.walletContent.obfuscatedValue);
1021
+ }
1022
+ }
1023
+ if (!secondOpts) {
920
1024
  let parsedUrl = url;
921
1025
  let urlExtendedPart;
922
1026
  const baseRegex = new RegExp("^config-(?<provider>[A-Za-z0-9]+)(://)(?<provider_arg>[^?]+)");
@@ -928,23 +1032,27 @@ async function _checkConfigProvider(options) {
928
1032
  if (match) {
929
1033
  const provider = match.groups.provider;
930
1034
  const provider_arg = match.groups.provider_arg;
931
- let configPckg;
932
- try {
933
- configPckg = require('./configProviders/' + provider);
934
- } catch (err) {
935
- errors.throwErr(errors.ERR_CONFIG_PROVIDER_NOT_SUPPORTED, provider);
936
- }
937
- const configProvider = new configPckg(provider_arg, urlExtendedPart);
938
- try {
939
- configProvider.init();
940
- } catch (err) {
941
- errors.throwErr(errors.ERR_CONFIG_PROVIDER_LOAD_FAILED, err.message);
942
- }
1035
+ const hookFn = registeredConfigProviderHooks[provider];
1036
+ if (hookFn == undefined)
1037
+ errors.throwErr(errors.ERR_REGISTER_HOOKFN_CONFIGPROVIDER, provider);
1038
+ const args = {};
1039
+ args.provider_arg = provider_arg;
1040
+ args.urlExtendedPart = urlExtendedPart;
1041
+
943
1042
  try {
1043
+ // hookFn returns an array with first element as the config stored in the configProvider
1044
+ // second being the credential to the configProvider
1045
+ const configProviderReturn = await hookFn(args);
1046
+ secondOpts = configProviderReturn[0];
944
1047
  if (!configProviderCache) {
945
1048
  configProviderCache = new Map();
946
1049
  }
947
- secondOpts = await configProvider.returnConfig();
1050
+ if (!secondOpts) {
1051
+ errors.throwErr(errors.ERR_CONFIG_PROVIDER_FAILED_TO_RETRIEVE_CONFIG, 'no configuration found in ' + provider);
1052
+ }
1053
+ if (provider != 'azure')
1054
+ secondOpts = await _setConfigParameters(secondOpts, configProviderReturn[1], provider);
1055
+
948
1056
  // obfuscate password & walletcontent and store config in the cache
949
1057
  const cacheOpts = { ...secondOpts};
950
1058
  if (secondOpts.password)
@@ -1057,6 +1165,19 @@ function registerProcessConfigurationHook(fn) {
1057
1165
  registeredHooks.push(fn);
1058
1166
  }
1059
1167
 
1168
+ //-----------------------------------------------------------------------------
1169
+ // registerConfigurationProviderHook()
1170
+ //
1171
+ // Registers Configuration Provider plugin modules and registered modules will
1172
+ // be called and executed during pool and standalone connection creation.
1173
+ //-----------------------------------------------------------------------------
1174
+ function registerConfigurationProviderHook(configProvider, fn) {
1175
+ errors.assertArgCount(arguments, 2, 2);
1176
+ errors.assertParamValue(typeof fn === 'function', 1);
1177
+ errors.assertParamValue(typeof configProvider === 'string', 1);
1178
+ registeredConfigProviderHooks[configProvider] = fn;
1179
+ }
1180
+
1060
1181
  // module exports
1061
1182
  module.exports = {
1062
1183
 
@@ -1088,6 +1209,7 @@ module.exports = {
1088
1209
  getPool,
1089
1210
  initOracleClient,
1090
1211
  registerProcessConfigurationHook,
1212
+ registerConfigurationProviderHook,
1091
1213
  shutdown: nodbUtil.callbackify(nodbUtil.wrapFn(shutdown)),
1092
1214
  startup: nodbUtil.callbackify(nodbUtil.wrapFn(startup)),
1093
1215