@harperfast/harper 5.0.2 → 5.0.3
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/bin/cliOperations.js +6 -4
- package/bin/copyDb.ts +208 -0
- package/bin/restart.js +8 -7
- package/bin/run.js +2 -1
- package/dist/bin/cliOperations.js +6 -4
- package/dist/bin/cliOperations.js.map +1 -1
- package/dist/bin/copyDb.d.ts +1 -0
- package/dist/bin/copyDb.js +197 -0
- package/dist/bin/copyDb.js.map +1 -1
- package/dist/bin/restart.js +8 -7
- package/dist/bin/restart.js.map +1 -1
- package/dist/bin/run.js +3 -1
- package/dist/bin/run.js.map +1 -1
- package/dist/resources/DatabaseTransaction.js +17 -2
- package/dist/resources/DatabaseTransaction.js.map +1 -1
- package/dist/resources/RecordEncoder.d.ts +1 -1
- package/dist/resources/RecordEncoder.js +2 -2
- package/dist/resources/RecordEncoder.js.map +1 -1
- package/dist/resources/ResourceInterface.d.ts +1 -1
- package/dist/resources/RocksIndexStore.d.ts +14 -7
- package/dist/resources/RocksIndexStore.js +19 -12
- package/dist/resources/RocksIndexStore.js.map +1 -1
- package/dist/resources/Table.js +43 -28
- package/dist/resources/Table.js.map +1 -1
- package/dist/resources/databases.js +18 -14
- package/dist/resources/databases.js.map +1 -1
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +2 -1
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +14 -12
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
- package/dist/security/certificateVerification/ocspVerification.js +1 -1
- package/dist/security/certificateVerification/ocspVerification.js.map +1 -1
- package/dist/security/keys.js +7 -7
- package/dist/security/keys.js.map +1 -1
- package/dist/server/itc/serverHandlers.js +0 -4
- package/dist/server/itc/serverHandlers.js.map +1 -1
- package/dist/utility/hdbTerms.d.ts +1 -0
- package/dist/utility/hdbTerms.js +1 -0
- package/dist/utility/hdbTerms.js.map +1 -1
- package/dist/utility/install/installer.js +11 -8
- package/dist/utility/install/installer.js.map +1 -1
- package/package.json +1 -1
- package/resources/DatabaseTransaction.ts +19 -2
- package/resources/RecordEncoder.ts +2 -2
- package/resources/ResourceInterface.ts +1 -1
- package/resources/RocksIndexStore.ts +20 -15
- package/resources/Table.ts +38 -24
- package/resources/databases.ts +29 -14
- package/resources/indexes/HierarchicalNavigableSmallWorld.ts +44 -23
- package/security/certificateVerification/ocspVerification.ts +1 -1
- package/security/keys.js +7 -7
- package/server/itc/serverHandlers.js +0 -4
- package/studio/web/assets/{index-f5-e8ocl.js → index-CxTavHFE.js} +5 -5
- package/studio/web/assets/{index-f5-e8ocl.js.map → index-CxTavHFE.js.map} +1 -1
- package/studio/web/assets/{index.lazy-CCd1vMot.js → index.lazy-CfiR1tvq.js} +2 -2
- package/studio/web/assets/{index.lazy-CCd1vMot.js.map → index.lazy-CfiR1tvq.js.map} +1 -1
- package/studio/web/assets/{profile-gjpePJuu.js → profile-C-uokAal.js} +2 -2
- package/studio/web/assets/{profile-gjpePJuu.js.map → profile-C-uokAal.js.map} +1 -1
- package/studio/web/assets/{status-CmoVx0A5.js → status-D6xeT4ss.js} +2 -2
- package/studio/web/assets/{status-CmoVx0A5.js.map → status-D6xeT4ss.js.map} +1 -1
- package/studio/web/index.html +1 -1
- package/utility/hdbTerms.ts +1 -0
- package/utility/install/installer.js +14 -10
package/resources/Table.ts
CHANGED
|
@@ -1424,23 +1424,35 @@ export function makeTable(options) {
|
|
|
1424
1424
|
*/
|
|
1425
1425
|
static evict(id, existingRecord, existingVersion) {
|
|
1426
1426
|
let entry;
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
if (
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1427
|
+
let transaction = txnForContext({ transaction: new DatabaseTransaction() }).getReadTxn();
|
|
1428
|
+
let options = { transaction };
|
|
1429
|
+
try {
|
|
1430
|
+
if (hasSourceGet || audit) {
|
|
1431
|
+
if (!existingRecord) return;
|
|
1432
|
+
entry = primaryStore.getEntry(id, options);
|
|
1433
|
+
if (!entry || !existingRecord) return;
|
|
1434
|
+
if (entry.version !== existingVersion) return;
|
|
1435
|
+
}
|
|
1436
|
+
if (hasSourceGet) {
|
|
1437
|
+
// if there is a resolution in-progress, abandon the eviction
|
|
1438
|
+
if (primaryStore.hasLock(id, entry.version)) return;
|
|
1439
|
+
}
|
|
1440
|
+
// evictions never go in the audit log, so we can not record a deletion entry for the eviction
|
|
1441
|
+
// as there is no corresponding audit entry and it would never get cleaned up. So we must simply
|
|
1442
|
+
// removed the entry entirely, but first cleanup indices
|
|
1443
|
+
if (primaryStore.ifVersion) {
|
|
1444
|
+
// lmdb
|
|
1445
|
+
primaryStore.ifVersion?.(id, existingVersion, () => {
|
|
1446
|
+
updateIndices(id, existingRecord, null);
|
|
1447
|
+
});
|
|
1448
|
+
return removeEntry(primaryStore, entry ?? primaryStore.getEntry(id), existingVersion);
|
|
1449
|
+
} else {
|
|
1450
|
+
updateIndices(id, existingRecord, null, options);
|
|
1451
|
+
return removeEntry(primaryStore, entry ?? primaryStore.getEntry(id), options);
|
|
1452
|
+
}
|
|
1453
|
+
} finally {
|
|
1454
|
+
return transaction.commit();
|
|
1436
1455
|
}
|
|
1437
|
-
primaryStore.ifVersion?.(id, existingVersion, () => {
|
|
1438
|
-
updateIndices(id, existingRecord, null);
|
|
1439
|
-
});
|
|
1440
|
-
// evictions never go in the audit log, so we can not record a deletion entry for the eviction
|
|
1441
|
-
// as there is no corresponding audit entry and it would never get cleaned up. So we must simply
|
|
1442
|
-
// removed the entry entirely
|
|
1443
|
-
return removeEntry(primaryStore, entry ?? primaryStore.getEntry(id), existingVersion);
|
|
1444
1456
|
}
|
|
1445
1457
|
/**
|
|
1446
1458
|
* This is intended to acquire a lock on a record from the whole cluster.
|
|
@@ -1951,9 +1963,10 @@ export function makeTable(options) {
|
|
|
1951
1963
|
context.lastModified = existingEntry.version;
|
|
1952
1964
|
TableResource._updateResource(this, existingEntry);
|
|
1953
1965
|
}
|
|
1954
|
-
if (precedesExistingVersion(txnTime, existingEntry, options?.nodeId)
|
|
1955
|
-
|
|
1956
|
-
|
|
1966
|
+
if (precedesExistingVersion(txnTime, existingEntry, options?.nodeId) < 0) {
|
|
1967
|
+
return;
|
|
1968
|
+
} // a newer record exists locally
|
|
1969
|
+
updateIndices(id, existingRecord, null, transaction && { transaction });
|
|
1957
1970
|
if (audit || trackDeletes) {
|
|
1958
1971
|
updateRecord(
|
|
1959
1972
|
id,
|
|
@@ -3511,6 +3524,7 @@ export function makeTable(options) {
|
|
|
3511
3524
|
// determine what index values need to be removed and added
|
|
3512
3525
|
let valuesToAdd = getIndexedValues(value, indexNulls) as any[];
|
|
3513
3526
|
let valuesToRemove = getIndexedValues(existingValue, indexNulls) as any[];
|
|
3527
|
+
let isLMDB = !!index.prefetch;
|
|
3514
3528
|
if (valuesToRemove?.length > 0) {
|
|
3515
3529
|
// put this in a conditional so we can do a faster version for new records
|
|
3516
3530
|
// determine the changes/diff from new values and old values
|
|
@@ -3527,18 +3541,18 @@ export function makeTable(options) {
|
|
|
3527
3541
|
})
|
|
3528
3542
|
: [];
|
|
3529
3543
|
valuesToRemove = Array.from(setToRemove);
|
|
3530
|
-
if ((valuesToRemove.length > 0 || valuesToAdd.length > 0) && LMDB_PREFETCH_WRITES) {
|
|
3544
|
+
if (isLMDB && (valuesToRemove.length > 0 || valuesToAdd.length > 0) && LMDB_PREFETCH_WRITES) {
|
|
3531
3545
|
// prefetch any values that have been removed or added
|
|
3532
3546
|
const valuesToPrefetch = valuesToRemove.concat(valuesToAdd).map((v) => ({ key: v, value: id }));
|
|
3533
|
-
index.prefetch
|
|
3547
|
+
index.prefetch(valuesToPrefetch, noop);
|
|
3534
3548
|
}
|
|
3535
3549
|
//if the update cleared out the attribute value we need to delete it from the index
|
|
3536
3550
|
for (let i = 0, l = valuesToRemove.length; i < l; i++) {
|
|
3537
3551
|
index.remove(valuesToRemove[i], id, options);
|
|
3538
3552
|
}
|
|
3539
|
-
} else if (valuesToAdd?.length > 0 && LMDB_PREFETCH_WRITES) {
|
|
3553
|
+
} else if (isLMDB && valuesToAdd?.length > 0 && LMDB_PREFETCH_WRITES) {
|
|
3540
3554
|
// no old values, just new
|
|
3541
|
-
index.prefetch
|
|
3555
|
+
index.prefetch(
|
|
3542
3556
|
valuesToAdd.map((v) => ({ key: v, value: id })),
|
|
3543
3557
|
noop
|
|
3544
3558
|
);
|
|
@@ -4124,7 +4138,7 @@ export function makeTable(options) {
|
|
|
4124
4138
|
// don't do anything if the version has changed
|
|
4125
4139
|
return;
|
|
4126
4140
|
}
|
|
4127
|
-
updateIndices(id, existingRecord, updatedRecord);
|
|
4141
|
+
updateIndices(id, existingRecord, updatedRecord, transaction && { transaction });
|
|
4128
4142
|
if (updatedRecord) {
|
|
4129
4143
|
if (existingEntry) {
|
|
4130
4144
|
context.previousResidency = TableResource.getResidencyRecord(existingEntry.residencyId);
|
package/resources/databases.ts
CHANGED
|
@@ -120,9 +120,13 @@ function openRocksDatabase(path: string, options: RocksDatabaseOptions & { dupSo
|
|
|
120
120
|
}
|
|
121
121
|
let db: RocksRootDatabase;
|
|
122
122
|
if (options.dupSort) {
|
|
123
|
-
db =
|
|
123
|
+
db = new RocksIndexStore(path, options).open() as RocksDatabaseEx;
|
|
124
124
|
} else {
|
|
125
125
|
db = RocksDatabase.open(path, options) as RocksDatabaseEx;
|
|
126
|
+
// the RocksDB put and remove return promises, which masks thrown errors in non-awaiting calls to put/remove,
|
|
127
|
+
// making them unsafe to replace LMDB methods, which will synchronously throw errors if there is a problem
|
|
128
|
+
db.put = db.putSync;
|
|
129
|
+
db.remove = db.removeSync;
|
|
126
130
|
db.encoder.name = options.name;
|
|
127
131
|
}
|
|
128
132
|
db.env = {};
|
|
@@ -386,18 +390,18 @@ function initStores(
|
|
|
386
390
|
) {
|
|
387
391
|
const envInit = new OpenEnvironmentObject(path, false);
|
|
388
392
|
const internalDbiInit = createOpenDBIObject(false);
|
|
389
|
-
let
|
|
390
|
-
if (!
|
|
393
|
+
let attributesDbi = rootStore.dbisDb;
|
|
394
|
+
if (!attributesDbi) {
|
|
391
395
|
if (rootStore instanceof RocksDatabase) {
|
|
392
|
-
|
|
396
|
+
attributesDbi = openRocksDatabase(rootStore.path, {
|
|
393
397
|
...internalDbiInit,
|
|
394
398
|
disableWAL: false,
|
|
395
399
|
name: INTERNAL_DBIS_NAME,
|
|
396
400
|
}) as RocksDatabaseEx;
|
|
397
401
|
} else {
|
|
398
|
-
|
|
402
|
+
attributesDbi = rootStore.openDB(INTERNAL_DBIS_NAME, internalDbiInit);
|
|
399
403
|
}
|
|
400
|
-
rootStore.dbisDb =
|
|
404
|
+
rootStore.dbisDb = attributesDbi;
|
|
401
405
|
}
|
|
402
406
|
|
|
403
407
|
let auditStore = rootStore.auditStore;
|
|
@@ -428,7 +432,7 @@ function initStores(
|
|
|
428
432
|
definedTables.rootStore = rootStore;
|
|
429
433
|
const tablesToLoad = new Map<string, any>();
|
|
430
434
|
|
|
431
|
-
for (const result of
|
|
435
|
+
for (const result of attributesDbi.getRange({ start: false })) {
|
|
432
436
|
const { key, value } = result as { key: string; value: any };
|
|
433
437
|
let [tableName, attribute_name] = key.toString().split('/');
|
|
434
438
|
if (attribute_name === '') {
|
|
@@ -489,16 +493,16 @@ function initStores(
|
|
|
489
493
|
} else {
|
|
490
494
|
tableId = primaryAttribute.tableId;
|
|
491
495
|
if (tableId) {
|
|
492
|
-
if (tableId >= (
|
|
493
|
-
|
|
496
|
+
if (tableId >= (attributesDbi.getSync(NEXT_TABLE_ID) || 0)) {
|
|
497
|
+
attributesDbi.putSync(NEXT_TABLE_ID, tableId + 1);
|
|
494
498
|
logger.info(`Updating next table id (it was out of sync) to ${tableId + 1} for ${tableName}`);
|
|
495
499
|
}
|
|
496
500
|
} else {
|
|
497
|
-
primaryAttribute.tableId = tableId =
|
|
501
|
+
primaryAttribute.tableId = tableId = attributesDbi.getSync(NEXT_TABLE_ID);
|
|
498
502
|
if (!tableId) tableId = 1;
|
|
499
503
|
logger.debug(`Table {tableName} missing an id, assigning {tableId}`);
|
|
500
|
-
|
|
501
|
-
|
|
504
|
+
attributesDbi.putSync(NEXT_TABLE_ID, tableId + 1);
|
|
505
|
+
attributesDbi.putSync(primaryAttribute.key, primaryAttribute);
|
|
502
506
|
}
|
|
503
507
|
const dbiInit = createOpenDBIObject(!primaryAttribute.isPrimaryKey, primaryAttribute.isPrimaryKey);
|
|
504
508
|
dbiInit.compression = primaryAttribute.compression;
|
|
@@ -544,7 +548,18 @@ function initStores(
|
|
|
544
548
|
const attribute = attributes.find((attribute) => attribute.name === existingAttribute.name);
|
|
545
549
|
if (!attribute) {
|
|
546
550
|
if (existingAttribute.isPrimaryKey) {
|
|
547
|
-
logger.error(
|
|
551
|
+
logger.error(
|
|
552
|
+
new Error('Unable to remove existing primary key attribute'),
|
|
553
|
+
existingAttribute,
|
|
554
|
+
'from attributes',
|
|
555
|
+
existingAttributes,
|
|
556
|
+
'in',
|
|
557
|
+
tableName,
|
|
558
|
+
'requesting new attribute list',
|
|
559
|
+
attributes,
|
|
560
|
+
'full metadata list',
|
|
561
|
+
Array.from(attributesDbi.getRange({ start: false }))
|
|
562
|
+
);
|
|
548
563
|
continue;
|
|
549
564
|
}
|
|
550
565
|
if (existingAttribute.indexed) {
|
|
@@ -581,7 +596,7 @@ function initStores(
|
|
|
581
596
|
indices,
|
|
582
597
|
attributes,
|
|
583
598
|
schemaDefined: primaryAttribute.schemaDefined,
|
|
584
|
-
dbisDB:
|
|
599
|
+
dbisDB: attributesDbi,
|
|
585
600
|
})
|
|
586
601
|
);
|
|
587
602
|
table.schemaVersion = 1;
|
|
@@ -142,7 +142,14 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
142
142
|
// For each level from top to bottom
|
|
143
143
|
while (currentLevel > level) {
|
|
144
144
|
// Search for closest neighbors at current level
|
|
145
|
-
const neighbors = this.searchLayer(
|
|
145
|
+
const neighbors = this.searchLayer(
|
|
146
|
+
vector,
|
|
147
|
+
entryPointId,
|
|
148
|
+
entryPoint,
|
|
149
|
+
this.efConstruction,
|
|
150
|
+
currentLevel,
|
|
151
|
+
options
|
|
152
|
+
);
|
|
146
153
|
|
|
147
154
|
if (neighbors.length > 0) {
|
|
148
155
|
entryPointId = neighbors[0].id; // closest neighbor becomes new entry point
|
|
@@ -157,7 +164,7 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
157
164
|
|
|
158
165
|
// Connect the new element to neighbors at its level and below
|
|
159
166
|
for (let l = Math.min(level, currentLevel); l >= 0; l--) {
|
|
160
|
-
let neighbors = this.searchLayer(vector, entryPointId, entryPoint, this.efConstruction, l);
|
|
167
|
+
let neighbors = this.searchLayer(vector, entryPointId, entryPoint, this.efConstruction, l, options);
|
|
161
168
|
neighbors = neighbors.slice(0, this.M << 1) as SearchResults;
|
|
162
169
|
|
|
163
170
|
if (neighbors.length === 0 && l === 0) {
|
|
@@ -336,16 +343,16 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
336
343
|
this.indexStore.put(id, updatedNode, options);
|
|
337
344
|
}
|
|
338
345
|
for (const [key, vector] of needsReindexing) {
|
|
339
|
-
this.index(key, vector, vector);
|
|
346
|
+
this.index(key, vector, vector, options);
|
|
340
347
|
}
|
|
341
348
|
this.checkSymmetry(nodeId, this.indexStore.getSync(nodeId, options), options);
|
|
342
349
|
}
|
|
343
350
|
|
|
344
|
-
private getEntryPoint() {
|
|
351
|
+
private getEntryPoint(options: { transaction?: any } = {}) {
|
|
345
352
|
// Get entry point
|
|
346
|
-
const entryPointId = this.indexStore.getSync(ENTRY_POINT);
|
|
353
|
+
const entryPointId = this.indexStore.getSync(ENTRY_POINT, options);
|
|
347
354
|
if (entryPointId === undefined) return;
|
|
348
|
-
const node = this.indexStore.getSync(entryPointId);
|
|
355
|
+
const node = this.indexStore.getSync(entryPointId, options);
|
|
349
356
|
return { id: entryPointId, ...node };
|
|
350
357
|
}
|
|
351
358
|
|
|
@@ -359,6 +366,7 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
359
366
|
* @param ef
|
|
360
367
|
* @param level
|
|
361
368
|
* @param distanceFunction
|
|
369
|
+
* @param options
|
|
362
370
|
* @private
|
|
363
371
|
*/
|
|
364
372
|
private searchLayer(
|
|
@@ -367,6 +375,7 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
367
375
|
entryPoint: any,
|
|
368
376
|
ef: number,
|
|
369
377
|
level: number,
|
|
378
|
+
options: { transaction?: any } = {},
|
|
370
379
|
distanceFunction = this.distance
|
|
371
380
|
): SearchResults {
|
|
372
381
|
const visited = new Set([entryPointId]);
|
|
@@ -396,7 +405,7 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
396
405
|
if (visited.has(neighborId) || neighborId === undefined) continue;
|
|
397
406
|
visited.add(neighborId);
|
|
398
407
|
|
|
399
|
-
const neighbor = this.indexStore.getSync(neighborId);
|
|
408
|
+
const neighbor = this.indexStore.getSync(neighborId, options);
|
|
400
409
|
if (!neighbor) continue;
|
|
401
410
|
this.nodesVisitedCount++;
|
|
402
411
|
const distance = distanceFunction(queryVector, neighbor.vector);
|
|
@@ -429,19 +438,22 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
429
438
|
* @param comparator
|
|
430
439
|
* @param context
|
|
431
440
|
*/
|
|
432
|
-
search(
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
441
|
+
search(
|
|
442
|
+
{
|
|
443
|
+
target,
|
|
444
|
+
value,
|
|
445
|
+
descending,
|
|
446
|
+
distance,
|
|
447
|
+
comparator,
|
|
448
|
+
}: {
|
|
449
|
+
target: number[];
|
|
450
|
+
value: number;
|
|
451
|
+
descending: boolean;
|
|
452
|
+
distance: string;
|
|
453
|
+
comparator: string;
|
|
454
|
+
},
|
|
455
|
+
context: any
|
|
456
|
+
) {
|
|
445
457
|
let limit = 0; // zero is ignored, only used if set below
|
|
446
458
|
switch (comparator) {
|
|
447
459
|
case 'lt':
|
|
@@ -462,14 +474,23 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
462
474
|
if (!target) throw new ClientError('A target vector must be provided for an HNSW query');
|
|
463
475
|
if (!Array.isArray(target)) throw new ClientError('The target vector must be an array');
|
|
464
476
|
|
|
465
|
-
|
|
477
|
+
const options = context.transaction; // should have a nested RocksDB transaction
|
|
478
|
+
let entryPoint = this.getEntryPoint(options);
|
|
466
479
|
if (!entryPoint) return [];
|
|
467
480
|
let entryPointId = entryPoint.id;
|
|
468
481
|
let results: Candidate[] = [];
|
|
469
482
|
// For each level from top to bottom
|
|
470
483
|
for (let l = entryPoint.level; l >= 0; l--) {
|
|
471
484
|
// Search for closest neighbors at current level
|
|
472
|
-
results = this.searchLayer(
|
|
485
|
+
results = this.searchLayer(
|
|
486
|
+
target,
|
|
487
|
+
entryPointId,
|
|
488
|
+
entryPoint,
|
|
489
|
+
this.efConstructionSearch,
|
|
490
|
+
l,
|
|
491
|
+
options,
|
|
492
|
+
distanceFunction
|
|
493
|
+
);
|
|
473
494
|
|
|
474
495
|
if (results.length > 0) {
|
|
475
496
|
const neighbor = results[0]; // closest neighbor becomes new entry point
|
|
@@ -500,7 +521,7 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
500
521
|
// verify that the connection is symmetrical
|
|
501
522
|
const symmetrical = neighborNode[l]?.find(({ id: nid }) => nid == id);
|
|
502
523
|
if (!symmetrical) {
|
|
503
|
-
logger.info?.('asymmetry detected', neighborNode[l]);
|
|
524
|
+
logger.info?.('asymmetry detected', neighborNode[l], 'does not have', id);
|
|
504
525
|
}
|
|
505
526
|
}
|
|
506
527
|
l++;
|
|
@@ -95,7 +95,7 @@ export async function verifyOCSP(
|
|
|
95
95
|
method: cached.method || 'ocsp',
|
|
96
96
|
};
|
|
97
97
|
} catch (error) {
|
|
98
|
-
logger.error?.(`OCSP verification error
|
|
98
|
+
logger.error?.(`OCSP verification error:`, error);
|
|
99
99
|
|
|
100
100
|
// Check failure mode
|
|
101
101
|
if (config.failureMode === 'fail-closed') {
|
package/security/keys.js
CHANGED
|
@@ -125,7 +125,7 @@ function getCertTable() {
|
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
async function getReplicationCert() {
|
|
128
|
-
const SNICallback = createTLSSelector('
|
|
128
|
+
const SNICallback = createTLSSelector('replication');
|
|
129
129
|
const secureTarget = {
|
|
130
130
|
secureContexts: null,
|
|
131
131
|
setSecureContext: (_ctx) => {},
|
|
@@ -238,7 +238,7 @@ function loadCertificates() {
|
|
|
238
238
|
|
|
239
239
|
promise = certificateTable.put({
|
|
240
240
|
name: certCn,
|
|
241
|
-
uses: config.uses ?? [
|
|
241
|
+
uses: config.uses ?? [configKey.includes('operations') ? ['operations-api'] : []],
|
|
242
242
|
ciphers: config.ciphers,
|
|
243
243
|
certificate: certificatePem,
|
|
244
244
|
private_key_name,
|
|
@@ -351,7 +351,7 @@ function certExtensions() {
|
|
|
351
351
|
async function createCertificateTable(cert, caCert) {
|
|
352
352
|
await setCertTable({
|
|
353
353
|
name: getThisNodeName(),
|
|
354
|
-
uses: ['
|
|
354
|
+
uses: ['replication'],
|
|
355
355
|
certificate: cert,
|
|
356
356
|
private_key_name: 'privateKey.pem',
|
|
357
357
|
is_authority: false,
|
|
@@ -360,7 +360,7 @@ async function createCertificateTable(cert, caCert) {
|
|
|
360
360
|
|
|
361
361
|
await setCertTable({
|
|
362
362
|
name: caCert.subject.getField('CN').value,
|
|
363
|
-
uses: [
|
|
363
|
+
uses: [],
|
|
364
364
|
certificate: pki.certificateToPem(caCert),
|
|
365
365
|
private_key_name: 'privateKey.pem',
|
|
366
366
|
is_authority: true,
|
|
@@ -600,7 +600,7 @@ async function reviewSelfSignedCert() {
|
|
|
600
600
|
|
|
601
601
|
await setCertTable({
|
|
602
602
|
name: hdbCa.subject.getField('CN').value,
|
|
603
|
-
uses: [
|
|
603
|
+
uses: [],
|
|
604
604
|
certificate: pki.certificateToPem(hdbCa),
|
|
605
605
|
private_key_name: keyName,
|
|
606
606
|
is_authority: true,
|
|
@@ -621,7 +621,7 @@ async function reviewSelfSignedCert() {
|
|
|
621
621
|
const newPublicCert = await generateCertificates(pki.privateKeyFromPem(caAndKey.private_key), publicKey, hdbCa);
|
|
622
622
|
await setCertTable({
|
|
623
623
|
name: certName,
|
|
624
|
-
uses: ['
|
|
624
|
+
uses: ['replication'],
|
|
625
625
|
certificate: newPublicCert,
|
|
626
626
|
is_authority: false,
|
|
627
627
|
private_key_name: caAndKey.ca.private_key_name,
|
|
@@ -755,7 +755,7 @@ function createTLSSelector(type, mtlsOptions) {
|
|
|
755
755
|
}
|
|
756
756
|
let quality = cert.is_self_signed ? 1 : 3;
|
|
757
757
|
// prefer operations certificates for operations API
|
|
758
|
-
if (cert.uses?.includes(type)) quality +=
|
|
758
|
+
if (cert.uses?.includes(type)) quality += 3;
|
|
759
759
|
|
|
760
760
|
const private_key = getPrivateKeyByName(cert.private_key_name);
|
|
761
761
|
|
|
@@ -46,10 +46,6 @@ async function schemaHandler(event) {
|
|
|
46
46
|
*/
|
|
47
47
|
async function syncSchemaMetadata(msg) {
|
|
48
48
|
try {
|
|
49
|
-
// reset current read transactions to ensure that we are getting the very latest data
|
|
50
|
-
harperBridge.resetReadTxn(hdbTerms.SYSTEM_SCHEMA_NAME, hdbTerms.SYSTEM_TABLE_NAMES.TABLE_TABLE_NAME);
|
|
51
|
-
harperBridge.resetReadTxn(hdbTerms.SYSTEM_SCHEMA_NAME, hdbTerms.SYSTEM_TABLE_NAMES.ATTRIBUTE_TABLE_NAME);
|
|
52
|
-
harperBridge.resetReadTxn(hdbTerms.SYSTEM_SCHEMA_NAME, hdbTerms.SYSTEM_TABLE_NAMES.SCHEMA_TABLE_NAME);
|
|
53
49
|
// TODO: Eventually should indicate which database/table changed so we don't have to scan everything
|
|
54
50
|
let databases = resetDatabases();
|
|
55
51
|
if (msg.table && msg.database)
|