oracledb 6.5.1 → 6.7.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 (73) hide show
  1. package/README.md +2 -2
  2. package/build/Release/oracledb-6.7.0-darwin-arm64.node +0 -0
  3. package/build/Release/oracledb-6.7.0-darwin-arm64.node-buildinfo.txt +1 -0
  4. package/build/Release/oracledb-6.7.0-darwin-x64.node +0 -0
  5. package/build/Release/oracledb-6.7.0-darwin-x64.node-buildinfo.txt +1 -0
  6. package/build/Release/oracledb-6.7.0-js-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-6.7.0-linux-arm64.node +0 -0
  8. package/build/Release/oracledb-6.7.0-linux-arm64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.7.0-linux-x64.node +0 -0
  10. package/build/Release/oracledb-6.7.0-linux-x64.node-buildinfo.txt +1 -0
  11. package/build/Release/oracledb-6.7.0-win32-x64.node +0 -0
  12. package/build/Release/oracledb-6.7.0-win32-x64.node-buildinfo.txt +1 -0
  13. package/examples/README.md +4 -0
  14. package/lib/configProviders/azure.js +178 -0
  15. package/lib/configProviders/base.js +85 -0
  16. package/lib/configProviders/ociobject.js +211 -0
  17. package/lib/connection.js +97 -14
  18. package/lib/constants.js +1 -0
  19. package/lib/errors.js +68 -6
  20. package/lib/impl/aqQueue.js +2 -1
  21. package/lib/impl/base.js +45 -0
  22. package/lib/impl/connection.js +53 -0
  23. package/lib/impl/datahandlers/constants.js +3 -1
  24. package/lib/impl/datahandlers/vector.js +24 -9
  25. package/lib/impl/lob.js +29 -1
  26. package/lib/impl/pool.js +15 -0
  27. package/lib/impl/resultset.js +28 -2
  28. package/lib/impl/sodaCollection.js +2 -1
  29. package/lib/impl/sodaDatabase.js +2 -1
  30. package/lib/impl/sodaDocCursor.js +2 -1
  31. package/lib/impl/sodaOperation.js +2 -1
  32. package/lib/lob.js +55 -3
  33. package/lib/oracledb.js +246 -7
  34. package/lib/pool.js +14 -5
  35. package/lib/settings.js +1 -0
  36. package/lib/thin/connection.js +304 -29
  37. package/lib/thin/dbObject.js +4 -0
  38. package/lib/thin/lob.js +193 -1
  39. package/lib/thin/pool.js +18 -0
  40. package/lib/thin/protocol/capabilities.js +2 -0
  41. package/lib/thin/protocol/constants.js +29 -1
  42. package/lib/thin/protocol/messages/auth.js +12 -6
  43. package/lib/thin/protocol/messages/base.js +3 -0
  44. package/lib/thin/protocol/messages/index.js +5 -1
  45. package/lib/thin/protocol/messages/lobOp.js +17 -5
  46. package/lib/thin/protocol/messages/sessionRelease.js +1 -0
  47. package/lib/thin/protocol/messages/transactionChangeState.js +99 -0
  48. package/lib/thin/protocol/messages/transactionSwitch.js +139 -0
  49. package/lib/thin/protocol/messages/withData.js +21 -6
  50. package/lib/thin/protocol/protocol.js +23 -0
  51. package/lib/thin/sqlnet/connStrategy.js +9 -1
  52. package/lib/thin/sqlnet/constants.js +2 -0
  53. package/lib/thin/sqlnet/navNodes.js +14 -2
  54. package/lib/thin/sqlnet/networkSession.js +11 -10
  55. package/lib/thin/sqlnet/ntTcp.js +1 -1
  56. package/lib/thin/sqlnet/paramParser.js +87 -50
  57. package/lib/thin/sqlnet/sessionAtts.js +14 -2
  58. package/lib/thin/util.js +4 -3
  59. package/lib/traceHandler.js +133 -0
  60. package/lib/transformer.js +1 -2
  61. package/lib/types.js +1 -1
  62. package/lib/util.js +213 -35
  63. package/lib/version.js +2 -2
  64. package/package.json +1 -1
  65. package/build/Release/oracledb-6.5.1-darwin-x64.node +0 -0
  66. package/build/Release/oracledb-6.5.1-darwin-x64.node-buildinfo.txt +0 -1
  67. package/build/Release/oracledb-6.5.1-js-buildinfo.txt +0 -1
  68. package/build/Release/oracledb-6.5.1-linux-arm64.node +0 -0
  69. package/build/Release/oracledb-6.5.1-linux-arm64.node-buildinfo.txt +0 -1
  70. package/build/Release/oracledb-6.5.1-linux-x64.node +0 -0
  71. package/build/Release/oracledb-6.5.1-linux-x64.node-buildinfo.txt +0 -1
  72. package/build/Release/oracledb-6.5.1-win32-x64.node +0 -0
  73. package/build/Release/oracledb-6.5.1-win32-x64.node-buildinfo.txt +0 -1
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
- # node-oracledb version 6.5.1
1
+ # node-oracledb version 6.7.0
2
2
 
3
3
  The node-oracledb add-on for Node.js powers high performance Oracle Database
4
4
  applications. Applications can be written in TypeScript, or directly in
5
5
  JavaScript.
6
6
 
7
- Use node-oracledb 6.5.1 to connect Node.js 14.6, or later, to Oracle
7
+ Use node-oracledb 6.7.0 to connect Node.js 14.6, or later, to Oracle
8
8
  Database. Older versions of node-oracledb may work with older versions of
9
9
  Node.js.
10
10
 
@@ -0,0 +1 @@
1
+ oracledb-6.7.0-darwin-arm64.node v22.2.0 29e0b9cfc2f22f3df1e6b746323fb5f1f95ba492 3f4e00888d20e313374cfe0fb148de2180eaf93f Thu, 07 Nov 2024 06:28:34 GMT
@@ -0,0 +1 @@
1
+ oracledb-6.7.0-darwin-x64.node v20.11.1 29e0b9cfc2f22f3df1e6b746323fb5f1f95ba492 3f4e00888d20e313374cfe0fb148de2180eaf93f Thu, 07 Nov 2024 06:21:29 GMT
@@ -0,0 +1 @@
1
+ 29e0b9cfc2f22f3df1e6b746323fb5f1f95ba492
@@ -0,0 +1 @@
1
+ oracledb-6.7.0-linux-arm64.node v18.20.4 29e0b9cfc2f22f3df1e6b746323fb5f1f95ba492 3f4e00888d20e313374cfe0fb148de2180eaf93f Thu, 07 Nov 2024 16:48:12 GMT
@@ -0,0 +1 @@
1
+ oracledb-6.7.0-linux-x64.node v16.20.2 29e0b9cfc2f22f3df1e6b746323fb5f1f95ba492 3f4e00888d20e313374cfe0fb148de2180eaf93f Thu, 07 Nov 2024 16:47:47 GMT
@@ -0,0 +1 @@
1
+ oracledb-6.7.0-win32-x64.node v18.16.0 29e0b9cfc2f22f3df1e6b746323fb5f1f95ba492 3f4e00888d20e313374cfe0fb148de2180eaf93f Thu, 07 Nov 2024 16:23:47 GMT
@@ -65,6 +65,7 @@ File Name | Description
65
65
  [`aqraw.js`](aqraw.js) | Basic Oracle Advanced Queuing (AQ) example passing text messages
66
66
  [`aqutil.js`](aqutil.js) | Common file to setup the user credentials for all the Advanced Queuing (AQ) examples.
67
67
  [`blobhttp.js`](blobhttp.js) | Simple web app that streams an image
68
+ [`azureConfigProvider.js`](azureConfigProvider.js) | Show how to connect to an Oracle Database using Azure Configuration Providers
68
69
  [`calltimeout.js`](calltimeout.js) | Shows how to cancel a SQL statement if it doesn't complete in a specified time
69
70
  [`connect.js`](connect.js) | Basic example for creating a standalone (non-pooled) connection
70
71
  [`connectionpool.js`](connectionpool.js) | Basic example creating a pool of connections
@@ -101,11 +102,13 @@ File Name | Description
101
102
  [`lobstream2.js`](lobstream2.js) | Shows using Stream data events to fetch a CLOB
102
103
  [`lowercasecolumns.js`](lowercasecolumns.js) | Shows how a type handler can convert column names to lower case
103
104
  [`metadata.js`](metadata.js) | Shows the metadata available after executing SELECT statements
105
+ [`ociConfigProvider.js`](ociConfigProvider.js) | Show how to connect to an Oracle Database using OCI Configuration Providers
104
106
  [`plsqlarray.js`](plsqlarray.js) | Examples of binding PL/SQL "INDEX BY" tables
105
107
  [`plsqlfunc.js`](plsqlfunc.js) | How to call a PL/SQL function
106
108
  [`plsqlproc.js`](plsqlproc.js) | How to call a PL/SQL procedure
107
109
  [`plsqlrecord.js`](plsqlrecord.js) | Shows binding of PL/SQL RECORDS
108
110
  [`plsqlvarrayrecord.js`](plsqlvarrayrecord.js) | Shows binding a VARRAY of RECORD in PL/SQL
111
+ [`plsqlrowtype.js`](plsqlrowtype.js) | Shows binding of PL/SQL %ROWTYPE object
109
112
  [`raw.js`](raw.js) | Shows using a Buffer to insert and select a RAW
110
113
  [`refcursor.js`](refcursor.js) | Shows using a ResultSet to fetch rows from a REF CURSOR
111
114
  [`refcursortoquerystream.js`](refcursortoquerystream.js) | Converts a REF CURSOR returned from `execute()` to a query stream.
@@ -134,3 +137,4 @@ File Name | Description
134
137
  [`vectortype2.js`](vectortype2.js) | Insert data into VECTOR columns and verify vector operations.
135
138
  [`version.js`](version.js) | Shows the node-oracledb version attributes
136
139
  [`webapp.js`](webapp.js) | A simple web application using a connection pool
140
+ [`xmltypeInDbObject.js`](xmltypeInDbObject.js) | Work with XMLType data in DbObject (Thin mode only)
@@ -0,0 +1,178 @@
1
+ // Copyright (c) 2024, Oracle and/or its affiliates.
2
+
3
+ //-----------------------------------------------------------------------------
4
+ //
5
+ // This software is dual-licensed to you under the Universal Permissive License
6
+ // (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
7
+ // 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
8
+ // either license.
9
+ //
10
+ // If you elect to accept the software under the Apache License, Version 2.0,
11
+ // the following applies:
12
+ //
13
+ // Licensed under the Apache License, Version 2.0 (the "License");
14
+ // you may not use this file except in compliance with the License.
15
+ // You may obtain a copy of the License at
16
+ //
17
+ // https://www.apache.org/licenses/LICENSE-2.0
18
+ //
19
+ // Unless required by applicable law or agreed to in writing, software
20
+ // distributed under the License is distributed on an "AS IS" BASIS,
21
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
+ // See the License for the specific language governing permissions and
23
+ // limitations under the License.
24
+ //
25
+ //-----------------------------------------------------------------------------
26
+
27
+ 'use strict';
28
+
29
+ let AppConfigurationClient;
30
+ let ClientSecretCredential, ClientCertificateCredential, ChainedTokenCredential, ManagedIdentityCredential, EnvironmentCredential;
31
+ const errors = require("../errors.js");
32
+ const { base } = require("./base.js");
33
+
34
+ class AzureProvider extends base {
35
+ constructor(provider_arg, urlExtendedPart) {
36
+ super(urlExtendedPart);
37
+ this._addParam("appconfigname", provider_arg);
38
+ }
39
+
40
+ //---------------------------------------------------------------------------
41
+ // init()
42
+ //
43
+ // Require/import modules from Azure SDK
44
+ //---------------------------------------------------------------------------
45
+ init() {
46
+ ({ AppConfigurationClient } = require("@azure/app-configuration"));
47
+ ({ ClientSecretCredential, ClientCertificateCredential, ChainedTokenCredential, ManagedIdentityCredential, EnvironmentCredential } = require("@azure/identity"));
48
+ }
49
+
50
+ //---------------------------------------------------------------------------
51
+ // _withChainedTokenCredential()
52
+ //
53
+ // Use of ChainedTokenCredential class which provides the ability to link
54
+ // together multiple credential instances to be tried sequentially when authenticating.
55
+ // Default authentication to try when no authentication parameter is given by the user
56
+ //---------------------------------------------------------------------------
57
+ _withChainedTokenCredential() {
58
+ const tokens = [];
59
+ if ((this.paramMap.get("azure_client_secret")))
60
+ tokens.push(new ClientSecretCredential(this.paramMap.get("azure_tenant_id"), this.paramMap.get("azure_client_id"), this.paramMap.get("azure_client_secret")));
61
+ if ((this.paramMap.get("azure_client_certificate_path")))
62
+ tokens.push(new ClientCertificateCredential(this.paramMap.get("azure_tenant_id"), this.paramMap.get("azure_client_id"), this.paramMap.get("azure_client_certificate_path")));
63
+ if ((this.paramMap.get('azure_managed_identity_client_id')))
64
+ tokens.push(this.paramMap.get('azure_managed_identity_client_id'));
65
+ tokens.push(new EnvironmentCredential());
66
+ const credential = new ChainedTokenCredential(...tokens);
67
+ return credential;
68
+ }
69
+
70
+ //---------------------------------------------------------------------------
71
+ // _returnCredential()
72
+ //
73
+ // Returns credential to access Azure Config Store on the basis of
74
+ // authentication parameters given by the user.
75
+ //---------------------------------------------------------------------------
76
+ _returnCredential() {
77
+ let auth = null;
78
+ if (this.paramMap.get('authentication')) {
79
+ auth = this.paramMap.get('authentication').toUpperCase();
80
+ }
81
+ if (auth && !(auth == 'AZURE_DEFAULT')) {
82
+ // do the given authentication
83
+ if (auth == 'AZURE_SERVICE_PRINCIPAL') {
84
+ if (this.paramMap.get("azure_client_certificate_path"))
85
+ return new ClientCertificateCredential(this.paramMap.get("azure_tenant_id"), this.paramMap.get("azure_client_id"), this.paramMap.get("azure_client_certificate_path"));
86
+ else if (this.paramMap.get("azure_client_secret"))
87
+ return new ClientSecretCredential(this.paramMap.get("azure_tenant_id"), this.paramMap.get("azure_client_id"), this.paramMap.get("azure_client_secret"));
88
+ else
89
+ errors.throwErr(errors.ERR_AZURE_SERVICE_PRINCIPAL_AUTH_FAILED);
90
+ } else if (auth == 'AZURE_MANAGED_IDENTITY') {
91
+ return new ManagedIdentityCredential(this.paramMap.get('azure_managed_identity_client_id'));
92
+ } else {
93
+ errors.throwErr(errors.ERR_AZURE_CONFIG_PROVIDER_AUTH_FAILED, auth);
94
+ }
95
+ } else {
96
+ //return default token credential
97
+ return this._withChainedTokenCredential();
98
+ }
99
+ }
100
+
101
+ //---------------------------------------------------------------------------
102
+ // _getConfigurationSetting()
103
+ //
104
+ // Get configuration setting from the config provider given a key
105
+ //and an optional label
106
+ //---------------------------------------------------------------------------
107
+ async _getConfigurationSetting(client, key, label) {
108
+ return await client.getConfigurationSetting({ key: key, label: label });
109
+
110
+ }
111
+
112
+ async returnConfig() {
113
+ const configObject = {};
114
+ const label = this.paramMap.get("label");
115
+ this.credential = this._returnCredential();
116
+ // azure config store
117
+ const client = new AppConfigurationClient(
118
+ "https://" + this.paramMap.get("appconfigname"), // ex: <https://<your appconfig resource>.azconfig.io>
119
+ this.credential
120
+ );
121
+ // retrieve connect_description
122
+ configObject.connectString = (await this._getConfigurationSetting(client, this.paramMap.get("key") + 'connect_descriptor', label)).value;
123
+
124
+ // retrieve node-oracledb parameters
125
+ try {
126
+ const params = (await this._getConfigurationSetting(client, this.paramMap.get("key") + 'node-oracledb', label)).value;
127
+ const obj = JSON.parse(params);
128
+ for (const key in obj) {
129
+ var val = obj[key];
130
+ configObject[key] = val;
131
+ }
132
+ } catch {
133
+ configObject['node-oracledb'] = null;
134
+ }
135
+ try {
136
+ // retrieve user
137
+ configObject.user = (await this._getConfigurationSetting(client, this.paramMap.get("key") + 'user', label)).value;
138
+ } catch {
139
+ configObject.user = null;
140
+ }
141
+ //retrieve password
142
+ configObject.password = await this.retrieveParamValueFromVault(client, label, 'password');
143
+ // retrieve wallet_location
144
+ configObject.walletContent = await this.retrieveParamValueFromVault(client, label, 'wallet_location');
145
+ if (configObject.walletContent) {
146
+ //only Pem file supported
147
+ if (!this.isPemFile(configObject.walletContent))
148
+ errors.throwErr(errors.ERR_WALLET_TYPE_NOT_SUPPORTED);
149
+ }
150
+ return configObject;
151
+ }
152
+ async retrieveParamValueFromVault(client, label, param) {
153
+ let paramJson = null;
154
+ try {
155
+ paramJson = await this._getConfigurationSetting(client, this.paramMap.get("key") + param, label);
156
+ } catch {
157
+ return null;
158
+ }
159
+ if (paramJson) {
160
+ let obj;
161
+ try {
162
+ obj = JSON.parse(paramJson.value);
163
+ } catch {
164
+ obj = paramJson.value;
165
+ }
166
+ if (obj.uri) {
167
+ const { SecretClient } = require("@azure/keyvault-secrets");
168
+ const vault_detail = await this._parsePwd(obj.uri);
169
+ const client1 = new SecretClient(vault_detail[0], this.credential);
170
+ return (await client1.getSecret(vault_detail[1])).value;
171
+ } else {
172
+ return paramJson.value;
173
+ }
174
+ }
175
+
176
+ }
177
+ }
178
+ module.exports = AzureProvider;
@@ -0,0 +1,85 @@
1
+ // Copyright (c) 2024, Oracle and/or its affiliates.
2
+
3
+ //-----------------------------------------------------------------------------
4
+ //
5
+ // This software is dual-licensed to you under the Universal Permissive License
6
+ // (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
7
+ // 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
8
+ // either license.
9
+ //
10
+ // If you elect to accept the software under the Apache License, Version 2.0,
11
+ // the following applies:
12
+ //
13
+ // Licensed under the Apache License, Version 2.0 (the "License");
14
+ // you may not use this file except in compliance with the License.
15
+ // You may obtain a copy of the License at
16
+ //
17
+ // https://www.apache.org/licenses/LICENSE-2.0
18
+ //
19
+ // Unless required by applicable law or agreed to in writing, software
20
+ // distributed under the License is distributed on an "AS IS" BASIS,
21
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
+ // See the License for the specific language governing permissions and
23
+ // limitations under the License.
24
+ //
25
+ //-----------------------------------------------------------------------------
26
+
27
+ 'use strict';
28
+
29
+ const pemHeaders = [
30
+ '-----BEGIN CERTIFICATE-----',
31
+ '-----BEGIN PUBLIC KEY-----',
32
+ '-----BEGIN PRIVATE KEY-----',
33
+ '-----BEGIN RSA PRIVATE KEY-----',
34
+ '-----BEGIN DSA PRIVATE KEY-----',
35
+ '-----BEGIN EC PRIVATE KEY-----',
36
+ '-----BEGIN ENCRYPTED PRIVATE KEY-----'
37
+ ];
38
+ const pemFooters = [
39
+ '-----END CERTIFICATE-----',
40
+ '-----END PUBLIC KEY-----',
41
+ '-----END PRIVATE KEY-----',
42
+ '-----END RSA PRIVATE KEY-----',
43
+ '-----END DSA PRIVATE KEY-----',
44
+ '-----END EC PRIVATE KEY-----',
45
+ '-----END ENCRYPTED PRIVATE KEY-----'
46
+ ];
47
+ class base {
48
+ constructor(url) {
49
+ const params = new URLSearchParams(url);
50
+ this.paramMap = new URLSearchParams([...params].map(([key, value]) => [key.toLowerCase(), value])); //parse the extended part and store parameters in Map
51
+ }
52
+
53
+ isPemFile(content) {
54
+ //remove any line breaks at the end of the content
55
+ content = content.trim();
56
+ return pemHeaders.some(header => content.includes(header)) &&
57
+ pemFooters.some(footer => content.endsWith(footer));
58
+ }
59
+
60
+ //---------------------------------------------------------------------------
61
+ // _addParam()
62
+ // Adds key,value pairs to the Map
63
+ //---------------------------------------------------------------------------
64
+ _addParam(key, value) {
65
+ const aliasKeyName = key.toLowerCase();
66
+ this.paramMap.set(aliasKeyName, value);
67
+ }
68
+
69
+ //---------------------------------------------------------------------------
70
+ // _parsePwd()
71
+ // Parse password which is in url format
72
+ // “uri”:“https://mykeyvault.vault.azure.net/secrets/secretkey”}
73
+ //---------------------------------------------------------------------------
74
+ _parsePwd(str) {
75
+ const vault_uri = new RegExp("(?<vault_url>https://[A-Za-z0-9._-]+)/secrets/(?<secretKey>[A-Za-z][A-Za-z0-9-]*)$", 'g');
76
+ const vault_detail = [];
77
+ for (const match of str.matchAll(vault_uri)) {
78
+ vault_detail[0] = match.groups.vault_url;
79
+ vault_detail[1] = match.groups.secretKey;
80
+ }
81
+ return vault_detail;
82
+ }
83
+
84
+ }
85
+ module.exports = {base};
@@ -0,0 +1,211 @@
1
+ // Copyright (c) 2024, Oracle and/or its affiliates.
2
+
3
+ //-----------------------------------------------------------------------------
4
+ //
5
+ // This software is dual-licensed to you under the Universal Permissive License
6
+ // (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
7
+ // 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
8
+ // either license.
9
+ //
10
+ // If you elect to accept the software under the Apache License, Version 2.0,
11
+ // the following applies:
12
+ //
13
+ // Licensed under the Apache License, Version 2.0 (the "License");
14
+ // you may not use this file except in compliance with the License.
15
+ // You may obtain a copy of the License at
16
+ //
17
+ // https://www.apache.org/licenses/LICENSE-2.0
18
+ //
19
+ // Unless required by applicable law or agreed to in writing, software
20
+ // distributed under the License is distributed on an "AS IS" BASIS,
21
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
+ // See the License for the specific language governing permissions and
23
+ // limitations under the License.
24
+ //
25
+ //-----------------------------------------------------------------------------
26
+
27
+ 'use strict';
28
+ const errors = require("../errors.js");
29
+ const { base } = require("./base.js");
30
+ const fs = require('fs');
31
+
32
+ const cloud_net_naming_pattern_oci = new RegExp("(?<objservername>[A-Za-z0-9._-]+)/n/" + "(?<namespace>[A-Za-z0-9._-]+)/b/" + "(?<bucketname>[A-Za-z0-9._-]+)/o/" + "(?<filename>[A-Za-z0-9._-]+)$");
33
+ // object to store module references that will be populated by init()
34
+ const oci = {};
35
+ class OCIProvider extends base {
36
+ constructor(provider_arg, urlExtendedPart) {
37
+ super(urlExtendedPart);
38
+ const match = provider_arg.match(cloud_net_naming_pattern_oci);
39
+ if (match) {
40
+ this._addParam("objservername", match.groups.objservername);
41
+ this._addParam("namespace", match.groups.namespace);
42
+ this._addParam("bucketname", match.groups.bucketname);
43
+ this._addParam("filename", match.groups.filename);
44
+ }
45
+ }
46
+
47
+ //---------------------------------------------------------------------------
48
+ // init()
49
+ //
50
+ // Require/import modules from ociobject
51
+ //---------------------------------------------------------------------------
52
+ init() {
53
+ oci.common = require('oci-common');
54
+ oci.objectstorage = require('oci-objectstorage');
55
+ }
56
+
57
+ //---------------------------------------------------------------------------
58
+ // _streamToString()
59
+ //
60
+ // Converts data stored in a Readable stream to string
61
+ //---------------------------------------------------------------------------
62
+ async _streamToString(stream) {
63
+ const chunks = [];
64
+ for await (const chunk of stream) {
65
+ chunks.push(Buffer.from(chunk));
66
+ }
67
+ return Buffer.concat(chunks).toString("utf-8");
68
+ }
69
+
70
+ //---------------------------------------------------------------------------
71
+ // _returnCredential()
72
+ //
73
+ // Returns credential to access OCI Object Store on the basis of
74
+ // authentication parameters given by the user.
75
+ //---------------------------------------------------------------------------
76
+ async _returnCredential() {
77
+ let provider = null;
78
+ let auth = null;
79
+ if (this.paramMap.get('authentication')) {
80
+ auth = this.paramMap.get('authentication').toUpperCase();
81
+ }
82
+ // authentication parameter given and its not OCI_DEFAULT
83
+ if (auth && !(auth == 'OCI_DEFAULT')) {
84
+ if (auth == 'OCI_INSTANCE_PRINCIPAL') {
85
+ provider = await new oci.common.InstancePrincipalsAuthenticationDetailsProviderBuilder().build();
86
+ } else if (auth == 'OCI_RESOURCE_PRINCIPAL') {
87
+ provider = await new oci.common.ResourcePrincipalAuthenticationDetailsProvider.builder();
88
+ } else
89
+ errors.throwErr(errors.ERR_OCIOBJECT_CONFIG_PROVIDER_AUTH_FAILED, auth);
90
+ } else {
91
+ // default authentication
92
+ try {
93
+ //authentication parameters exist in the configurationFile
94
+ provider = new oci.common.ConfigFileAuthenticationDetailsProvider(
95
+ this.paramMap.get("oci_profile_path"), //default path ~/.oci/config
96
+ this.paramMap.get("oci_profile")
97
+ );
98
+ } catch (err) {
99
+ //throw error for wrong profile or wrong path
100
+ if (!this.paramMap.get("oci_tenancy") || !this.paramMap.get("oci_user")) {
101
+ throw (err);
102
+ }
103
+ // authentication parameters are directly given in the connectString
104
+ const publicKey = fs.readFileSync(this.paramMap.get('oci_key_file'), { encoding: "utf8" });
105
+ const region = this.retrieveRegion(this.paramMap.get('objservername'));
106
+ provider = new oci.common.SimpleAuthenticationDetailsProvider(
107
+ this.paramMap.get("oci_tenancy"),
108
+ this.paramMap.get("oci_user"),
109
+ this.paramMap.get("oci_fingerprint"),
110
+ publicKey,
111
+ undefined,
112
+ oci.common.Region[region]
113
+ );
114
+ }
115
+ }
116
+ return provider;
117
+ }
118
+
119
+ //---------------------------------------------------------------------------
120
+ // returnConfig()
121
+ //
122
+ // Returns config stored in the OCI Object Store and
123
+ // parses and gets password field stored in OCI/Azure Vault
124
+ //---------------------------------------------------------------------------
125
+ async returnConfig() {
126
+ const configObject = {};
127
+ this.credential = await this._returnCredential();
128
+ // oci object store
129
+ const client_oci = new (oci.objectstorage).ObjectStorageClient({
130
+ authenticationDetailsProvider: this.credential
131
+ });
132
+ const getObjectRequest = {
133
+ objectName: this.paramMap.get('filename'),
134
+ bucketName: this.paramMap.get('bucketname'),
135
+ namespaceName: this.paramMap.get('namespace')
136
+ };
137
+ const getObjectResponse = await client_oci.getObject(getObjectRequest);
138
+ const resp = await this._streamToString(getObjectResponse.value);
139
+ // Entire object we get from OCI Object Storage
140
+ this.obj = JSON.parse(resp);
141
+ const userAlias = this.paramMap.get('key'); // alias
142
+ if (userAlias) {
143
+ this.obj = this.obj[userAlias];
144
+ }
145
+ const pmSection = 'node-oracledb';
146
+ const params = this.obj[pmSection];
147
+ for (const key in params) {
148
+ var val = params[key];
149
+ configObject[key] = val;
150
+ }
151
+ configObject.connectString = this.obj.connect_descriptor;
152
+ configObject.user = this.obj.user;
153
+ if (this.obj.password) {
154
+ configObject.password = await this.retrieveParamValueFromVault('password');
155
+ }
156
+ if (this.obj.wallet_location) {
157
+ // retrieve wallet_location
158
+ configObject.walletContent = await this.retrieveParamValueFromVault('wallet_location');
159
+ //only Pem file supported
160
+ if (!this.isPemFile(configObject.walletContent))
161
+ errors.throwErr(errors.ERR_WALLET_TYPE_NOT_SUPPORTED);
162
+ }
163
+ return configObject;
164
+ }
165
+
166
+ //---------------------------------------------------------------------------
167
+ // retrieveRegion(objservername)
168
+ //
169
+ // returns region from the given objservername.
170
+ //---------------------------------------------------------------------------
171
+ retrieveRegion(objservername) {
172
+ const arr = objservername.split(".");
173
+ return arr[1].toUpperCase().replaceAll('-', '_');
174
+ }
175
+
176
+ async retrieveParamValueFromVault(param) {
177
+ if (this.obj[param].type == "azurevault") {
178
+ if (this.obj[param].authentication) {
179
+ const { SecretClient } = require("@azure/keyvault-secrets");
180
+ const {ClientSecretCredential, ClientCertificateCredential} = require("@azure/identity");
181
+ if (this.obj[param].authentication.azure_client_secret)
182
+ this.credential = new ClientSecretCredential(this.obj[param].authentication.azure_tenant_id, this.obj[param].authentication.azure_client_id, this.obj[param].authentication.azure_client_secret);
183
+ else if (this.obj[param].authentication.azure_client_certificate_path)
184
+ this.credential = new ClientCertificateCredential(this.obj[param].authentication.azure_tenant_id, this.obj[param].authentication.azure_client_id, this.obj[param].authentication.azure_client_certificate_path);
185
+ else
186
+ errors.throwErr(errors.ERR_AZURE_VAULT_AUTH_FAILED);
187
+ const vault_detail = await this._parsePwd(this.obj[param].value);
188
+ const client1 = new SecretClient(vault_detail[0], this.credential);
189
+ return (await client1.getSecret(vault_detail[1])).value;
190
+ } else {
191
+ errors.throwErr(errors.ERR_AZURE_VAULT_AUTH_FAILED);
192
+ }
193
+ } else if (this.obj[param].type == "ocivault") {
194
+ const secrets = require('oci-secrets');
195
+ const secretClientOci = new secrets.SecretsClient({
196
+ authenticationDetailsProvider: this.credential
197
+ });
198
+ const getSecretBundleRequest = {
199
+ secretId: this.obj[param].value
200
+ };
201
+ const getSecretBundleResponse = await secretClientOci.getSecretBundle(getSecretBundleRequest);
202
+ const base64content = getSecretBundleResponse.secretBundle.secretBundleContent.content;
203
+ // decode base64 content
204
+ const returnVal = Buffer.from(base64content, "base64").toString("utf-8");
205
+ return returnVal;
206
+ } else {
207
+ return this.obj[param];
208
+ }
209
+ }
210
+ }
211
+ module.exports = OCIProvider;