oracledb 6.7.2 → 6.8.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.
- package/LICENSE.txt +1 -1
- package/NOTICE.txt +1 -1
- package/README.md +2 -2
- package/build/Release/oracledb-6.8.0-darwin-arm64.node +0 -0
- package/build/Release/oracledb-6.8.0-darwin-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.8.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.8.0-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.8.0-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.8.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.8.0-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.8.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.8.0-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.8.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.8.0-win32-x64.node-buildinfo.txt +1 -0
- package/lib/connection.js +66 -2
- package/lib/dbObject.js +42 -10
- package/lib/errors.js +96 -13
- package/lib/impl/connection.js +15 -1
- package/lib/impl/datahandlers/buffer.js +92 -1
- package/lib/impl/datahandlers/constants.js +2 -0
- package/lib/impl/datahandlers/oson.js +15 -1
- package/lib/impl/datahandlers/vector.js +72 -27
- package/lib/oracledb.js +80 -4
- package/lib/settings.js +5 -1
- package/lib/thin/connection.js +13 -2
- package/lib/thin/dbObject.js +38 -7
- package/lib/thin/pool.js +7 -3
- package/lib/thin/protocol/capabilities.js +1 -1
- package/lib/thin/protocol/constants.js +2 -0
- package/lib/thin/protocol/messages/auth.js +29 -6
- package/lib/thin/protocol/messages/fastAuth.js +6 -1
- package/lib/thin/protocol/messages/withData.js +10 -1
- package/lib/thin/protocol/packet.js +1 -1
- package/lib/thin/sqlnet/ANO.js +438 -0
- package/lib/thin/sqlnet/constants.js +5 -1
- package/lib/thin/sqlnet/ezConnectResolver.js +4 -2
- package/lib/thin/sqlnet/navNodes.js +21 -2
- package/lib/thin/sqlnet/networkSession.js +88 -16
- package/lib/thin/sqlnet/ntTcp.js +50 -3
- package/lib/thin/sqlnet/packet.js +31 -4
- package/lib/thin/sqlnet/sessionAtts.js +25 -2
- package/lib/thin/util.js +3 -8
- package/lib/transformer.js +13 -2
- package/lib/types.js +220 -3
- package/lib/util.js +1 -1
- package/lib/version.js +2 -2
- package/package.json +1 -1
- package/plugins/token/extensionAzure/index.js +101 -0
- package/plugins/token/extensionOci/index.js +174 -0
- package/build/Release/oracledb-6.7.2-darwin-arm64.node +0 -0
- package/build/Release/oracledb-6.7.2-darwin-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.7.2-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.7.2-darwin-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.7.2-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.7.2-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.7.2-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.7.2-linux-x64.node +0 -0
- package/build/Release/oracledb-6.7.2-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.7.2-win32-x64.node +0 -0
- package/build/Release/oracledb-6.7.2-win32-x64.node-buildinfo.txt +0 -1
package/lib/types.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2025, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -33,6 +33,7 @@ const util = require('util');
|
|
|
33
33
|
const dbTypeByNum = new Map();
|
|
34
34
|
const dbTypeByOraTypeNum = new Map();
|
|
35
35
|
const dbTypeByColumnTypeName = new Map();
|
|
36
|
+
const MAX_UINT32 = Math.pow(2, 32) - 1;
|
|
36
37
|
|
|
37
38
|
// define class used for database types
|
|
38
39
|
class DbType {
|
|
@@ -145,7 +146,7 @@ const DB_TYPE_INTERVAL_DS = new DbType(2015,
|
|
|
145
146
|
{ oraTypeNum: 183, bufferSizeFactor: 11 });
|
|
146
147
|
const DB_TYPE_INTERVAL_YM = new DbType(2016,
|
|
147
148
|
"DB_TYPE_INTERVAL_YM", "INTERVAL YEAR TO MONTH",
|
|
148
|
-
{ oraTypeNum: 182 });
|
|
149
|
+
{ oraTypeNum: 182, bufferSizeFactor: 5 });
|
|
149
150
|
const DB_TYPE_JSON = new DbType(2027,
|
|
150
151
|
"DB_TYPE_JSON", "JSON",
|
|
151
152
|
{ oraTypeNum: 119 });
|
|
@@ -339,6 +340,219 @@ class JsonId extends Uint8Array {
|
|
|
339
340
|
}
|
|
340
341
|
}
|
|
341
342
|
|
|
343
|
+
// Represents the SparseVector.
|
|
344
|
+
// indices must be an regular Array
|
|
345
|
+
// values can be regular or typedArray.
|
|
346
|
+
class SparseVector {
|
|
347
|
+
constructor(input) {
|
|
348
|
+
this._indices = new Uint32Array(0);
|
|
349
|
+
this._values = new Float64Array(0);
|
|
350
|
+
this._numDimensions = 0;
|
|
351
|
+
|
|
352
|
+
if (!input) {
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
if (typeof input === 'object' &&
|
|
356
|
+
"numDimensions" in input &&
|
|
357
|
+
"indices" in input &&
|
|
358
|
+
"values" in input
|
|
359
|
+
) {
|
|
360
|
+
// Object has valid properties for Sparse.
|
|
361
|
+
this._fromObject(input);
|
|
362
|
+
} else if (typeof input === 'string') {
|
|
363
|
+
// initialize from string.
|
|
364
|
+
this._fromString(input);
|
|
365
|
+
} else if (this._validDenseArray(input)) {
|
|
366
|
+
// dense array
|
|
367
|
+
this._fromDense(input);
|
|
368
|
+
} else {
|
|
369
|
+
errors.throwErr(errors.ERR_VECTOR_SPARSE_INVALID_INPUT);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
_validDenseArray(value) {
|
|
374
|
+
return (value instanceof Float32Array ||
|
|
375
|
+
value instanceof Float64Array ||
|
|
376
|
+
value instanceof Int8Array || (Object.getPrototypeOf(value)
|
|
377
|
+
=== Uint8Array.prototype) || Array.isArray(value));
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Check if indexArray and valuesArray have the same length
|
|
381
|
+
static _validateLengths(indices, values) {
|
|
382
|
+
if (indices.length !== values.length) {
|
|
383
|
+
if (!(values instanceof Uint8Array)) {
|
|
384
|
+
// Skip for binary vector format
|
|
385
|
+
errors.throwErr(errors.ERR_VECTOR_SPARSE_INDICES_VALUES_NOT_EQUAL);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
_updateProperties(dims, indices, values) {
|
|
391
|
+
if (!this._validDenseArray(values)) {
|
|
392
|
+
errors.throwErr(errors.ERR_VECTOR_SPARSE_VALUES_IS_NOT_ARRAY);
|
|
393
|
+
}
|
|
394
|
+
if (!(indices instanceof Uint32Array) && !Array.isArray(indices)) {
|
|
395
|
+
errors.throwErr(errors.ERR_VECTOR_SPARSE_INDICES_IS_NOT_ARRAY);
|
|
396
|
+
}
|
|
397
|
+
SparseVector._validateLengths(indices, values);
|
|
398
|
+
if (!(typeof dims === 'number' && Number.isInteger(dims) && dims > 0)) {
|
|
399
|
+
errors.throwErr(errors.ERR_VECTOR_SPARSE_DIMS_IS_NOT_INTEGER);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
this._numDimensions = dims;
|
|
403
|
+
this._indices = indices;
|
|
404
|
+
this._values = values;
|
|
405
|
+
this._convertToTypedArrays();
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
_fromObject(input) {
|
|
409
|
+
this._updateProperties(input.numDimensions, input.indices, input.values);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
_convertToTypedArrays() {
|
|
413
|
+
// convert to typed arrays.
|
|
414
|
+
if (!(this._indices instanceof Uint32Array)) {
|
|
415
|
+
// validate elements are valid uint32 type.
|
|
416
|
+
const indices = new Uint32Array(this._indices.map((x, index) => {
|
|
417
|
+
if (typeof x !== 'number' || !Number.isInteger(x)) {
|
|
418
|
+
errors.throwErr(errors.ERR_VECTOR_SPARSE_INDICES_ELEM_IS_NOT_VALID, index);
|
|
419
|
+
}
|
|
420
|
+
if (x < 0 || x > MAX_UINT32 || x > (this.numDimensions - 1)) {
|
|
421
|
+
errors.throwErr(errors.ERR_VECTOR_SPARSE_INDICES_ELEM_IS_NOT_VALID,
|
|
422
|
+
index);
|
|
423
|
+
}
|
|
424
|
+
return x;
|
|
425
|
+
}));
|
|
426
|
+
this._indices = indices;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
this._values = Array.isArray(this._values) ? new Float64Array(this._values)
|
|
430
|
+
: this._values;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// Initialize the state using the dense array.
|
|
434
|
+
// The length of input is assumed to be same as
|
|
435
|
+
// dimensions of sparse Vector column.
|
|
436
|
+
// values will be an array even if input is a typedArray.
|
|
437
|
+
_fromDense(input) {
|
|
438
|
+
this._indices = [];
|
|
439
|
+
this._values = [];
|
|
440
|
+
|
|
441
|
+
for (let i = 0; i < input.length; i++) {
|
|
442
|
+
if (input[i] !== 0) {
|
|
443
|
+
this._indices.push(i);
|
|
444
|
+
this._values.push(input[i]);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
this._numDimensions = input.length;
|
|
448
|
+
this._convertToTypedArrays();
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// parse a string input into a sparse vector
|
|
452
|
+
_fromString(str) {
|
|
453
|
+
let data;
|
|
454
|
+
|
|
455
|
+
// verify it is a valid JSON
|
|
456
|
+
try {
|
|
457
|
+
// use simple tokenizer?
|
|
458
|
+
data = JSON.parse(str);
|
|
459
|
+
} catch (e) {
|
|
460
|
+
errors.throwErr(errors.ERR_VECTOR_SPARSE_INVALID_JSON);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// Check if data is an array with exactly 3 elements
|
|
464
|
+
if (!Array.isArray(data) || data.length !== 3) {
|
|
465
|
+
errors.throwErr(errors.ERR_VECTOR_SPARSE_INVALID_STRING);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
const [dims, indices, values] = data;
|
|
469
|
+
this._updateProperties(dims, indices, values);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// Internal method to create an instance
|
|
473
|
+
static create(sparseValue) {
|
|
474
|
+
SparseVector._validateLengths(sparseValue.indices, sparseValue.values);
|
|
475
|
+
const instance = Object.create(this.prototype);
|
|
476
|
+
instance._numDimensions = sparseValue.numDimensions;
|
|
477
|
+
instance._indices = sparseValue.indices;
|
|
478
|
+
instance._values = sparseValue.values;
|
|
479
|
+
return instance;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
get indices() {
|
|
483
|
+
return this._indices;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
get values() {
|
|
487
|
+
return this._values;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
get numDimensions() {
|
|
491
|
+
return this._numDimensions;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
toJSON() {
|
|
495
|
+
return {
|
|
496
|
+
numDimensions: this._numDimensions,
|
|
497
|
+
indices: this._indices,
|
|
498
|
+
values: this._values,
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// It always constructs a typedArray.
|
|
503
|
+
_createEmptyArray(input, len) {
|
|
504
|
+
if (Array.isArray(input)) {
|
|
505
|
+
return new Float64Array(len);
|
|
506
|
+
} else {
|
|
507
|
+
// same typedArray of input type.
|
|
508
|
+
return new input.constructor(len);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
// Convert sparse vector to a dense vector
|
|
513
|
+
// It returns typed array.
|
|
514
|
+
dense() {
|
|
515
|
+
if (this._numDimensions === 0) {
|
|
516
|
+
return null;
|
|
517
|
+
}
|
|
518
|
+
const dense = this._createEmptyArray(this._values, this._numDimensions);
|
|
519
|
+
this._indices.forEach((index, i) => {
|
|
520
|
+
dense[index] = this._values[i];
|
|
521
|
+
});
|
|
522
|
+
return dense;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// Interval Year-to-Month Class
|
|
527
|
+
class IntervalYM {
|
|
528
|
+
constructor(obj) {
|
|
529
|
+
if (obj) {
|
|
530
|
+
errors.assertParamPropInt(obj, 1, "years");
|
|
531
|
+
errors.assertParamPropInt(obj, 1, "months");
|
|
532
|
+
}
|
|
533
|
+
this.years = obj?.years || 0;
|
|
534
|
+
this.months = obj?.months || 0;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
// Interval Day-to-Second Class
|
|
539
|
+
class IntervalDS {
|
|
540
|
+
constructor(obj) {
|
|
541
|
+
if (obj) {
|
|
542
|
+
errors.assertParamPropInt(obj, 1, "days");
|
|
543
|
+
errors.assertParamPropInt(obj, 1, "hours");
|
|
544
|
+
errors.assertParamPropInt(obj, 1, "minutes");
|
|
545
|
+
errors.assertParamPropInt(obj, 1, "seconds");
|
|
546
|
+
errors.assertParamPropInt(obj, 1, "fseconds");
|
|
547
|
+
}
|
|
548
|
+
this.days = obj?.days || 0;
|
|
549
|
+
this.hours = obj?.hours || 0;
|
|
550
|
+
this.minutes = obj?.minutes || 0;
|
|
551
|
+
this.seconds = obj?.seconds || 0;
|
|
552
|
+
this.fseconds = obj?.fseconds || 0;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
342
556
|
module.exports = {
|
|
343
557
|
DbType,
|
|
344
558
|
DB_TYPE_BFILE,
|
|
@@ -376,5 +590,8 @@ module.exports = {
|
|
|
376
590
|
getTypeByColumnTypeName,
|
|
377
591
|
getTypeByNum,
|
|
378
592
|
getTypeByOraTypeNum,
|
|
379
|
-
JsonId
|
|
593
|
+
JsonId,
|
|
594
|
+
SparseVector,
|
|
595
|
+
IntervalYM,
|
|
596
|
+
IntervalDS
|
|
380
597
|
};
|
package/lib/util.js
CHANGED
|
@@ -501,7 +501,7 @@ function isVectorValue(value) {
|
|
|
501
501
|
return (value instanceof Float32Array ||
|
|
502
502
|
value instanceof Float64Array ||
|
|
503
503
|
value instanceof Int8Array || (Object.getPrototypeOf(value)
|
|
504
|
-
=== Uint8Array.prototype));
|
|
504
|
+
=== Uint8Array.prototype) || value instanceof types.SparseVector);
|
|
505
505
|
}
|
|
506
506
|
|
|
507
507
|
//-----------------------------------------------------------------------------
|
package/lib/version.js
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Copyright (c) 2025, 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
|
+
'use strict';
|
|
27
|
+
const oracledb = require('oracledb');
|
|
28
|
+
const msal = require('@azure/msal-node');
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
async function getToken(params) {
|
|
32
|
+
switch (params.authType.toLowerCase()) {
|
|
33
|
+
case 'azureserviceprincipal':
|
|
34
|
+
return await servicePrincipalCredentials(params);
|
|
35
|
+
default:
|
|
36
|
+
throwErr(`Invalid authentication type ${params.authType} in extensionAzure plugins.`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
//---------------------------------------------------------------------------
|
|
41
|
+
// throwErr()
|
|
42
|
+
//---------------------------------------------------------------------------
|
|
43
|
+
function throwErr(message) {
|
|
44
|
+
throw new Error(message);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//---------------------------------------------------------------------------
|
|
48
|
+
// Returns the access token for authentication as a service principal. This
|
|
49
|
+
// authentication method requires a client ID along with either a secret or
|
|
50
|
+
// certificate. These values may be provided as config parameters read by
|
|
51
|
+
// the Azure SDK.
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
async function servicePrincipalCredentials(params) {
|
|
54
|
+
const clientId = params.clientId ??
|
|
55
|
+
throwErr("Token based authentication config parameter clientId is missing for azureServicePrincipal in extensionAzure plugins.");
|
|
56
|
+
const authority = params.authority ??
|
|
57
|
+
throwErr("Token based authentication config parameter authority is missing for azureServicePrincipal in extensionAzure plugins.");
|
|
58
|
+
const clientSecret = params.clientSecret ??
|
|
59
|
+
throwErr("Token based authentication config parameter clientSecret is missing for azureServicePrincipal in extensionAzure plugins.");
|
|
60
|
+
const msalConfig = {
|
|
61
|
+
auth: {
|
|
62
|
+
clientId: clientId,
|
|
63
|
+
authority: authority,
|
|
64
|
+
clientSecret: clientSecret,
|
|
65
|
+
},
|
|
66
|
+
system: {
|
|
67
|
+
// Use it while generating azure tokens behind proxy
|
|
68
|
+
// Otherwise can remove this option
|
|
69
|
+
networkClient: params.proxy,
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
if (!msalConfig.system.networkClient) {
|
|
74
|
+
delete msalConfig.system.networkClient;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const scopes = params.scopes ??
|
|
78
|
+
throwErr("Token based authentication config parameter scopes is missing for azureServicePrincipal in extensionAzure plugins.");
|
|
79
|
+
const tokenRequest = {
|
|
80
|
+
scopes: [scopes],
|
|
81
|
+
};
|
|
82
|
+
const cca = new msal.ConfidentialClientApplication(msalConfig);
|
|
83
|
+
const authResponse = await cca.acquireTokenByClientCredential(tokenRequest);
|
|
84
|
+
return authResponse.accessToken;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// hookFn()
|
|
89
|
+
// hookFn is registered to driver while loading plugins.
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
|
|
92
|
+
function hookFn(options) {
|
|
93
|
+
if (options.tokenAuthConfigAzure) {
|
|
94
|
+
// eslint-disable-next-line no-unused-vars
|
|
95
|
+
options.accessToken = async function callbackFn(refresh, config) {
|
|
96
|
+
return await getToken(config);
|
|
97
|
+
};
|
|
98
|
+
options.accessTokenConfig = options.tokenAuthConfigAzure;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
oracledb.registerProcessConfigurationHook(hookFn);
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// Copyright (c) 2025, 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
|
+
'use strict';
|
|
27
|
+
const oracledb = require('oracledb');
|
|
28
|
+
const identitydataplane = require("oci-identitydataplane");
|
|
29
|
+
const common = require("oci-common");
|
|
30
|
+
const { generateKeyPair } = require('crypto');
|
|
31
|
+
const fs = require('fs');
|
|
32
|
+
|
|
33
|
+
async function getToken(params) {
|
|
34
|
+
switch (params.authType.toLowerCase()) {
|
|
35
|
+
case 'configfilebasedauthentication':
|
|
36
|
+
return await configFileBasedAuthentication(params);
|
|
37
|
+
case 'simpleauthentication':
|
|
38
|
+
return await simpleAuthentication(params);
|
|
39
|
+
default:
|
|
40
|
+
throwErr(`Invalid authentication type ${params.authType} in extensionOci plugins.`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//---------------------------------------------------------------------------
|
|
45
|
+
// throwErr()
|
|
46
|
+
//---------------------------------------------------------------------------
|
|
47
|
+
function throwErr(message) {
|
|
48
|
+
throw new Error(message);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
//---------------------------------------------------------------------------
|
|
52
|
+
// Generates a public-private key pair for proof of possession when token
|
|
53
|
+
// requested by this provider is presented for validation.
|
|
54
|
+
//---------------------------------------------------------------------------
|
|
55
|
+
async function _getKeyPair() {
|
|
56
|
+
return await new Promise((resolve, reject) => {
|
|
57
|
+
generateKeyPair('rsa', {
|
|
58
|
+
modulusLength: 4096,
|
|
59
|
+
publicKeyEncoding: {
|
|
60
|
+
type: 'spki',
|
|
61
|
+
format: 'pem'
|
|
62
|
+
},
|
|
63
|
+
privateKeyEncoding: {
|
|
64
|
+
type: 'pkcs8',
|
|
65
|
+
format: 'pem',
|
|
66
|
+
}
|
|
67
|
+
}, (err, publicKey, privateKey) => {
|
|
68
|
+
if (err) return reject(err);
|
|
69
|
+
resolve({publicKey, privateKey});
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
//---------------------------------------------------------------------------
|
|
75
|
+
// User defined function for reading token and private key values
|
|
76
|
+
// generated by the OCI SDK.
|
|
77
|
+
// Returns the OCI SDK's token request details object for the given
|
|
78
|
+
// config parameters, where a scope parameter specifies the
|
|
79
|
+
// scope of requested access. The request will specify a public key
|
|
80
|
+
// as being paired with a private key that the presenter of the token must
|
|
81
|
+
// prove to be in possession of.
|
|
82
|
+
//---------------------------------------------------------------------------
|
|
83
|
+
async function configFileBasedAuthentication(accessTokenConfig) {
|
|
84
|
+
const provider =
|
|
85
|
+
new common.ConfigFileAuthenticationDetailsProvider(accessTokenConfig.configFileLocation, accessTokenConfig.profile);
|
|
86
|
+
const client = new identitydataplane.DataplaneClient({authenticationDetailsProvider: provider});
|
|
87
|
+
const keyPair = await _getKeyPair();
|
|
88
|
+
const generateScopedAccessTokenDetails = {
|
|
89
|
+
scope: "urn:oracle:db::id::*",
|
|
90
|
+
publicKey: keyPair.publicKey
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const generateScopedAccessTokenRequest = {
|
|
94
|
+
generateScopedAccessTokenDetails: generateScopedAccessTokenDetails
|
|
95
|
+
};
|
|
96
|
+
const generateScopedAccessTokenResponse =
|
|
97
|
+
await client.generateScopedAccessToken(generateScopedAccessTokenRequest);
|
|
98
|
+
const obj = {
|
|
99
|
+
token: generateScopedAccessTokenResponse.securityToken.token,
|
|
100
|
+
privateKey: keyPair.privateKey
|
|
101
|
+
};
|
|
102
|
+
return obj;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
//---------------------------------------------------------------------------
|
|
106
|
+
// simpleAuthentication()
|
|
107
|
+
//---------------------------------------------------------------------------
|
|
108
|
+
async function simpleAuthentication(accessTokenConfig) {
|
|
109
|
+
const tenancy = accessTokenConfig.tenancy ??
|
|
110
|
+
throwErr("Token based authentication config parameter tenancy is missing for simpleauthentication in extensionOci plugins.");
|
|
111
|
+
const user = accessTokenConfig.user ??
|
|
112
|
+
throwErr("Token based authentication config parameter user is missing for simpleauthentication in extensionOci plugins.");
|
|
113
|
+
const fingerprint = accessTokenConfig.fingerprint ??
|
|
114
|
+
throwErr("Token based authentication config parameter fingerprint is missing for simpleauthentication in extensionOci plugins.");
|
|
115
|
+
const passphrase = accessTokenConfig.passphrase |= null; // optional
|
|
116
|
+
const privateKeyLocation = accessTokenConfig.privateKeyLocation ??
|
|
117
|
+
throwErr("Token based authentication config parameter privateKeyLocation is missing for simpleauthentication in extensionOci plugins.");
|
|
118
|
+
const privateKey = fs.readFileSync(privateKeyLocation, 'utf-8'); // ~/.oci/oci_api_key.pem
|
|
119
|
+
const regionId = accessTokenConfig.regionId ?? // ex : us-ashburn-1
|
|
120
|
+
throwErr("Token based authentication config parameter regionId is missing for simpleauthentication in extensionOci plugins.");
|
|
121
|
+
|
|
122
|
+
let region;
|
|
123
|
+
const regionsList = common.Region.values();
|
|
124
|
+
regionsList.forEach(regions => {
|
|
125
|
+
if (regions.regionId === regionId) {
|
|
126
|
+
region = regions;
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
const provider = new common.SimpleAuthenticationDetailsProvider(
|
|
131
|
+
tenancy,
|
|
132
|
+
user,
|
|
133
|
+
fingerprint,
|
|
134
|
+
privateKey,
|
|
135
|
+
passphrase,
|
|
136
|
+
region
|
|
137
|
+
);
|
|
138
|
+
const client = new identitydataplane.DataplaneClient({
|
|
139
|
+
authenticationDetailsProvider: provider
|
|
140
|
+
});
|
|
141
|
+
const keyPair = await _getKeyPair();
|
|
142
|
+
const generateScopedAccessTokenDetails = {
|
|
143
|
+
scope: "urn:oracle:db::id::*",
|
|
144
|
+
publicKey: keyPair.publicKey
|
|
145
|
+
};
|
|
146
|
+
const generateScopedAccessTokenRequest = {
|
|
147
|
+
generateScopedAccessTokenDetails: generateScopedAccessTokenDetails
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const generateScopedAccessTokenResponse = await client.generateScopedAccessToken(
|
|
151
|
+
generateScopedAccessTokenRequest
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
const obj = {
|
|
155
|
+
token: generateScopedAccessTokenResponse.securityToken.token,
|
|
156
|
+
privateKey: keyPair.privateKey
|
|
157
|
+
};
|
|
158
|
+
return obj;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
//---------------------------------------------------------------------------
|
|
162
|
+
// hookFn()
|
|
163
|
+
// hookFn will get registerd to driver while loading plugins.
|
|
164
|
+
//---------------------------------------------------------------------------
|
|
165
|
+
function hookFn(options) {
|
|
166
|
+
if (options.tokenAuthConfigOci) {
|
|
167
|
+
// eslint-disable-next-line no-unused-vars
|
|
168
|
+
options.accessToken = async function callbackFn(refresh, config) {
|
|
169
|
+
return await getToken(config);
|
|
170
|
+
};
|
|
171
|
+
options.accessTokenConfig = options.tokenAuthConfigOci;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
oracledb.registerProcessConfigurationHook(hookFn);
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
oracledb-6.7.2-darwin-arm64.node v22.2.0 d813e9fe939a65599afab84c08ad9fcea51718d5 ca4b004c471033328549f8b4d461cb5985fe2230 Fri, 07 Feb 2025 13:55:05 GMT
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
oracledb-6.7.2-darwin-x64.node v20.11.1 d813e9fe939a65599afab84c08ad9fcea51718d5 ca4b004c471033328549f8b4d461cb5985fe2230 Fri, 07 Feb 2025 14:37:36 GMT
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
d813e9fe939a65599afab84c08ad9fcea51718d5
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
oracledb-6.7.2-linux-arm64.node v20.16.0 d813e9fe939a65599afab84c08ad9fcea51718d5 ca4b004c471033328549f8b4d461cb5985fe2230 Fri, 07 Feb 2025 13:48:03 GMT
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
oracledb-6.7.2-linux-x64.node v20.16.0 d813e9fe939a65599afab84c08ad9fcea51718d5 ca4b004c471033328549f8b4d461cb5985fe2230 Fri, 07 Feb 2025 13:47:00 GMT
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
oracledb-6.7.2-win32-x64.node v20.0.0 d813e9fe939a65599afab84c08ad9fcea51718d5 ca4b004c471033328549f8b4d461cb5985fe2230 Fri, 07 Feb 2025 13:46:32 GMT
|