harperdb 4.6.6 → 4.7.0-alpha.2
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 +0 -0
- package/README.md +1 -1
- package/bin/harperdb.js +89 -78
- package/bin/lite.js +85 -74
- package/components/requestRestart.d.ts +3 -0
- package/components/status/ComponentStatus.d.ts +61 -0
- package/components/status/ComponentStatusRegistry.d.ts +80 -0
- package/components/status/api.d.ts +104 -0
- package/components/status/crossThread.d.ts +62 -0
- package/components/status/errors.d.ts +68 -0
- package/components/status/index.d.ts +35 -0
- package/components/status/internal.d.ts +40 -0
- package/components/status/registry.d.ts +10 -0
- package/components/status/types.d.ts +75 -0
- package/json/systemSchema.json +68 -7
- package/launchServiceScripts/launchNatsIngestService.js +85 -74
- package/launchServiceScripts/launchNatsReplyService.js +85 -74
- package/launchServiceScripts/launchUpdateNodes4-0-0.js +85 -74
- package/npm-shrinkwrap.json +361 -71
- package/package.json +6 -6
- package/resources/RequestTarget.d.ts +1 -1
- package/resources/Resource.d.ts +3 -3
- package/resources/ResourceInterface.d.ts +33 -10
- package/resources/Resources.d.ts +1 -0
- package/resources/Table.d.ts +3 -3
- package/resources/analytics/hostnames.d.ts +3 -3
- package/resources/analytics/write.d.ts +2 -0
- package/resources/auditStore.d.ts +2 -0
- package/resources/databases.d.ts +3 -3
- package/resources/usageLicensing.d.ts +23 -0
- package/security/certificateVerification.d.ts +80 -0
- package/security/pkijs-ed25519-patch.d.ts +14 -0
- package/server/jobs/jobProcess.js +85 -74
- package/server/replication/knownNodes.d.ts +13 -1
- package/server/replication/replicationConnection.d.ts +2 -1
- package/server/status/index.d.ts +14 -5
- package/server/threads/threadServer.js +85 -74
- package/studio/build-local/asset-manifest.json +2 -2
- package/studio/build-local/index.html +1 -1
- package/studio/build-local/static/js/main.b93998e3.js +2 -0
- package/utility/hdbTerms.d.ts +8 -0
- package/utility/scripts/restartHdb.js +85 -74
- package/validation/usageLicensing.d.ts +34 -0
- package/studio/build-local/static/js/main.f9919fa0.js +0 -2
- /package/studio/build-local/static/js/{main.f9919fa0.js.LICENSE.txt → main.b93998e3.js.LICENSE.txt} +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { DatabaseTransaction } from './DatabaseTransaction.ts';
|
|
2
2
|
import { OperationFunctionName } from '../server/serverHelpers/serverUtilities.ts';
|
|
3
|
-
import { RequestTarget } from './RequestTarget';
|
|
3
|
+
import { RequestTarget } from './RequestTarget.ts';
|
|
4
|
+
import { Entry } from './RecordEncoder.ts';
|
|
4
5
|
export interface ResourceInterface<Key = any, Record = any> {
|
|
5
|
-
get?(id: Id): Promise<
|
|
6
|
+
get?(id: Id): Promise<Record>;
|
|
6
7
|
get?(query: RequestTargetOrId): Promise<AsyncIterable<Record>>;
|
|
7
8
|
put?(target: RequestTargetOrId, record: any): void;
|
|
8
9
|
post?(target: RequestTargetOrId, record: any): void;
|
|
@@ -21,25 +22,25 @@ export interface User {
|
|
|
21
22
|
username: string;
|
|
22
23
|
}
|
|
23
24
|
export interface Context {
|
|
24
|
-
/** The user making the request
|
|
25
|
+
/** The user making the request */
|
|
25
26
|
user?: User;
|
|
26
|
-
/** The database transaction object
|
|
27
|
+
/** The database transaction object */
|
|
27
28
|
transaction?: DatabaseTransaction;
|
|
28
|
-
/** If the operation that will be performed with this context should check user authorization
|
|
29
|
+
/** If the operation that will be performed with this context should check user authorization */
|
|
29
30
|
authorize?: number;
|
|
30
|
-
/** The last modification time of any data that has been accessed with this context
|
|
31
|
+
/** The last modification time of any data that has been accessed with this context */
|
|
31
32
|
lastModified?: number;
|
|
32
33
|
/** The time at which a saved record should expire */
|
|
33
34
|
expiresAt?: number;
|
|
34
|
-
/** Indicates that caching should not be applied
|
|
35
|
+
/** Indicates that caching should not be applied */
|
|
35
36
|
noCache?: boolean;
|
|
36
|
-
/** Indicates that values from the source data should be stored as a cached value
|
|
37
|
+
/** Indicates that values from the source data should be stored as a cached value */
|
|
37
38
|
noCacheStore?: boolean;
|
|
38
39
|
/** Only return values from the table, and don't use data from the source */
|
|
39
40
|
onlyIfCached?: boolean;
|
|
40
41
|
/** Allows data from a caching table to be used if there is an error retrieving data from the source */
|
|
41
42
|
staleIfError?: boolean;
|
|
42
|
-
/** Indicates any cached data must be revalidated
|
|
43
|
+
/** Indicates any cached data must be revalidated */
|
|
43
44
|
mustRevalidate?: boolean;
|
|
44
45
|
/** An array of nodes to replicate to */
|
|
45
46
|
replicateTo?: string[];
|
|
@@ -52,6 +53,28 @@ export interface Context {
|
|
|
52
53
|
resourceCache?: Map<Id, any>;
|
|
53
54
|
_freezeRecords?: boolean;
|
|
54
55
|
}
|
|
56
|
+
export interface SourceContext<TRequestContext = Context> {
|
|
57
|
+
/** The original request context passed from the caching layer */
|
|
58
|
+
requestContext: TRequestContext;
|
|
59
|
+
/** The existing record, from the existing entry (if any) */
|
|
60
|
+
replacingRecord?: any;
|
|
61
|
+
/** The existing database entry (if any) */
|
|
62
|
+
replacingEntry?: Entry;
|
|
63
|
+
/** The version/timestamp of the existing record */
|
|
64
|
+
replacingVersion?: number;
|
|
65
|
+
/** Indicates that values from the source data should NOT be stored as a cached value */
|
|
66
|
+
noCacheStore?: boolean;
|
|
67
|
+
/** Reference to the source Resource instance */
|
|
68
|
+
source?: ResourceInterface;
|
|
69
|
+
/** Shared resource cache from parent context for visibility of modifications */
|
|
70
|
+
resourceCache?: Map<Id, any>;
|
|
71
|
+
/** Database transaction for the context */
|
|
72
|
+
transaction?: DatabaseTransaction;
|
|
73
|
+
/** The time at which the cached entry should expire (ms since epoch) */
|
|
74
|
+
expiresAt?: number;
|
|
75
|
+
/** The last modification time of any data accessed with this context */
|
|
76
|
+
lastModified?: number;
|
|
77
|
+
}
|
|
55
78
|
export type Operator = 'and' | 'or';
|
|
56
79
|
type SearchType = 'equals' | 'contains' | 'starts_with' | 'ends_with' | 'greater_than' | 'greater_than_equal' | 'less_than' | 'less_than_equal' | 'between';
|
|
57
80
|
export interface DirectCondition {
|
|
@@ -94,7 +117,7 @@ export interface SubscriptionRequest {
|
|
|
94
117
|
export type Query = RequestTarget;
|
|
95
118
|
export type RequestTargetOrId = RequestTarget | Id;
|
|
96
119
|
export type Id = number | string | (number | string | null)[] | null;
|
|
97
|
-
type UpdatableRecord<T> = T;
|
|
120
|
+
export type UpdatableRecord<T> = T;
|
|
98
121
|
interface Subscription {
|
|
99
122
|
}
|
|
100
123
|
export {};
|
package/resources/Resources.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ interface ResourceEntry {
|
|
|
12
12
|
export declare class Resources extends Map<string, ResourceEntry> {
|
|
13
13
|
isWorker: boolean;
|
|
14
14
|
loginPath?: (request: any) => string;
|
|
15
|
+
allTypes: Map<any, any>;
|
|
15
16
|
set(path: any, resource: any, exportTypes?: {
|
|
16
17
|
[key: string]: boolean;
|
|
17
18
|
}, force?: boolean): void;
|
package/resources/Table.d.ts
CHANGED
|
@@ -203,7 +203,7 @@ export declare function makeTable(options: any): {
|
|
|
203
203
|
get isCollection(): boolean;
|
|
204
204
|
connect(incomingMessages: import("./IterableEventQueue.js").IterableEventQueue, query?: {}): AsyncIterable<any>;
|
|
205
205
|
getId(): Id;
|
|
206
|
-
getContext(): Context;
|
|
206
|
+
getContext(): Context | import("./ResourceInterface.ts").SourceContext;
|
|
207
207
|
};
|
|
208
208
|
name: any;
|
|
209
209
|
primaryStore: any;
|
|
@@ -412,7 +412,7 @@ export declare function makeTable(options: any): {
|
|
|
412
412
|
get isCollection(): boolean;
|
|
413
413
|
connect(incomingMessages: import("./IterableEventQueue.js").IterableEventQueue, query?: {}): AsyncIterable<any>;
|
|
414
414
|
getId(): Id;
|
|
415
|
-
getContext(): Context;
|
|
415
|
+
getContext(): Context | import("./ResourceInterface.ts").SourceContext;
|
|
416
416
|
}> | {
|
|
417
417
|
#record: any;
|
|
418
418
|
#changes: any;
|
|
@@ -574,7 +574,7 @@ export declare function makeTable(options: any): {
|
|
|
574
574
|
get isCollection(): boolean;
|
|
575
575
|
connect(incomingMessages: import("./IterableEventQueue.js").IterableEventQueue, query?: {}): AsyncIterable<any>;
|
|
576
576
|
getId(): Id;
|
|
577
|
-
getContext(): Context;
|
|
577
|
+
getContext(): Context | import("./ResourceInterface.ts").SourceContext;
|
|
578
578
|
};
|
|
579
579
|
_updateResource(resource: any, entry: any): void;
|
|
580
580
|
getNewId(): any;
|
|
@@ -110,7 +110,7 @@ export declare function getAnalyticsHostnameTable(): {
|
|
|
110
110
|
get isCollection(): boolean;
|
|
111
111
|
connect(incomingMessages: import("../IterableEventQueue.js").IterableEventQueue, query?: {}): AsyncIterable<any>;
|
|
112
112
|
getId(): import("../ResourceInterface.js").Id;
|
|
113
|
-
getContext(): import("../ResourceInterface.js").Context;
|
|
113
|
+
getContext(): import("../ResourceInterface.js").Context | import("../ResourceInterface.js").SourceContext;
|
|
114
114
|
};
|
|
115
115
|
name: any;
|
|
116
116
|
primaryStore: any;
|
|
@@ -250,7 +250,7 @@ export declare function getAnalyticsHostnameTable(): {
|
|
|
250
250
|
get isCollection(): boolean;
|
|
251
251
|
connect(incomingMessages: import("../IterableEventQueue.js").IterableEventQueue, query?: {}): AsyncIterable<any>;
|
|
252
252
|
getId(): import("../ResourceInterface.js").Id;
|
|
253
|
-
getContext(): import("../ResourceInterface.js").Context;
|
|
253
|
+
getContext(): import("../ResourceInterface.js").Context | import("../ResourceInterface.js").SourceContext;
|
|
254
254
|
}> | {
|
|
255
255
|
#record: any;
|
|
256
256
|
#changes: any;
|
|
@@ -361,7 +361,7 @@ export declare function getAnalyticsHostnameTable(): {
|
|
|
361
361
|
get isCollection(): boolean;
|
|
362
362
|
connect(incomingMessages: import("../IterableEventQueue.js").IterableEventQueue, query?: {}): AsyncIterable<any>;
|
|
363
363
|
getId(): import("../ResourceInterface.js").Id;
|
|
364
|
-
getContext(): import("../ResourceInterface.js").Context;
|
|
364
|
+
getContext(): import("../ResourceInterface.js").Context | import("../ResourceInterface.js").SourceContext;
|
|
365
365
|
};
|
|
366
366
|
_updateResource(resource: any, entry: any): void;
|
|
367
367
|
getNewId(): any;
|
|
@@ -23,6 +23,7 @@ export declare function setAnalyticsEnabled(enabled: boolean): void;
|
|
|
23
23
|
*/
|
|
24
24
|
export declare function recordAction(value: Value, metric: string, path?: string, method?: string, type?: string): void;
|
|
25
25
|
export declare function recordActionBinary(value: any, metric: any, path?: any, method?: any, type?: any): void;
|
|
26
|
+
export declare const analyticsDelay = 1000;
|
|
26
27
|
export declare function addAnalyticsListener(callback: any): void;
|
|
27
28
|
export declare function recordHostname(): Promise<void>;
|
|
28
29
|
export interface Metric {
|
|
@@ -47,6 +48,7 @@ export declare function calculateCPUUtilization(resourceUsage: ResourceUsage, pe
|
|
|
47
48
|
* new values for this time period.
|
|
48
49
|
*/
|
|
49
50
|
export declare function diffResourceUsage(lastResourceUsage: ResourceUsage, resourceUsage: ResourceUsage): ResourceUsage;
|
|
51
|
+
export declare function onAnalyticsAggregate(callback: any): void;
|
|
50
52
|
export {};
|
|
51
53
|
/**
|
|
52
54
|
* This section contains a possible/experimental approach to bucketing values as they come instead of pushing all into an array and sorting.
|
|
@@ -53,6 +53,7 @@ export declare function readAuditEntry(buffer: Uint8Array, start?: number, end?:
|
|
|
53
53
|
previousLocalTime: any;
|
|
54
54
|
readonly user: import("ordered-binary").Key;
|
|
55
55
|
readonly encoded: Uint8Array<ArrayBufferLike>;
|
|
56
|
+
readonly size: number;
|
|
56
57
|
getValue(store: any, fullRecord?: any, auditTime?: any): any;
|
|
57
58
|
getBinaryValue(): Uint8Array<ArrayBufferLike>;
|
|
58
59
|
extendedType: any;
|
|
@@ -70,6 +71,7 @@ export declare function readAuditEntry(buffer: Uint8Array, start?: number, end?:
|
|
|
70
71
|
previousLocalTime?: undefined;
|
|
71
72
|
readonly user?: undefined;
|
|
72
73
|
readonly encoded?: undefined;
|
|
74
|
+
readonly size?: undefined;
|
|
73
75
|
getValue?: undefined;
|
|
74
76
|
getBinaryValue?: undefined;
|
|
75
77
|
extendedType?: undefined;
|
package/resources/databases.d.ts
CHANGED
|
@@ -187,7 +187,7 @@ export declare function table(tableDefinition: TableDefinition): {
|
|
|
187
187
|
get isCollection(): boolean;
|
|
188
188
|
connect(incomingMessages: import("./IterableEventQueue.js").IterableEventQueue, query?: {}): AsyncIterable<any>;
|
|
189
189
|
getId(): import("./ResourceInterface.js").Id;
|
|
190
|
-
getContext(): import("./ResourceInterface.js").Context;
|
|
190
|
+
getContext(): import("./ResourceInterface.js").Context | import("./ResourceInterface.js").SourceContext;
|
|
191
191
|
};
|
|
192
192
|
name: any;
|
|
193
193
|
primaryStore: any;
|
|
@@ -327,7 +327,7 @@ export declare function table(tableDefinition: TableDefinition): {
|
|
|
327
327
|
get isCollection(): boolean;
|
|
328
328
|
connect(incomingMessages: import("./IterableEventQueue.js").IterableEventQueue, query?: {}): AsyncIterable<any>;
|
|
329
329
|
getId(): import("./ResourceInterface.js").Id;
|
|
330
|
-
getContext(): import("./ResourceInterface.js").Context;
|
|
330
|
+
getContext(): import("./ResourceInterface.js").Context | import("./ResourceInterface.js").SourceContext;
|
|
331
331
|
}> | {
|
|
332
332
|
#record: any;
|
|
333
333
|
#changes: any;
|
|
@@ -438,7 +438,7 @@ export declare function table(tableDefinition: TableDefinition): {
|
|
|
438
438
|
get isCollection(): boolean;
|
|
439
439
|
connect(incomingMessages: import("./IterableEventQueue.js").IterableEventQueue, query?: {}): AsyncIterable<any>;
|
|
440
440
|
getId(): import("./ResourceInterface.js").Id;
|
|
441
|
-
getContext(): import("./ResourceInterface.js").Context;
|
|
441
|
+
getContext(): import("./ResourceInterface.js").Context | import("./ResourceInterface.js").SourceContext;
|
|
442
442
|
};
|
|
443
443
|
_updateResource(resource: any, entry: any): void;
|
|
444
444
|
getNewId(): any;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ValidatedLicense } from '../validation/usageLicensing.ts';
|
|
2
|
+
interface InstallLicenseRequest {
|
|
3
|
+
operation: 'install_usage_license';
|
|
4
|
+
license: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function installUsageLicenseOp(req: InstallLicenseRequest): Promise<string>;
|
|
7
|
+
interface UsageLicense extends ValidatedLicense {
|
|
8
|
+
usedReads: number;
|
|
9
|
+
usedReadBytes: number;
|
|
10
|
+
usedWrites: number;
|
|
11
|
+
usedWriteBytes: number;
|
|
12
|
+
usedRealTimeMessages: number;
|
|
13
|
+
usedRealTimeBytes: number;
|
|
14
|
+
usedCpuTime: number;
|
|
15
|
+
}
|
|
16
|
+
interface UsageLicenseRecord extends UsageLicense {
|
|
17
|
+
addTo: (field: string, value: number) => void;
|
|
18
|
+
}
|
|
19
|
+
interface GetUsageLicensesReq {
|
|
20
|
+
operation: 'get_usage_licenses';
|
|
21
|
+
}
|
|
22
|
+
export declare function getUsageLicensesOp(req: GetUsageLicensesReq): AsyncIterable<UsageLicenseRecord>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Certificate verification for mTLS authentication
|
|
3
|
+
*
|
|
4
|
+
* This module provides certificate revocation checking for client certificates
|
|
5
|
+
* in mutual TLS (mTLS) connections. Currently supports OCSP (Online Certificate
|
|
6
|
+
* Status Protocol) with the ability to add CRL (Certificate Revocation List) support.
|
|
7
|
+
* Uses a system table, hdb_certificate_cache, for a certificate verification
|
|
8
|
+
* status cache.
|
|
9
|
+
*
|
|
10
|
+
* Default configuration:
|
|
11
|
+
* - Enabled by default when mTLS is configured
|
|
12
|
+
* - Timeout: 5 seconds
|
|
13
|
+
* - Cache TTL: 1 hour
|
|
14
|
+
* - Failure mode: fail-open (allows connections if verification fails)
|
|
15
|
+
*/
|
|
16
|
+
import './pkijs-ed25519-patch.ts';
|
|
17
|
+
interface CertificateVerificationResult {
|
|
18
|
+
valid: boolean;
|
|
19
|
+
status: string;
|
|
20
|
+
cached?: boolean;
|
|
21
|
+
error?: string;
|
|
22
|
+
method?: 'ocsp' | 'crl' | 'disabled';
|
|
23
|
+
}
|
|
24
|
+
interface PeerCertificate {
|
|
25
|
+
subject?: {
|
|
26
|
+
CN?: string;
|
|
27
|
+
[key: string]: any;
|
|
28
|
+
};
|
|
29
|
+
raw?: Buffer;
|
|
30
|
+
issuerCertificate?: PeerCertificate;
|
|
31
|
+
}
|
|
32
|
+
interface CertificateVerificationConfig {
|
|
33
|
+
timeout?: number;
|
|
34
|
+
cacheTtl?: number;
|
|
35
|
+
failureMode?: 'fail-open' | 'fail-closed';
|
|
36
|
+
}
|
|
37
|
+
interface CertificateChainEntry {
|
|
38
|
+
cert: Buffer;
|
|
39
|
+
issuer?: Buffer;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Determine if certificate verification should be performed based on configuration
|
|
43
|
+
* @param mtlsConfig - The mTLS configuration (can be boolean or object)
|
|
44
|
+
* @returns Configuration object or false if verification is disabled
|
|
45
|
+
*/
|
|
46
|
+
export declare function getCertificateVerificationConfig(mtlsConfig: boolean | Record<string, any> | null | undefined): false | CertificateVerificationConfig;
|
|
47
|
+
/**
|
|
48
|
+
* Verify certificate revocation status
|
|
49
|
+
* @param peerCertificate - Peer certificate object from TLS connection
|
|
50
|
+
* @param mtlsConfig - The mTLS configuration from the request
|
|
51
|
+
* @returns Promise resolving to verification result
|
|
52
|
+
*/
|
|
53
|
+
export declare function verifyCertificate(peerCertificate: PeerCertificate, mtlsConfig?: boolean | Record<string, any> | null): Promise<CertificateVerificationResult>;
|
|
54
|
+
/**
|
|
55
|
+
* Verify OCSP status of a client certificate
|
|
56
|
+
* @param certPem - Client certificate in PEM format or Buffer
|
|
57
|
+
* @param issuerPem - Issuer (CA) certificate in PEM format or Buffer
|
|
58
|
+
* @returns Promise resolving to verification result
|
|
59
|
+
*/
|
|
60
|
+
export declare function verifyOCSP(certPem: Buffer | string, issuerPem: Buffer | string, config?: CertificateVerificationConfig): Promise<CertificateVerificationResult>;
|
|
61
|
+
/**
|
|
62
|
+
* Set TTL configuration for the certificate cache
|
|
63
|
+
* @param ttlConfig - Configuration for cache expiration and eviction
|
|
64
|
+
*/
|
|
65
|
+
export declare function setCertificateCacheTTL(ttlConfig: {
|
|
66
|
+
expiration: number;
|
|
67
|
+
eviction?: number;
|
|
68
|
+
scanInterval?: number;
|
|
69
|
+
}): void;
|
|
70
|
+
/**
|
|
71
|
+
* Convert a buffer to PEM format
|
|
72
|
+
*/
|
|
73
|
+
export declare function bufferToPem(buffer: Buffer, type: string): string;
|
|
74
|
+
/**
|
|
75
|
+
* Extract certificate chain from peer certificate object
|
|
76
|
+
* @param peerCertificate - Peer certificate object from TLS connection
|
|
77
|
+
* @returns Certificate chain
|
|
78
|
+
*/
|
|
79
|
+
export declare function extractCertificateChain(peerCertificate: PeerCertificate): CertificateChainEntry[];
|
|
80
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PKI.js Ed25519/Ed448 Support Patch
|
|
3
|
+
*
|
|
4
|
+
* This module patches PKI.js to add complete Ed25519/Ed448 support for certificate
|
|
5
|
+
* and OCSP response verification. While PKI.js has some Ed25519/Ed448 support,
|
|
6
|
+
* it currently lacks:
|
|
7
|
+
* - getHashAlgorithm() support for Ed25519/Ed448 OIDs
|
|
8
|
+
* - getAlgorithmByOID() recognition of Ed25519/Ed448
|
|
9
|
+
* - Certificate verification using Ed25519/Ed448 signatures
|
|
10
|
+
* - OCSP response signature verification with Ed25519/Ed448
|
|
11
|
+
*
|
|
12
|
+
* This patch must be loaded before any module that uses PKI.js (including easy-ocsp).
|
|
13
|
+
*/
|
|
14
|
+
export declare function applyEd25519Patch(): void;
|