@forklaunch/core 3.1.0 → 3.2.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/bin/gateway-mock/routes/email.mjs +91 -4
- package/lib/http/emailClient.d.ts +46 -0
- package/lib/http/emailClient.d.ts.map +1 -1
- package/lib/http/index.d.ts +1 -0
- package/lib/http/index.d.ts.map +1 -1
- package/lib/http/index.js +303 -92
- package/lib/http/index.js.map +1 -1
- package/lib/http/index.mjs +262 -54
- package/lib/http/index.mjs.map +1 -1
- package/lib/http/middleware/request/enrichDetails.middleware.d.ts.map +1 -1
- package/lib/http/telemetry/auditLogger.d.ts +5 -1
- package/lib/http/telemetry/auditLogger.d.ts.map +1 -1
- package/lib/http/telemetry/requestAudit.d.ts +30 -0
- package/lib/http/telemetry/requestAudit.d.ts.map +1 -0
- package/lib/persistence/complianceChanges.d.ts +30 -0
- package/lib/persistence/complianceChanges.d.ts.map +1 -0
- package/lib/persistence/compliancePropertyBuilder.d.ts.map +1 -1
- package/lib/persistence/compliantField.d.ts +41 -8
- package/lib/persistence/compliantField.d.ts.map +1 -1
- package/lib/persistence/defineComplianceEntity.d.ts.map +1 -1
- package/lib/persistence/index.d.ts +2 -1
- package/lib/persistence/index.d.ts.map +1 -1
- package/lib/persistence/index.js +150 -18
- package/lib/persistence/index.js.map +1 -1
- package/lib/persistence/index.mjs +148 -18
- package/lib/persistence/index.mjs.map +1 -1
- package/package.json +10 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enrichDetails.middleware.d.ts","sourceRoot":"","sources":["../../../../src/http/middleware/request/enrichDetails.middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAS3D,OAAO,EAEL,sBAAsB,EACvB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,IAAI,EACJ,aAAa,EACb,mBAAmB,EACnB,MAAM,EACN,YAAY,EACZ,4BAA4B,EAC5B,WAAW,EACX,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,aAAa,EACd,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"enrichDetails.middleware.d.ts","sourceRoot":"","sources":["../../../../src/http/middleware/request/enrichDetails.middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAS3D,OAAO,EAEL,sBAAsB,EACvB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,IAAI,EACJ,aAAa,EACb,mBAAmB,EACnB,MAAM,EACN,YAAY,EACZ,4BAA4B,EAC5B,WAAW,EACX,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,aAAa,EACd,MAAM,mCAAmC,CAAC;AAK3C,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAE7E;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,EAAE,SAAS,kBAAkB,EAC7B,cAAc,SAAS,MAAM,EAC7B,CAAC,SAAS,YAAY,CAAC,EAAE,CAAC,EAC1B,UAAU,SAAS,eAAe,CAAC,EAAE,CAAC,EACtC,OAAO,SAAS,IAAI,CAAC,EAAE,CAAC,EACxB,QAAQ,SAAS,WAAW,CAAC,EAAE,CAAC,EAChC,UAAU,SAAS,aAAa,CAAC,EAAE,CAAC,EACpC,UAAU,SAAS,aAAa,CAAC,EAAE,CAAC,EACpC,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzC,YAAY,SAAS,aAAa,CAAC,EAAE,EAAE,cAAc,CAAC,EACtD,aAAa,SAAS,aAAa,CAAC,EAAE,CAAC,EAEvC,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,mBAAmB,CAAC,EAAE,CAAC,GAAG,4BAA4B,CAAC,EAAE,CAAC,EAC3E,aAAa,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChD,eAAe,EACb,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,EACjE,sBAAsB,CAAC,EAAE,sBAAsB,CAAC,iBAAiB,CAAC,EAClE,aAAa,CAAC,EAAE,MAAM,wBAAwB,CAAC,EAAE,EAAE,aAAa,CAAC,GAAG,SAAS,GAC5E,wBAAwB,CACzB,EAAE,EACF,CAAC,EACD,UAAU,EACV,OAAO,EACP,QAAQ,EACR,UAAU,EACV,UAAU,EACV,SAAS,EACT,YAAY,EACZ,aAAa,EACb,OAAO,EACP,OAAO,EACP,sBAAsB,CACvB,CAqCA"}
|
|
@@ -10,7 +10,11 @@ export type AuditEntry = {
|
|
|
10
10
|
status: number;
|
|
11
11
|
duration: number;
|
|
12
12
|
redactedFields: string[];
|
|
13
|
-
eventType: 'http' | 'ws' | 'auth_failure' | 'rate_limit' | 'rbac_deny' | 'super_admin_bypass'
|
|
13
|
+
eventType: 'http' | 'ws' | 'auth_failure' | 'rate_limit' | 'rbac_deny' | 'super_admin_bypass'
|
|
14
|
+
/** A compliant field's plaintext was read (.deanon). */
|
|
15
|
+
| 'data_access'
|
|
16
|
+
/** A record holding sensitive fields was created, updated or deleted. */
|
|
17
|
+
| 'data_change';
|
|
14
18
|
};
|
|
15
19
|
export declare class AuditLogger {
|
|
16
20
|
_otel: OpenTelemetryCollector<MetricsDefinition>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auditLogger.d.ts","sourceRoot":"","sources":["../../../src/http/telemetry/auditLogger.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,SAAS,EACL,MAAM,GACN,IAAI,GACJ,cAAc,GACd,YAAY,GACZ,WAAW,GACX,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"auditLogger.d.ts","sourceRoot":"","sources":["../../../src/http/telemetry/auditLogger.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,SAAS,EACL,MAAM,GACN,IAAI,GACJ,cAAc,GACd,YAAY,GACZ,WAAW,GACX,oBAAoB;IACtB,wDAAwD;OACtD,aAAa;IACf,yEAAyE;OACvE,aAAa,CAAC;CACnB,CAAC;AAEF,qBAAa,WAAW;IACtB,KAAK,EAAE,sBAAsB,CAAC,iBAAiB,CAAC,CAAC;IAEjD,YAAY,IAAI,EAAE,sBAAsB,CAAC,iBAAiB,CAAC,EAE1D;IAED,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAsB9B;IAED,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAKhE;CACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { MetricsDefinition } from '../types/openTelemetryCollector.types';
|
|
2
|
+
import { AuditEntry } from './auditLogger';
|
|
3
|
+
import { OpenTelemetryCollector } from './openTelemetryCollector';
|
|
4
|
+
/**
|
|
5
|
+
* Default audit trail for every app built on ForkLaunch: one audit record per
|
|
6
|
+
* request (who, tenant, method, route, status, duration and a hash of the
|
|
7
|
+
* body, never its content) and one per read of a compliant field's plaintext.
|
|
8
|
+
* Records carry `log.type: audit` so the platform can keep them apart from
|
|
9
|
+
* application logs. On unless FORKLAUNCH_AUDIT=off.
|
|
10
|
+
*/
|
|
11
|
+
export declare function auditEnabled(): boolean;
|
|
12
|
+
/** The audit event a response status stands for. */
|
|
13
|
+
export declare function auditEventType(status: number): AuditEntry['eventType'];
|
|
14
|
+
/** Append the audit record for one finished request. */
|
|
15
|
+
export declare function recordRequestAudit(otel: OpenTelemetryCollector<MetricsDefinition> | undefined, req: {
|
|
16
|
+
method: string;
|
|
17
|
+
originalPath?: string;
|
|
18
|
+
path?: string;
|
|
19
|
+
session?: unknown;
|
|
20
|
+
body?: unknown;
|
|
21
|
+
}, status: number, durationMs: number): void;
|
|
22
|
+
/**
|
|
23
|
+
* Every `.deanon` read of a compliant field becomes an audit record (field,
|
|
24
|
+
* level, tenant), and every create/update/delete of a record holding sensitive
|
|
25
|
+
* fields a `data_change` record (entity#id, action, sensitive field names). It is emitted inside the request's trace, which ties it to
|
|
26
|
+
* the request's own audit record and so to the user. Registered once per
|
|
27
|
+
* process; returns a function that removes it.
|
|
28
|
+
*/
|
|
29
|
+
export declare function auditComplianceAccess(otel: OpenTelemetryCollector<MetricsDefinition>): () => void;
|
|
30
|
+
//# sourceMappingURL=requestAudit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestAudit.d.ts","sourceRoot":"","sources":["../../../src/http/telemetry/requestAudit.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAe,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE;;;;;;GAMG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAYD,oDAAoD;AACpD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAKtE;AAeD,wDAAwD;AACxD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,sBAAsB,CAAC,iBAAiB,CAAC,GAAG,SAAS,EAC3D,GAAG,EAAE;IACH,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,EACD,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GACjB,IAAI,CAmBN;AAID;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,sBAAsB,CAAC,iBAAiB,CAAC,GAC9C,MAAM,IAAI,CAsCZ"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { EntitySchema } from '@mikro-orm/core';
|
|
2
|
+
import type { ComplianceLevel } from './complianceTypes';
|
|
3
|
+
/**
|
|
4
|
+
* Emitted after a record of an entity holding pii, phi or pci fields is
|
|
5
|
+
* created, updated or deleted. Carries field names, never values.
|
|
6
|
+
*/
|
|
7
|
+
export interface ComplianceChangeEvent {
|
|
8
|
+
entity: string;
|
|
9
|
+
/** Primary key, colon-joined for composite keys. */
|
|
10
|
+
id: string;
|
|
11
|
+
action: 'create' | 'update' | 'delete';
|
|
12
|
+
/** Fields written (create: every field set; update: the changed ones). */
|
|
13
|
+
fields: string[];
|
|
14
|
+
/** The sensitive fields among them. */
|
|
15
|
+
sensitiveFields: string[];
|
|
16
|
+
tenantId: string | null;
|
|
17
|
+
}
|
|
18
|
+
export type ComplianceChangeListener = (event: ComplianceChangeEvent) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Register a listener for every change to a sensitive record, for audit
|
|
21
|
+
* trails. Returns a function that removes it.
|
|
22
|
+
*/
|
|
23
|
+
export declare function onComplianceChange(listener: ComplianceChangeListener): () => void;
|
|
24
|
+
/**
|
|
25
|
+
* Attach create/update/delete hooks to an entity schema that holds sensitive
|
|
26
|
+
* fields, so every change to one of its records is reported without the app
|
|
27
|
+
* wiring anything.
|
|
28
|
+
*/
|
|
29
|
+
export declare function installComplianceChangeHooks(schema: EntitySchema, entityName: string, levels: Map<string, ComplianceLevel>): void;
|
|
30
|
+
//# sourceMappingURL=complianceChanges.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complianceChanges.d.ts","sourceRoot":"","sources":["../../src/persistence/complianceChanges.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAa,MAAM,iBAAiB,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGzD;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACvC,0EAA0E;IAC1E,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,uCAAuC;IACvC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,MAAM,wBAAwB,GAAG,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;AAO9E;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,wBAAwB,GACjC,MAAM,IAAI,CAGZ;AAaD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,YAAY,EACpB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,GACnC,IAAI,CAgCN"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compliancePropertyBuilder.d.ts","sourceRoot":"","sources":["../../src/persistence/compliancePropertyBuilder.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"compliancePropertyBuilder.d.ts","sourceRoot":"","sources":["../../src/persistence/compliancePropertyBuilder.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAgRjE;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,EAAE,EAAE,gBAsCK,CAAC"}
|
|
@@ -63,6 +63,24 @@ export declare class LegacyCiphertextError extends Error {
|
|
|
63
63
|
export declare class CompliantQueryError extends Error {
|
|
64
64
|
readonly name: 'CompliantQueryError';
|
|
65
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Thrown when a compliant field is read or written while a tenant other than
|
|
68
|
+
* the one that owns it is bound.
|
|
69
|
+
*
|
|
70
|
+
* A field belongs to the tenant it was loaded under (or, for a value assigned
|
|
71
|
+
* in-process, the tenant bound when it was assigned), and `.deanon` decrypts
|
|
72
|
+
* with that tenant's key whatever context is bound at read time. A different
|
|
73
|
+
* bound tenant means the value is about to cross into another tenant's
|
|
74
|
+
* request, so it is refused rather than revealed or re-sealed.
|
|
75
|
+
*/
|
|
76
|
+
export declare class TenantMismatchError extends Error {
|
|
77
|
+
readonly path: string;
|
|
78
|
+
readonly operation: string;
|
|
79
|
+
readonly ownerTenantId: string;
|
|
80
|
+
readonly boundTenantId: string;
|
|
81
|
+
readonly name: 'TenantMismatchError';
|
|
82
|
+
constructor(path: string, operation: string, ownerTenantId: string, boundTenantId: string);
|
|
83
|
+
}
|
|
66
84
|
/**
|
|
67
85
|
* A de-identified value, produced only by a compliant field's `.anon`.
|
|
68
86
|
* Anything that must never carry protected data (a message to a provider
|
|
@@ -88,8 +106,12 @@ export declare function defaultAnonStrategy(elementRuntimeType: string, isArray:
|
|
|
88
106
|
* `[object Object]` and serializing it prints `{}`, so nothing leaks by
|
|
89
107
|
* accident and every read is explicit.
|
|
90
108
|
*
|
|
91
|
-
* Plaintext is decrypted lazily, on the first `.deanon`,
|
|
92
|
-
*
|
|
109
|
+
* Plaintext is decrypted lazily, on the first `.deanon`, with the key of the
|
|
110
|
+
* tenant the field was loaded (or assigned) under. That tenant is captured
|
|
111
|
+
* when the row is hydrated, so `.deanon` works after the call that loaded it
|
|
112
|
+
* has returned (building a DTO outside the tenant-bound entity manager) and
|
|
113
|
+
* can never decrypt under a different tenant: if another tenant is bound at
|
|
114
|
+
* read time it throws {@link TenantMismatchError}.
|
|
93
115
|
*
|
|
94
116
|
* Assigning a plain value to the property (directly, through `em.create` or
|
|
95
117
|
* through `em.assign`) wraps it; `where: { property: value }` works for
|
|
@@ -108,12 +130,17 @@ export declare class CompliantField<V = unknown, L extends EncryptedComplianceLe
|
|
|
108
130
|
readonly __level?: L;
|
|
109
131
|
private constructor();
|
|
110
132
|
/**
|
|
111
|
-
* @internal Wrap a plaintext value for `spec
|
|
112
|
-
*
|
|
133
|
+
* @internal Wrap a plaintext value for `spec`, owned by `tenant` (the one
|
|
134
|
+
* bound where it was assigned, if any). Applications assign plain values to
|
|
135
|
+
* the entity property instead.
|
|
113
136
|
*/
|
|
114
|
-
static fromPlain<V>(value: V, spec: CompliantFieldSpec): CompliantField<V>;
|
|
115
|
-
/**
|
|
116
|
-
|
|
137
|
+
static fromPlain<V>(value: V, spec: CompliantFieldSpec, tenant: string | undefined): CompliantField<V>;
|
|
138
|
+
/**
|
|
139
|
+
* @internal Wrap a stored value (any envelope, or legacy plaintext) loaded
|
|
140
|
+
* under `tenant`: the tenant bound during hydration, which is the loading
|
|
141
|
+
* entity manager's.
|
|
142
|
+
*/
|
|
143
|
+
static fromStored<V>(stored: string, spec: CompliantFieldSpec, index: string | null | undefined, tenant: string | undefined): CompliantField<V>;
|
|
117
144
|
/** @internal A queryable field whose ciphertext column was not selected. */
|
|
118
145
|
static fromIndexOnly<V>(index: string | null, spec: CompliantFieldSpec): CompliantField<V>;
|
|
119
146
|
/** The field's classification. */
|
|
@@ -129,7 +156,7 @@ export declare function isCompliantField(value: unknown): value is CompliantFiel
|
|
|
129
156
|
export declare function sealedValueOf(field: CompliantField): string | undefined;
|
|
130
157
|
/** @internal Normalize an already-serialized value for indexing. */
|
|
131
158
|
export declare function normalizeSerializedForIndex(serialized: string, spec: CompliantFieldSpec): string;
|
|
132
|
-
/** @internal Blind index of a raw query value. */
|
|
159
|
+
/** @internal Blind index of a raw query value, under the bound tenant. */
|
|
133
160
|
export declare function blindIndexOfValue(value: unknown, spec: CompliantFieldSpec): string;
|
|
134
161
|
/** @internal The blind index for a field, computing it when missing. */
|
|
135
162
|
export declare function blindIndexOf(field: CompliantField): string | null;
|
|
@@ -140,6 +167,12 @@ export interface PendingIndex {
|
|
|
140
167
|
}
|
|
141
168
|
export declare function isPendingIndex(value: unknown): value is PendingIndex;
|
|
142
169
|
export declare function pendingIndexValue(value: PendingIndex): string | null;
|
|
170
|
+
/**
|
|
171
|
+
* @internal The `runtimeType` of a compliant property: what it holds in
|
|
172
|
+
* memory. Deliberately not one of MikroORM's scalar names, which it checks
|
|
173
|
+
* assigned values against.
|
|
174
|
+
*/
|
|
175
|
+
export declare const COMPLIANT_RUNTIME_TYPE = "CompliantField";
|
|
143
176
|
declare abstract class CompliantTypeBase extends Type<unknown, string | null> {
|
|
144
177
|
readonly spec: CompliantFieldSpec;
|
|
145
178
|
constructor(spec: CompliantFieldSpec);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compliantField.d.ts","sourceRoot":"","sources":["../../src/persistence/compliantField.ts"],"names":[],"mappings":"AACA,OAAO,EACL,IAAI,EACJ,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAkBlE;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE1E,8EAA8E;AAC9E,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;CAC5C;AAED,uEAAuE;AACvE,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,wBAAwB,CAAC;IAChC,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,GAAG,WAAW,CAAC;IACjC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IAChC,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;CACd;AAMD,8EAA8E;AAC9E,MAAM,WAAW,qBAAqB;IACpC,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,wBAAwB,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,wBAAwB,GAAG,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;AAO9E;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,wBAAwB,GACjC,MAAM,IAAI,CAGZ;AAMD;;;;GAIG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,EAAG,uBAAuB,CAAU;CAClD;AAED,+EAA+E;AAC/E,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAG,qBAAqB,CAAU;CAChD;AASD;;;;;GAKG;AACH,qBAAa,IAAI;IACf,QAAQ,CAAC,KAAK,EAAG,MAAM,CAAC;IAExB,gBAAgB;IAChB,YAAY,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAOrC;CACF;AAED,mFAAmF;AACnF,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,IAAI,CAMpD;AA0BD,gBAAgB;AAChB,wBAAgB,WAAW,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAwB1E;AAED,0DAA0D;AAC1D,wBAAgB,mBAAmB,CACjC,kBAAkB,EAAE,MAAM,EAC1B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,GACf,YAAY,CAKd;
|
|
1
|
+
{"version":3,"file":"compliantField.d.ts","sourceRoot":"","sources":["../../src/persistence/compliantField.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defineComplianceEntity.d.ts","sourceRoot":"","sources":["../../src/persistence/defineComplianceEntity.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,4BAA4B,EACjC,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC/B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAML,KAAK,eAAe,EACpB,KAAK,eAAe,EACrB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"defineComplianceEntity.d.ts","sourceRoot":"","sources":["../../src/persistence/defineComplianceEntity.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,4BAA4B,EACjC,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC/B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAML,KAAK,eAAe,EACpB,KAAK,eAAe,EACrB,MAAM,mBAAmB,CAAC;AA8E3B,KAAK,kBAAkB,CAAC,CAAC,IAAI;KAC1B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAChB;QAAE,UAAU,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAA;SAAE,CAAA;KAAE,GAClD,CAAC,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,GAC/B,CAAC,CAAC,CAAC,CAAC,GACJ;QAAE,UAAU,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAA;SAAE,CAAA;KAAE;CACvD,CAAC;AAQF,wBAAgB,sBAAsB,CACpC,KAAK,CAAC,KAAK,SAAS,MAAM,EAC1B,KAAK,CAAC,UAAU,SAAS,MAAM,EAC/B,KAAK,CAAC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjD,KAAK,CAAC,GAAG,SAAS,CAAC,MAAM,WAAW,CAAC,EAAE,GAAG,SAAS,GAAG,SAAS,EAC/D,KAAK,CAAC,KAAK,GAAG,KAAK,EACnB,KAAK,CAAC,WAAW,GAAG,KAAK,EACzB,KAAK,CAAC,YAAY,SAAS,OAAO,GAAG,KAAK,EAE1C,IAAI,EAAE,4BAA4B,CAChC,KAAK,EACL,UAAU,EACV,WAAW,GAAG,kBAAkB,CAAC,WAAW,CAAC,EAC7C,GAAG,EACH,KAAK,EACL,WAAW,EACX,YAAY,CACb,GAAG;IAAE,SAAS,CAAC,EAAE,eAAe,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GACxD,oBAAoB,CACrB,KAAK,EACL,UAAU,EACV,yBAAyB,CAAC,WAAW,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,CAAC,EAC7E,KAAK,EACL,WAAW,CACZ,CA+FA"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export { ComplianceLevel, type ComplianceLevel as ComplianceLevelType, getComplianceMetadata, getEntityComplianceFields, entityHasEncryptedFields, RetentionAction, type RetentionAction as RetentionActionType, type RetentionPolicy, RetentionDuration, parseDuration, subtractDuration, type ParsedDuration, getEntityRetention, getAllRetentionPolicies, getEntityUserIdField, getAllUserIdFields, type CompliantValue, type EncryptedComplianceLevel, type EncryptedKeysOf, type RequiresEncryptionContext, type SelectionAvoidsEncryptedColumns } from './complianceTypes';
|
|
2
2
|
export { wrapEmWithForgivingDecryption, type ForgivingDecryptionLogger } from './forgivingDecryptionEm';
|
|
3
3
|
export { asEncryptionSafe, type ContextFreeKeysOfSchema, type ContextFreeReadOptions, type DecryptingReadOptions, type EncryptedKeysOfSchema, type EncryptionAwareReadOptions, type EncryptionSafeEntityManager, type HydratingReadMethod, type PropertiesOfSchema, type SchemaRequiresEncryptionContext } from './encryptionSafeEm';
|
|
4
|
-
export { Anon, CompliantField, CompliantIndexType, CompliantQueryError, CompliantType, LegacyCiphertextError, deanon, isAnon, isCompliantField, onComplianceAccess, type AnonStrategy, type ComplianceAccessEvent, type ComplianceAccessListener, type ComplianceOptions, type Deanon, type Deanonymized } from './compliantField';
|
|
4
|
+
export { Anon, CompliantField, CompliantIndexType, CompliantQueryError, TenantMismatchError, CompliantType, LegacyCiphertextError, deanon, isAnon, isCompliantField, onComplianceAccess, type AnonStrategy, type ComplianceAccessEvent, type ComplianceAccessListener, type ComplianceOptions, type Deanon, type Deanonymized } from './compliantField';
|
|
5
5
|
export { fp } from './compliancePropertyBuilder';
|
|
6
6
|
export { defineComplianceEntity } from './defineComplianceEntity';
|
|
7
7
|
export { wrapEmWithNativeQueryBlocking } from './complianceEventSubscriber';
|
|
8
|
+
export { onComplianceChange, type ComplianceChangeEvent, type ComplianceChangeListener } from './complianceChanges';
|
|
8
9
|
export { EncryptedType, registerEncryptor, setEncryptionTenantId, withEncryptionContext, getCurrentTenantId, getBoundTenantId, assertBindableTenantId, EmptyTenantError, UnboundTenantError } from './encryptedType';
|
|
9
10
|
export { FieldEncryptor, MissingEncryptionKeyError, DecryptionError, EncryptionRequiredError, parseEncryptionKeyList, encryptionKeyId, stampedKeyId, stampedPrefix, isEncryptedCiphertext, sealedAnon, BLIND_INDEX_PREFIX, ENCRYPTED_PREFIXES, ENCRYPTION_FORMAT_ENV, ENCRYPTION_KEY_ENV, LEGACY_ENCRYPTION_KEYS_ENV, LEGACY_ENCRYPTION_KEY_ENV, type FieldEncryptorOptions, type OpenedCiphertext, type CiphertextFormat } from './fieldEncryptor';
|
|
10
11
|
export { reencryptEncryptedColumns, classifyEncryptedValue, collectFallbackTenantIds, defaultTenantIdsFor, entityMetadataList, rotationTotals, countValuesByKeyId, isEncryptedValue, type ReencryptOptions, type RotationOutcome, type RotationTableReport, type SqlExecute, type EntityMetadataLike } from './keyRotation';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/persistence/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,KAAK,eAAe,IAAI,mBAAmB,EAC3C,qBAAqB,EACrB,yBAAyB,EACzB,wBAAwB,EAExB,eAAe,EACf,KAAK,eAAe,IAAI,mBAAmB,EAC3C,KAAK,eAAe,EACpB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,KAAK,cAAc,EACnB,kBAAkB,EAClB,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,KAAK,cAAc,EACnB,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,KAAK,yBAAyB,EAC9B,KAAK,+BAA+B,EACrC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,6BAA6B,EAC7B,KAAK,yBAAyB,EAC/B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,+BAA+B,EACrC,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EACL,IAAI,EACJ,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,EACb,qBAAqB,EACrB,MAAM,EACN,MAAM,EACN,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,iBAAiB,EACtB,KAAK,MAAM,EACX,KAAK,YAAY,EAClB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,EAAE,EAAE,MAAM,6BAA6B,CAAC;AAGjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/persistence/index.ts"],"names":[],"mappings":"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"}
|
package/lib/persistence/index.js
CHANGED
|
@@ -53,6 +53,7 @@ __export(persistence_exports, {
|
|
|
53
53
|
RetentionDuration: () => RetentionDuration,
|
|
54
54
|
RlsEventSubscriber: () => RlsEventSubscriber,
|
|
55
55
|
TENANT_FILTER_NAME: () => TENANT_FILTER_NAME,
|
|
56
|
+
TenantMismatchError: () => TenantMismatchError,
|
|
56
57
|
UnboundTenantError: () => UnboundTenantError,
|
|
57
58
|
asEncryptionSafe: () => asEncryptionSafe,
|
|
58
59
|
assertBindableTenantId: () => assertBindableTenantId,
|
|
@@ -81,6 +82,7 @@ __export(persistence_exports, {
|
|
|
81
82
|
isEncryptedCiphertext: () => isEncryptedCiphertext,
|
|
82
83
|
isEncryptedValue: () => isEncryptedValue,
|
|
83
84
|
onComplianceAccess: () => onComplianceAccess,
|
|
85
|
+
onComplianceChange: () => onComplianceChange,
|
|
84
86
|
parseDuration: () => parseDuration,
|
|
85
87
|
parseEncryptionKeyList: () => parseEncryptionKeyList,
|
|
86
88
|
reencryptEncryptedColumns: () => reencryptEncryptedColumns,
|
|
@@ -827,6 +829,22 @@ var LegacyCiphertextError = class extends Error {
|
|
|
827
829
|
var CompliantQueryError = class extends Error {
|
|
828
830
|
name = "CompliantQueryError";
|
|
829
831
|
};
|
|
832
|
+
var TenantMismatchError = class extends Error {
|
|
833
|
+
constructor(path, operation, ownerTenantId, boundTenantId) {
|
|
834
|
+
super(
|
|
835
|
+
`Cannot ${operation} ${path || "a compliant field"} under tenant '${boundTenantId}': it belongs to tenant '${ownerTenantId}', the tenant it was loaded or assigned under. Read it outside any encryption context, or inside the owning tenant's.`
|
|
836
|
+
);
|
|
837
|
+
this.path = path;
|
|
838
|
+
this.operation = operation;
|
|
839
|
+
this.ownerTenantId = ownerTenantId;
|
|
840
|
+
this.boundTenantId = boundTenantId;
|
|
841
|
+
}
|
|
842
|
+
path;
|
|
843
|
+
operation;
|
|
844
|
+
ownerTenantId;
|
|
845
|
+
boundTenantId;
|
|
846
|
+
name = "TenantMismatchError";
|
|
847
|
+
};
|
|
830
848
|
var MINT = /* @__PURE__ */ Symbol.for("forklaunch.compliance.mint");
|
|
831
849
|
var ANON_BRAND = /* @__PURE__ */ Symbol.for("forklaunch.compliance.anon");
|
|
832
850
|
var Anon = class {
|
|
@@ -907,10 +925,11 @@ var CompliantField = class _CompliantField {
|
|
|
907
925
|
Object.freeze(this);
|
|
908
926
|
}
|
|
909
927
|
/**
|
|
910
|
-
* @internal Wrap a plaintext value for `spec
|
|
911
|
-
*
|
|
928
|
+
* @internal Wrap a plaintext value for `spec`, owned by `tenant` (the one
|
|
929
|
+
* bound where it was assigned, if any). Applications assign plain values to
|
|
930
|
+
* the entity property instead.
|
|
912
931
|
*/
|
|
913
|
-
static fromPlain(value, spec) {
|
|
932
|
+
static fromPlain(value, spec, tenant) {
|
|
914
933
|
if (spec.enumValues) {
|
|
915
934
|
const values = spec.isArray && Array.isArray(value) ? value : [value];
|
|
916
935
|
for (const v of values) {
|
|
@@ -923,16 +942,22 @@ var CompliantField = class _CompliantField {
|
|
|
923
942
|
}
|
|
924
943
|
return new _CompliantField({
|
|
925
944
|
spec,
|
|
945
|
+
tenant,
|
|
926
946
|
hasPlain: true,
|
|
927
947
|
plain: value,
|
|
928
948
|
anon: computeAnon(spec.anon, value)
|
|
929
949
|
});
|
|
930
950
|
}
|
|
931
|
-
/**
|
|
932
|
-
|
|
951
|
+
/**
|
|
952
|
+
* @internal Wrap a stored value (any envelope, or legacy plaintext) loaded
|
|
953
|
+
* under `tenant`: the tenant bound during hydration, which is the loading
|
|
954
|
+
* entity manager's.
|
|
955
|
+
*/
|
|
956
|
+
static fromStored(stored, spec, index, tenant) {
|
|
933
957
|
if (!isEncryptedCiphertext(stored)) {
|
|
934
958
|
return new _CompliantField({
|
|
935
959
|
spec,
|
|
960
|
+
tenant,
|
|
936
961
|
hasPlain: true,
|
|
937
962
|
plain: deserializeFromEncryption(
|
|
938
963
|
stored,
|
|
@@ -944,6 +969,7 @@ var CompliantField = class _CompliantField {
|
|
|
944
969
|
}
|
|
945
970
|
return new _CompliantField({
|
|
946
971
|
spec,
|
|
972
|
+
tenant,
|
|
947
973
|
hasPlain: false,
|
|
948
974
|
sealed: stored,
|
|
949
975
|
anon: sealedAnon(stored) ?? void 0,
|
|
@@ -976,11 +1002,24 @@ var CompliantField = class _CompliantField {
|
|
|
976
1002
|
return readPlaintext(this, true);
|
|
977
1003
|
}
|
|
978
1004
|
};
|
|
1005
|
+
function tenantOf(state, operation) {
|
|
1006
|
+
const bound = getBoundTenantId();
|
|
1007
|
+
if (state.tenant === void 0) return requireBoundTenantId(operation);
|
|
1008
|
+
if (bound !== void 0 && bound !== state.tenant) {
|
|
1009
|
+
throw new TenantMismatchError(
|
|
1010
|
+
state.spec.path,
|
|
1011
|
+
operation,
|
|
1012
|
+
state.tenant,
|
|
1013
|
+
bound
|
|
1014
|
+
);
|
|
1015
|
+
}
|
|
1016
|
+
return state.tenant;
|
|
1017
|
+
}
|
|
979
1018
|
function readPlaintext(field, report) {
|
|
980
1019
|
const state = stateOf(field);
|
|
981
1020
|
let tenantId = "";
|
|
982
1021
|
if (!state.hasPlain) {
|
|
983
|
-
tenantId =
|
|
1022
|
+
tenantId = tenantOf(state, "read");
|
|
984
1023
|
if (state.sealed === void 0) {
|
|
985
1024
|
throw new Error(
|
|
986
1025
|
`${state.spec.path} was not loaded: its ciphertext column was left out of the selection`
|
|
@@ -999,6 +1038,8 @@ function readPlaintext(field, report) {
|
|
|
999
1038
|
state.spec.isArray
|
|
1000
1039
|
);
|
|
1001
1040
|
state.hasPlain = true;
|
|
1041
|
+
} else if (state.tenant !== void 0) {
|
|
1042
|
+
tenantId = tenantOf(state, "read");
|
|
1002
1043
|
}
|
|
1003
1044
|
if (report) {
|
|
1004
1045
|
tenantId ||= getBoundTenantId() ?? "";
|
|
@@ -1026,10 +1067,11 @@ function sealedValueOf(field) {
|
|
|
1026
1067
|
return state.sealed;
|
|
1027
1068
|
}
|
|
1028
1069
|
if (!state.hasPlain) return state.sealed;
|
|
1029
|
-
|
|
1030
|
-
if (state.sealed !== void 0 && state.sealedTenant === tenantId) {
|
|
1070
|
+
if (state.sealed !== void 0 && state.sealedTenant === state.tenant) {
|
|
1031
1071
|
return state.sealed;
|
|
1032
1072
|
}
|
|
1073
|
+
const tenantId = tenantOf(state, "write");
|
|
1074
|
+
state.tenant = tenantId;
|
|
1033
1075
|
if (state.anon === void 0) {
|
|
1034
1076
|
state.anon = computeAnon(state.spec.anon, state.plain);
|
|
1035
1077
|
}
|
|
@@ -1048,9 +1090,12 @@ function normalizedForIndex(value, spec) {
|
|
|
1048
1090
|
return normalizeSerializedForIndex(serializeForEncryption(value), spec);
|
|
1049
1091
|
}
|
|
1050
1092
|
function blindIndexOfValue(value, spec) {
|
|
1093
|
+
return blindIndexUnder(value, spec, requireBoundTenantId("query"));
|
|
1094
|
+
}
|
|
1095
|
+
function blindIndexUnder(value, spec, tenantId) {
|
|
1051
1096
|
return requireEncryptor(spec.path).blindIndex(
|
|
1052
1097
|
normalizedForIndex(value, spec),
|
|
1053
|
-
|
|
1098
|
+
tenantId
|
|
1054
1099
|
);
|
|
1055
1100
|
}
|
|
1056
1101
|
function blindIndexOf(field) {
|
|
@@ -1059,7 +1104,7 @@ function blindIndexOf(field) {
|
|
|
1059
1104
|
if (!state.hasPlain && state.sealed === void 0) return state.index ?? null;
|
|
1060
1105
|
try {
|
|
1061
1106
|
const plain = state.hasPlain ? state.plain : readPlaintext(field, false);
|
|
1062
|
-
state.index =
|
|
1107
|
+
state.index = blindIndexUnder(plain, state.spec, tenantOf(state, "index"));
|
|
1063
1108
|
} catch {
|
|
1064
1109
|
return state.index ?? null;
|
|
1065
1110
|
}
|
|
@@ -1072,6 +1117,7 @@ function isPendingIndex(value) {
|
|
|
1072
1117
|
function pendingIndexValue(value) {
|
|
1073
1118
|
return value[PENDING];
|
|
1074
1119
|
}
|
|
1120
|
+
var COMPLIANT_RUNTIME_TYPE = "CompliantField";
|
|
1075
1121
|
var CompliantTypeBase = class extends import_core2.Type {
|
|
1076
1122
|
constructor(spec) {
|
|
1077
1123
|
super();
|
|
@@ -1082,7 +1128,7 @@ var CompliantTypeBase = class extends import_core2.Type {
|
|
|
1082
1128
|
return "text";
|
|
1083
1129
|
}
|
|
1084
1130
|
get runtimeType() {
|
|
1085
|
-
return
|
|
1131
|
+
return COMPLIANT_RUNTIME_TYPE;
|
|
1086
1132
|
}
|
|
1087
1133
|
ensureComparable() {
|
|
1088
1134
|
return false;
|
|
@@ -1101,12 +1147,19 @@ var CompliantType = class extends CompliantTypeBase {
|
|
|
1101
1147
|
if (value === null || value === void 0) return null;
|
|
1102
1148
|
if (isCompliantField(value)) return sealedValueOf(value) ?? null;
|
|
1103
1149
|
if (isEncryptedCiphertext(value)) return value;
|
|
1104
|
-
return sealedValueOf(
|
|
1150
|
+
return sealedValueOf(
|
|
1151
|
+
CompliantField.fromPlain(value, this.spec, getBoundTenantId())
|
|
1152
|
+
) ?? null;
|
|
1105
1153
|
}
|
|
1106
1154
|
convertToJSValue(value) {
|
|
1107
1155
|
if (value === null || value === void 0) return value;
|
|
1108
1156
|
if (isCompliantField(value)) return value;
|
|
1109
|
-
return CompliantField.fromStored(
|
|
1157
|
+
return CompliantField.fromStored(
|
|
1158
|
+
String(value),
|
|
1159
|
+
this.spec,
|
|
1160
|
+
void 0,
|
|
1161
|
+
getBoundTenantId()
|
|
1162
|
+
);
|
|
1110
1163
|
}
|
|
1111
1164
|
};
|
|
1112
1165
|
var EQUALITY_OPERATORS = /* @__PURE__ */ new Set(["$eq", "$ne", "$in", "$nin"]);
|
|
@@ -1135,6 +1188,18 @@ function isCompliantType(type) {
|
|
|
1135
1188
|
return type instanceof CompliantType || type instanceof CompliantIndexType;
|
|
1136
1189
|
}
|
|
1137
1190
|
var SLOTS = globalThis[/* @__PURE__ */ Symbol.for("forklaunch.compliance.slots")] ??= /* @__PURE__ */ new WeakMap();
|
|
1191
|
+
var LOADED_TENANTS = globalThis[/* @__PURE__ */ Symbol.for("forklaunch.compliance.loadedTenants")] ??= /* @__PURE__ */ new WeakMap();
|
|
1192
|
+
function loadedTenantOf(entity, binding) {
|
|
1193
|
+
return LOADED_TENANTS.get(entity)?.[binding.property];
|
|
1194
|
+
}
|
|
1195
|
+
function recordLoadedTenant(entity, binding) {
|
|
1196
|
+
let tenants = LOADED_TENANTS.get(entity);
|
|
1197
|
+
if (!tenants) {
|
|
1198
|
+
tenants = {};
|
|
1199
|
+
LOADED_TENANTS.set(entity, tenants);
|
|
1200
|
+
}
|
|
1201
|
+
tenants[binding.property] = getBoundTenantId();
|
|
1202
|
+
}
|
|
1138
1203
|
function slotsOf(entity) {
|
|
1139
1204
|
let slots = SLOTS.get(entity);
|
|
1140
1205
|
if (!slots) {
|
|
@@ -1150,12 +1215,22 @@ function readProperty(entity, binding) {
|
|
|
1150
1215
|
const stored = slots[binding.sibling];
|
|
1151
1216
|
if (isPendingIndex(value)) {
|
|
1152
1217
|
const index = pendingIndexValue(value);
|
|
1153
|
-
const field = typeof stored === "string" ? CompliantField.fromStored(
|
|
1218
|
+
const field = typeof stored === "string" ? CompliantField.fromStored(
|
|
1219
|
+
stored,
|
|
1220
|
+
binding.spec,
|
|
1221
|
+
index,
|
|
1222
|
+
loadedTenantOf(entity, binding)
|
|
1223
|
+
) : CompliantField.fromIndexOnly(index, binding.spec);
|
|
1154
1224
|
slots[binding.property] = field;
|
|
1155
1225
|
return field;
|
|
1156
1226
|
}
|
|
1157
1227
|
if (value == null && typeof stored === "string") {
|
|
1158
|
-
const field = CompliantField.fromStored(
|
|
1228
|
+
const field = CompliantField.fromStored(
|
|
1229
|
+
stored,
|
|
1230
|
+
binding.spec,
|
|
1231
|
+
null,
|
|
1232
|
+
loadedTenantOf(entity, binding)
|
|
1233
|
+
);
|
|
1159
1234
|
slots[binding.property] = field;
|
|
1160
1235
|
return field;
|
|
1161
1236
|
}
|
|
@@ -1177,10 +1252,18 @@ function writeProperty(entity, binding, value) {
|
|
|
1177
1252
|
return;
|
|
1178
1253
|
}
|
|
1179
1254
|
if (isCompliantField(value)) {
|
|
1180
|
-
slots[binding.property] = sameRules(stateOf(value).spec, binding.spec) ? value : CompliantField.fromPlain(
|
|
1255
|
+
slots[binding.property] = sameRules(stateOf(value).spec, binding.spec) ? value : CompliantField.fromPlain(
|
|
1256
|
+
readPlaintext(value, false),
|
|
1257
|
+
binding.spec,
|
|
1258
|
+
stateOf(value).tenant ?? getBoundTenantId()
|
|
1259
|
+
);
|
|
1181
1260
|
return;
|
|
1182
1261
|
}
|
|
1183
|
-
slots[binding.property] = CompliantField.fromPlain(
|
|
1262
|
+
slots[binding.property] = CompliantField.fromPlain(
|
|
1263
|
+
value,
|
|
1264
|
+
binding.spec,
|
|
1265
|
+
getBoundTenantId()
|
|
1266
|
+
);
|
|
1184
1267
|
}
|
|
1185
1268
|
function installCompliantAccessors(prototype, bindings) {
|
|
1186
1269
|
installInspect(prototype, bindings);
|
|
@@ -1207,6 +1290,7 @@ function installCompliantAccessors(prototype, bindings) {
|
|
|
1207
1290
|
return sealedValueOf(field) ?? stored;
|
|
1208
1291
|
},
|
|
1209
1292
|
set(value) {
|
|
1293
|
+
recordLoadedTenant(this, binding);
|
|
1210
1294
|
slotsOf(this)[sibling] = value;
|
|
1211
1295
|
}
|
|
1212
1296
|
});
|
|
@@ -1315,7 +1399,7 @@ function wrapClassified(builder, level, complianceOptions) {
|
|
|
1315
1399
|
};
|
|
1316
1400
|
options.type = spec.queryable ? new CompliantIndexType(spec) : new CompliantType(spec);
|
|
1317
1401
|
options.columnType = "text";
|
|
1318
|
-
options.runtimeType =
|
|
1402
|
+
options.runtimeType = COMPLIANT_RUNTIME_TYPE;
|
|
1319
1403
|
options.accessor = true;
|
|
1320
1404
|
}
|
|
1321
1405
|
}
|
|
@@ -1419,6 +1503,47 @@ var fp = new Proxy(import_core3.p, {
|
|
|
1419
1503
|
|
|
1420
1504
|
// src/persistence/defineComplianceEntity.ts
|
|
1421
1505
|
var import_core4 = require("@mikro-orm/core");
|
|
1506
|
+
|
|
1507
|
+
// src/persistence/complianceChanges.ts
|
|
1508
|
+
var LISTENERS2 = globalThis[/* @__PURE__ */ Symbol.for("forklaunch.compliance.changeListeners")] ??= /* @__PURE__ */ new Set();
|
|
1509
|
+
function onComplianceChange(listener) {
|
|
1510
|
+
LISTENERS2.add(listener);
|
|
1511
|
+
return () => LISTENERS2.delete(listener);
|
|
1512
|
+
}
|
|
1513
|
+
function emit(event) {
|
|
1514
|
+
for (const listener of LISTENERS2) {
|
|
1515
|
+
try {
|
|
1516
|
+
listener(event);
|
|
1517
|
+
} catch (error) {
|
|
1518
|
+
console.error("Compliance change listener failed:", error);
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
function installComplianceChangeHooks(schema, entityName, levels) {
|
|
1523
|
+
const sensitive = new Set(
|
|
1524
|
+
[...levels].filter(([, level]) => level !== "none").map(([name]) => name)
|
|
1525
|
+
);
|
|
1526
|
+
if (!sensitive.size) return;
|
|
1527
|
+
const report = (action) => (args) => {
|
|
1528
|
+
if (!LISTENERS2.size) return;
|
|
1529
|
+
const entity = args.entity;
|
|
1530
|
+
const keys = args.meta?.primaryKeys ?? ["id"];
|
|
1531
|
+
const fields = action === "update" ? Object.keys(args.changeSet?.payload ?? {}) : action === "create" ? [...levels.keys()].filter((name) => entity[name] !== void 0) : [];
|
|
1532
|
+
emit({
|
|
1533
|
+
entity: entityName,
|
|
1534
|
+
id: keys.map((key) => String(entity[key] ?? "")).join(":"),
|
|
1535
|
+
action,
|
|
1536
|
+
fields,
|
|
1537
|
+
sensitiveFields: action === "delete" ? [...sensitive] : fields.filter((name) => sensitive.has(name)),
|
|
1538
|
+
tenantId: getBoundTenantId() ?? null
|
|
1539
|
+
});
|
|
1540
|
+
};
|
|
1541
|
+
schema.addHook("afterCreate", report("create"));
|
|
1542
|
+
schema.addHook("afterUpdate", report("update"));
|
|
1543
|
+
schema.addHook("afterDelete", report("delete"));
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
// src/persistence/defineComplianceEntity.ts
|
|
1422
1547
|
var naming = new import_core4.UnderscoreNamingStrategy();
|
|
1423
1548
|
function wireCompliantProperties(entityName, properties) {
|
|
1424
1549
|
const wired = {};
|
|
@@ -1498,6 +1623,11 @@ function defineComplianceEntity(meta) {
|
|
|
1498
1623
|
...meta,
|
|
1499
1624
|
properties: wired.properties
|
|
1500
1625
|
});
|
|
1626
|
+
installComplianceChangeHooks(
|
|
1627
|
+
schema,
|
|
1628
|
+
entityName,
|
|
1629
|
+
complianceFields
|
|
1630
|
+
);
|
|
1501
1631
|
if (wired.bindings.length > 0) {
|
|
1502
1632
|
const entityClass = schema.meta.class;
|
|
1503
1633
|
if (entityClass)
|
|
@@ -2080,6 +2210,7 @@ function rebind(result, target, proxy) {
|
|
|
2080
2210
|
RetentionDuration,
|
|
2081
2211
|
RlsEventSubscriber,
|
|
2082
2212
|
TENANT_FILTER_NAME,
|
|
2213
|
+
TenantMismatchError,
|
|
2083
2214
|
UnboundTenantError,
|
|
2084
2215
|
asEncryptionSafe,
|
|
2085
2216
|
assertBindableTenantId,
|
|
@@ -2108,6 +2239,7 @@ function rebind(result, target, proxy) {
|
|
|
2108
2239
|
isEncryptedCiphertext,
|
|
2109
2240
|
isEncryptedValue,
|
|
2110
2241
|
onComplianceAccess,
|
|
2242
|
+
onComplianceChange,
|
|
2111
2243
|
parseDuration,
|
|
2112
2244
|
parseEncryptionKeyList,
|
|
2113
2245
|
reencryptEncryptedColumns,
|