life-as-api 0.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/LICENSE +21 -0
- package/README.md +377 -0
- package/dist/agent/finance-agent.d.ts +44 -0
- package/dist/agent/finance-agent.js +75 -0
- package/dist/agent/finance-agent.js.map +1 -0
- package/dist/agent/legal-agent.d.ts +44 -0
- package/dist/agent/legal-agent.js +76 -0
- package/dist/agent/legal-agent.js.map +1 -0
- package/dist/agent/medical-agent.d.ts +44 -0
- package/dist/agent/medical-agent.js +75 -0
- package/dist/agent/medical-agent.js.map +1 -0
- package/dist/agent/trusted-agent-registry.d.ts +53 -0
- package/dist/agent/trusted-agent-registry.js +57 -0
- package/dist/agent/trusted-agent-registry.js.map +1 -0
- package/dist/audit/audit-chain-verifier.d.ts +10 -0
- package/dist/audit/audit-chain-verifier.js +67 -0
- package/dist/audit/audit-chain-verifier.js.map +1 -0
- package/dist/audit/audit-log.d.ts +48 -0
- package/dist/audit/audit-log.js +74 -0
- package/dist/audit/audit-log.js.map +1 -0
- package/dist/audit/sqlite-audit-log.d.ts +29 -0
- package/dist/audit/sqlite-audit-log.js +142 -0
- package/dist/audit/sqlite-audit-log.js.map +1 -0
- package/dist/auth/access-context-issuer.d.ts +18 -0
- package/dist/auth/access-context-issuer.js +88 -0
- package/dist/auth/access-context-issuer.js.map +1 -0
- package/dist/auth/assert-authorized-for-subject.d.ts +2 -0
- package/dist/auth/assert-authorized-for-subject.js +20 -0
- package/dist/auth/assert-authorized-for-subject.js.map +1 -0
- package/dist/auth/backend-context-minting-boundary.d.ts +23 -0
- package/dist/auth/backend-context-minting-boundary.js +281 -0
- package/dist/auth/backend-context-minting-boundary.js.map +1 -0
- package/dist/auth/default-authorization-policy.d.ts +7 -0
- package/dist/auth/default-authorization-policy.js +64 -0
- package/dist/auth/default-authorization-policy.js.map +1 -0
- package/dist/auth/fake-auth-adapter.d.ts +7 -0
- package/dist/auth/fake-auth-adapter.js +27 -0
- package/dist/auth/fake-auth-adapter.js.map +1 -0
- package/dist/auth/http-client.d.ts +12 -0
- package/dist/auth/http-client.js +7 -0
- package/dist/auth/http-client.js.map +1 -0
- package/dist/auth/in-memory-grant-resolver.d.ts +21 -0
- package/dist/auth/in-memory-grant-resolver.js +73 -0
- package/dist/auth/in-memory-grant-resolver.js.map +1 -0
- package/dist/auth/in-memory-tenant-boundary.d.ts +16 -0
- package/dist/auth/in-memory-tenant-boundary.js +37 -0
- package/dist/auth/in-memory-tenant-boundary.js.map +1 -0
- package/dist/auth/jwks-key-ring-auth-adapter.d.ts +38 -0
- package/dist/auth/jwks-key-ring-auth-adapter.js +123 -0
- package/dist/auth/jwks-key-ring-auth-adapter.js.map +1 -0
- package/dist/auth/jwks-key-ring.d.ts +25 -0
- package/dist/auth/jwks-key-ring.js +111 -0
- package/dist/auth/jwks-key-ring.js.map +1 -0
- package/dist/auth/jwt-auth-adapter.d.ts +15 -0
- package/dist/auth/jwt-auth-adapter.js +59 -0
- package/dist/auth/jwt-auth-adapter.js.map +1 -0
- package/dist/auth/jwt-core.d.ts +32 -0
- package/dist/auth/jwt-core.js +226 -0
- package/dist/auth/jwt-core.js.map +1 -0
- package/dist/auth/jwt-key-ring-auth-adapter.d.ts +16 -0
- package/dist/auth/jwt-key-ring-auth-adapter.js +58 -0
- package/dist/auth/jwt-key-ring-auth-adapter.js.map +1 -0
- package/dist/auth/oidc-discovery.d.ts +15 -0
- package/dist/auth/oidc-discovery.js +46 -0
- package/dist/auth/oidc-discovery.js.map +1 -0
- package/dist/auth/production-scoped-life-api.d.ts +58 -0
- package/dist/auth/production-scoped-life-api.js +802 -0
- package/dist/auth/production-scoped-life-api.js.map +1 -0
- package/dist/auth/proposal-scope-inspector.d.ts +3 -0
- package/dist/auth/proposal-scope-inspector.js +42 -0
- package/dist/auth/proposal-scope-inspector.js.map +1 -0
- package/dist/auth/proposal-scoped-life-api.d.ts +21 -0
- package/dist/auth/proposal-scoped-life-api.js +168 -0
- package/dist/auth/proposal-scoped-life-api.js.map +1 -0
- package/dist/auth/rate-limited-context-minting-boundary.d.ts +27 -0
- package/dist/auth/rate-limited-context-minting-boundary.js +77 -0
- package/dist/auth/rate-limited-context-minting-boundary.js.map +1 -0
- package/dist/auth/revocation-aware-auth-adapter.d.ts +21 -0
- package/dist/auth/revocation-aware-auth-adapter.js +88 -0
- package/dist/auth/revocation-aware-auth-adapter.js.map +1 -0
- package/dist/auth/sqlite-grant-resolver.d.ts +8 -0
- package/dist/auth/sqlite-grant-resolver.js +78 -0
- package/dist/auth/sqlite-grant-resolver.js.map +1 -0
- package/dist/auth/sqlite-tenant-boundary.d.ts +7 -0
- package/dist/auth/sqlite-tenant-boundary.js +41 -0
- package/dist/auth/sqlite-tenant-boundary.js.map +1 -0
- package/dist/auth/static-jwt-key-ring.d.ts +13 -0
- package/dist/auth/static-jwt-key-ring.js +73 -0
- package/dist/auth/static-jwt-key-ring.js.map +1 -0
- package/dist/auth/subject-scoped-life-api.d.ts +14 -0
- package/dist/auth/subject-scoped-life-api.js +51 -0
- package/dist/auth/subject-scoped-life-api.js.map +1 -0
- package/dist/auth/test-context-minting-boundary.d.ts +13 -0
- package/dist/auth/test-context-minting-boundary.js +74 -0
- package/dist/auth/test-context-minting-boundary.js.map +1 -0
- package/dist/auth/types.d.ts +77 -0
- package/dist/auth/types.js +16 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/compliance/subject-data-report.d.ts +43 -0
- package/dist/compliance/subject-data-report.js +155 -0
- package/dist/compliance/subject-data-report.js.map +1 -0
- package/dist/consent/consent-guard.d.ts +4 -0
- package/dist/consent/consent-guard.js +37 -0
- package/dist/consent/consent-guard.js.map +1 -0
- package/dist/consent/grant-registry.d.ts +7 -0
- package/dist/consent/grant-registry.js +13 -0
- package/dist/consent/grant-registry.js.map +1 -0
- package/dist/consent/intersect-selector.d.ts +3 -0
- package/dist/consent/intersect-selector.js +66 -0
- package/dist/consent/intersect-selector.js.map +1 -0
- package/dist/contract/diagnostics.d.ts +32 -0
- package/dist/contract/diagnostics.js +112 -0
- package/dist/contract/diagnostics.js.map +1 -0
- package/dist/contract/project-contracts.d.ts +5 -0
- package/dist/contract/project-contracts.js +159 -0
- package/dist/contract/project-contracts.js.map +1 -0
- package/dist/contract/types.d.ts +32 -0
- package/dist/contract/types.js +5 -0
- package/dist/contract/types.js.map +1 -0
- package/dist/crypto/aes-gcm.d.ts +11 -0
- package/dist/crypto/aes-gcm.js +78 -0
- package/dist/crypto/aes-gcm.js.map +1 -0
- package/dist/crypto/claim-serializer.d.ts +26 -0
- package/dist/crypto/claim-serializer.js +59 -0
- package/dist/crypto/claim-serializer.js.map +1 -0
- package/dist/crypto/sha256.d.ts +12 -0
- package/dist/crypto/sha256.js +40 -0
- package/dist/crypto/sha256.js.map +1 -0
- package/dist/crypto/static-key.d.ts +11 -0
- package/dist/crypto/static-key.js +60 -0
- package/dist/crypto/static-key.js.map +1 -0
- package/dist/crypto/types.d.ts +20 -0
- package/dist/crypto/types.js +8 -0
- package/dist/crypto/types.js.map +1 -0
- package/dist/datasource/trusted-data-source-registry.d.ts +51 -0
- package/dist/datasource/trusted-data-source-registry.js +57 -0
- package/dist/datasource/trusted-data-source-registry.js.map +1 -0
- package/dist/erasure/tombstone.d.ts +13 -0
- package/dist/erasure/tombstone.js +20 -0
- package/dist/erasure/tombstone.js.map +1 -0
- package/dist/evidence/evidence-backed-claim-creator.d.ts +48 -0
- package/dist/evidence/evidence-backed-claim-creator.js +107 -0
- package/dist/evidence/evidence-backed-claim-creator.js.map +1 -0
- package/dist/evidence/in-memory-raw-document-store.d.ts +26 -0
- package/dist/evidence/in-memory-raw-document-store.js +84 -0
- package/dist/evidence/in-memory-raw-document-store.js.map +1 -0
- package/dist/evidence/raw-document-store.d.ts +12 -0
- package/dist/evidence/raw-document-store.js +8 -0
- package/dist/evidence/raw-document-store.js.map +1 -0
- package/dist/evidence/source-evidence-validator.d.ts +4 -0
- package/dist/evidence/source-evidence-validator.js +14 -0
- package/dist/evidence/source-evidence-validator.js.map +1 -0
- package/dist/evidence/sqlite-raw-document-store.d.ts +19 -0
- package/dist/evidence/sqlite-raw-document-store.js +122 -0
- package/dist/evidence/sqlite-raw-document-store.js.map +1 -0
- package/dist/guardian/guardian-registry.d.ts +96 -0
- package/dist/guardian/guardian-registry.js +95 -0
- package/dist/guardian/guardian-registry.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/observability/health.d.ts +12 -0
- package/dist/observability/health.js +16 -0
- package/dist/observability/health.js.map +1 -0
- package/dist/observability/logger.d.ts +21 -0
- package/dist/observability/logger.js +40 -0
- package/dist/observability/logger.js.map +1 -0
- package/dist/observability/metrics.d.ts +15 -0
- package/dist/observability/metrics.js +52 -0
- package/dist/observability/metrics.js.map +1 -0
- package/dist/persistence/backup.d.ts +24 -0
- package/dist/persistence/backup.js +251 -0
- package/dist/persistence/backup.js.map +1 -0
- package/dist/persistence/decryptability-scan.d.ts +10 -0
- package/dist/persistence/decryptability-scan.js +144 -0
- package/dist/persistence/decryptability-scan.js.map +1 -0
- package/dist/persistence/in-memory-unit-of-work.d.ts +11 -0
- package/dist/persistence/in-memory-unit-of-work.js +32 -0
- package/dist/persistence/in-memory-unit-of-work.js.map +1 -0
- package/dist/persistence/key-availability.d.ts +9 -0
- package/dist/persistence/key-availability.js +125 -0
- package/dist/persistence/key-availability.js.map +1 -0
- package/dist/persistence/sqlite/migrations.d.ts +9 -0
- package/dist/persistence/sqlite/migrations.js +535 -0
- package/dist/persistence/sqlite/migrations.js.map +1 -0
- package/dist/persistence/sqlite/schema.d.ts +10 -0
- package/dist/persistence/sqlite/schema.js +101 -0
- package/dist/persistence/sqlite/schema.js.map +1 -0
- package/dist/persistence/sqlite/sqlite-fact-store.d.ts +24 -0
- package/dist/persistence/sqlite/sqlite-fact-store.js +207 -0
- package/dist/persistence/sqlite/sqlite-fact-store.js.map +1 -0
- package/dist/persistence/sqlite/sqlite-source-registry.d.ts +17 -0
- package/dist/persistence/sqlite/sqlite-source-registry.js +132 -0
- package/dist/persistence/sqlite/sqlite-source-registry.js.map +1 -0
- package/dist/persistence/sqlite/sqlite-unit-of-work.d.ts +8 -0
- package/dist/persistence/sqlite/sqlite-unit-of-work.js +41 -0
- package/dist/persistence/sqlite/sqlite-unit-of-work.js.map +1 -0
- package/dist/persistence/sqlite/types.d.ts +24 -0
- package/dist/persistence/sqlite/types.js +28 -0
- package/dist/persistence/sqlite/types.js.map +1 -0
- package/dist/persistence/unit-of-work.d.ts +6 -0
- package/dist/persistence/unit-of-work.js +15 -0
- package/dist/persistence/unit-of-work.js.map +1 -0
- package/dist/proposal/accepted-claim-appender.d.ts +7 -0
- package/dist/proposal/accepted-claim-appender.js +16 -0
- package/dist/proposal/accepted-claim-appender.js.map +1 -0
- package/dist/proposal/in-memory-proposal-queue.d.ts +21 -0
- package/dist/proposal/in-memory-proposal-queue.js +218 -0
- package/dist/proposal/in-memory-proposal-queue.js.map +1 -0
- package/dist/proposal/policy-aware-proposal-queue.d.ts +23 -0
- package/dist/proposal/policy-aware-proposal-queue.js +162 -0
- package/dist/proposal/policy-aware-proposal-queue.js.map +1 -0
- package/dist/proposal/proposal-policy.d.ts +37 -0
- package/dist/proposal/proposal-policy.js +72 -0
- package/dist/proposal/proposal-policy.js.map +1 -0
- package/dist/proposal/proposal-queue.d.ts +13 -0
- package/dist/proposal/proposal-queue.js +15 -0
- package/dist/proposal/proposal-queue.js.map +1 -0
- package/dist/proposal/source-aware-claim-appender.d.ts +13 -0
- package/dist/proposal/source-aware-claim-appender.js +47 -0
- package/dist/proposal/source-aware-claim-appender.js.map +1 -0
- package/dist/proposal/sqlite-proposal-queue.d.ts +26 -0
- package/dist/proposal/sqlite-proposal-queue.js +282 -0
- package/dist/proposal/sqlite-proposal-queue.js.map +1 -0
- package/dist/resolution/resolve-claims.d.ts +4 -0
- package/dist/resolution/resolve-claims.js +101 -0
- package/dist/resolution/resolve-claims.js.map +1 -0
- package/dist/resolution/trust-profile.d.ts +12 -0
- package/dist/resolution/trust-profile.js +23 -0
- package/dist/resolution/trust-profile.js.map +1 -0
- package/dist/resolution/types.d.ts +15 -0
- package/dist/resolution/types.js +8 -0
- package/dist/resolution/types.js.map +1 -0
- package/dist/sdk/create-backend-integrated-life-api-for-test.d.ts +23 -0
- package/dist/sdk/create-backend-integrated-life-api-for-test.js +240 -0
- package/dist/sdk/create-backend-integrated-life-api-for-test.js.map +1 -0
- package/dist/sdk/create-life-api.d.ts +55 -0
- package/dist/sdk/create-life-api.js +251 -0
- package/dist/sdk/create-life-api.js.map +1 -0
- package/dist/sdk/create-sqlite-life-api.d.ts +33 -0
- package/dist/sdk/create-sqlite-life-api.js +654 -0
- package/dist/sdk/create-sqlite-life-api.js.map +1 -0
- package/dist/sdk/life-api.d.ts +27 -0
- package/dist/sdk/life-api.js +17 -0
- package/dist/sdk/life-api.js.map +1 -0
- package/dist/sdk/validation.d.ts +8 -0
- package/dist/sdk/validation.js +216 -0
- package/dist/sdk/validation.js.map +1 -0
- package/dist/source/in-memory-source-registry.d.ts +15 -0
- package/dist/source/in-memory-source-registry.js +104 -0
- package/dist/source/in-memory-source-registry.js.map +1 -0
- package/dist/source/source-aware-fact-store.d.ts +19 -0
- package/dist/source/source-aware-fact-store.js +40 -0
- package/dist/source/source-aware-fact-store.js.map +1 -0
- package/dist/source/source-kind-predicate-policy.d.ts +4 -0
- package/dist/source/source-kind-predicate-policy.js +62 -0
- package/dist/source/source-kind-predicate-policy.js.map +1 -0
- package/dist/source/source-registry.d.ts +11 -0
- package/dist/source/source-registry.js +12 -0
- package/dist/source/source-registry.js.map +1 -0
- package/dist/store/in-memory-fact-store.d.ts +25 -0
- package/dist/store/in-memory-fact-store.js +192 -0
- package/dist/store/in-memory-fact-store.js.map +1 -0
- package/dist/surface/context-query.d.ts +21 -0
- package/dist/surface/context-query.js +113 -0
- package/dist/surface/context-query.js.map +1 -0
- package/dist/surface/evidence-backed-context-query.d.ts +62 -0
- package/dist/surface/evidence-backed-context-query.js +240 -0
- package/dist/surface/evidence-backed-context-query.js.map +1 -0
- package/dist/types/access-context.d.ts +25 -0
- package/dist/types/access-context.js +6 -0
- package/dist/types/access-context.js.map +1 -0
- package/dist/types/claim.d.ts +48 -0
- package/dist/types/claim.js +5 -0
- package/dist/types/claim.js.map +1 -0
- package/dist/types/consent.d.ts +41 -0
- package/dist/types/consent.js +3 -0
- package/dist/types/consent.js.map +1 -0
- package/dist/types/crypto-boundary.d.ts +12 -0
- package/dist/types/crypto-boundary.js +15 -0
- package/dist/types/crypto-boundary.js.map +1 -0
- package/dist/types/evidence.d.ts +31 -0
- package/dist/types/evidence.js +8 -0
- package/dist/types/evidence.js.map +1 -0
- package/dist/types/fact-store.d.ts +24 -0
- package/dist/types/fact-store.js +12 -0
- package/dist/types/fact-store.js.map +1 -0
- package/dist/types/ids.d.ts +36 -0
- package/dist/types/ids.js +11 -0
- package/dist/types/ids.js.map +1 -0
- package/dist/types/proposal.d.ts +38 -0
- package/dist/types/proposal.js +7 -0
- package/dist/types/proposal.js.map +1 -0
- package/dist/types/source.d.ts +33 -0
- package/dist/types/source.js +6 -0
- package/dist/types/source.js.map +1 -0
- package/dist/types/trust.d.ts +24 -0
- package/dist/types/trust.js +5 -0
- package/dist/types/trust.js.map +1 -0
- package/dist/utilities/deep-freeze.d.ts +1 -0
- package/dist/utilities/deep-freeze.js +17 -0
- package/dist/utilities/deep-freeze.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-grant-resolver.js","sourceRoot":"","sources":["../../src/auth/sqlite-grant-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
import type { TenantBoundary } from "./types.js";
|
|
3
|
+
export declare class SQLiteTenantBoundary implements TenantBoundary {
|
|
4
|
+
private readonly _stmt;
|
|
5
|
+
constructor(db: Database.Database);
|
|
6
|
+
assertOwnership(tenantId: string, personId: string): Promise<void>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// SQLite-backed TenantBoundary — Production-02d-b.
|
|
2
|
+
// Do NOT export from src/index.ts.
|
|
3
|
+
//
|
|
4
|
+
// AUTH_SQLITE_TENANT_BOUNDARY_BACKEND_001: implements TenantBoundary with a
|
|
5
|
+
// Database.Database-backed read path; behaviorally identical to InMemoryTenantBoundary.
|
|
6
|
+
// AUTH_SQLITE_TENANT_MEMBERSHIP_STATUS_CHECKED_001: assertOwnership checks
|
|
7
|
+
// status === "active" at read time; suspended rows are denied with the same
|
|
8
|
+
// code as missing rows (AUTH_TENANT_OWNERSHIP_DENIED_001) — no enumeration leak.
|
|
9
|
+
// AUTH_SQLITE_TENANT_MEMBERSHIP_SCHEMA_001: constructor throws this code when
|
|
10
|
+
// auth_tenant_memberships table is absent — signals missing runMigrations call,
|
|
11
|
+
// not a runtime auth denial.
|
|
12
|
+
//
|
|
13
|
+
// Storage-failure behavior: SQLite errors propagate as thrown — never converted
|
|
14
|
+
// to AUTH_TENANT_OWNERSHIP_DENIED_001 (a real storage failure is not a denial).
|
|
15
|
+
const SCHEMA_CODE = "AUTH_SQLITE_TENANT_MEMBERSHIP_SCHEMA_001";
|
|
16
|
+
const DENIED_CODE = "AUTH_TENANT_OWNERSHIP_DENIED_001";
|
|
17
|
+
export class SQLiteTenantBoundary {
|
|
18
|
+
_stmt;
|
|
19
|
+
constructor(db) {
|
|
20
|
+
// AUTH_SQLITE_TENANT_MEMBERSHIP_SCHEMA_001: fail if migration has not run
|
|
21
|
+
const tablePresent = db
|
|
22
|
+
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='auth_tenant_memberships'")
|
|
23
|
+
.get() !== undefined;
|
|
24
|
+
if (!tablePresent) {
|
|
25
|
+
throw Object.assign(new Error(`[${SCHEMA_CODE}] auth_tenant_memberships table absent — call runMigrations before constructing SQLiteTenantBoundary`), { code: SCHEMA_CODE });
|
|
26
|
+
}
|
|
27
|
+
this._stmt = db.prepare("SELECT status FROM auth_tenant_memberships WHERE tenant_id = ? AND person_id = ?");
|
|
28
|
+
}
|
|
29
|
+
async assertOwnership(tenantId, personId) {
|
|
30
|
+
// AUTH_SQLITE_TENANT_MEMBERSHIP_STATUS_CHECKED_001
|
|
31
|
+
// SQLite errors propagate — they are NOT caught here.
|
|
32
|
+
const row = this._stmt.get(tenantId, personId);
|
|
33
|
+
// AUTH_TENANT_SUBJECT_NOT_FOUND_SAFE_001:
|
|
34
|
+
// Missing and suspended use the same error code — no enumeration leak.
|
|
35
|
+
if (row === undefined || row.status !== "active") {
|
|
36
|
+
throw Object.assign(new Error(`[${DENIED_CODE}] subject is not an active member of the tenant`), { code: DENIED_CODE });
|
|
37
|
+
}
|
|
38
|
+
// Resolves void on success.
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=sqlite-tenant-boundary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-tenant-boundary.js","sourceRoot":"","sources":["../../src/auth/sqlite-tenant-boundary.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,mCAAmC;AACnC,EAAE;AACF,4EAA4E;AAC5E,0FAA0F;AAC1F,2EAA2E;AAC3E,8EAA8E;AAC9E,mFAAmF;AACnF,8EAA8E;AAC9E,kFAAkF;AAClF,+BAA+B;AAC/B,EAAE;AACF,gFAAgF;AAChF,kFAAkF;AAKlF,MAAM,WAAW,GAAG,0CAA0C,CAAC;AAC/D,MAAM,WAAW,GAAG,kCAAkC,CAAC;AAEvD,MAAM,OAAO,oBAAoB;IACd,KAAK,CAAqB;IAE3C,YAAY,EAAqB;QAC/B,0EAA0E;QAC1E,MAAM,YAAY,GACf,EAAE;aACA,OAAO,CACN,sFAAsF,CACvF;aACA,GAAG,EAAmC,KAAK,SAAS,CAAC;QAE1D,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,MAAM,CAAC,MAAM,CACjB,IAAI,KAAK,CACP,IAAI,WAAW,sGAAsG,CACtH,EACD,EAAE,IAAI,EAAE,WAAW,EAAE,CACtB,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,OAAO,CACrB,kFAAkF,CACnF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,QAAgB,EAAE,QAAgB;QACtD,mDAAmD;QACnD,sDAAsD;QACtD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAEhC,CAAC;QAEd,0CAA0C;QAC1C,uEAAuE;QACvE,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACjD,MAAM,MAAM,CAAC,MAAM,CACjB,IAAI,KAAK,CACP,IAAI,WAAW,iDAAiD,CACjE,EACD,EAAE,IAAI,EAAE,WAAW,EAAE,CACtB,CAAC;QACJ,CAAC;QACD,4BAA4B;IAC9B,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type JwtKeyStatus = "active" | "verifying-only" | "revoked";
|
|
2
|
+
export interface JwtKeyDescriptor {
|
|
3
|
+
readonly keyId: string;
|
|
4
|
+
readonly secret: Uint8Array;
|
|
5
|
+
readonly status: JwtKeyStatus;
|
|
6
|
+
readonly notBefore?: string;
|
|
7
|
+
readonly notAfter?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class StaticJwtKeyRing {
|
|
10
|
+
private readonly _keys;
|
|
11
|
+
constructor(keys: ReadonlyArray<JwtKeyDescriptor>);
|
|
12
|
+
resolveKey(keyId: string, nowMs: number): Buffer;
|
|
13
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// src/auth/static-jwt-key-ring.ts
|
|
2
|
+
// TEST/DEV only — NOT exported from src/index.ts.
|
|
3
|
+
// Constructor-injected, in-memory JWT key ring for HS256 secret management.
|
|
4
|
+
// Analogous to StaticKeyProvider (src/crypto/static-key.ts) but for JWT HMAC secrets.
|
|
5
|
+
// JWT secrets are raw Uint8Array — distinct from CryptoKey objects used in at-rest encryption.
|
|
6
|
+
//
|
|
7
|
+
// AUTH_JWT_SECRET_SOURCE_INJECTED_001 ✅ Production-04-a (architecture invariant)
|
|
8
|
+
// AUTH_JWT_KEY_RING_VALIDATED_001 ✅ Production-04-a (construction-time postcondition)
|
|
9
|
+
// AUTH_JWT_KEY_ID_DUPLICATE_001 ✅ Production-04-a
|
|
10
|
+
// AUTH_JWT_ROTATION_GRACE_BOUNDED_001 ✅ Production-04-a
|
|
11
|
+
// AUTH_JWT_KEY_REVOKED_DENIED_001 ✅ Production-04-a
|
|
12
|
+
// AUTH_JWT_KEY_EXPIRED_DENIED_001 ✅ Production-04-a
|
|
13
|
+
import { throwErr, MIN_SECRET_BYTES } from "./jwt-core.js";
|
|
14
|
+
// ─── StaticJwtKeyRing ─────────────────────────────────────────────────────────
|
|
15
|
+
export class StaticJwtKeyRing {
|
|
16
|
+
_keys;
|
|
17
|
+
constructor(keys) {
|
|
18
|
+
const map = new Map();
|
|
19
|
+
for (const desc of keys) {
|
|
20
|
+
// Empty / missing keyId
|
|
21
|
+
if (typeof desc.keyId !== "string" || desc.keyId.length === 0) {
|
|
22
|
+
throwErr("AUTH_CREDENTIAL_KEY_CONFIG_INVALID_001", "each key descriptor in the ring must have a non-empty keyId");
|
|
23
|
+
}
|
|
24
|
+
// Duplicate keyId (AUTH_JWT_KEY_ID_DUPLICATE_001)
|
|
25
|
+
if (map.has(desc.keyId)) {
|
|
26
|
+
throwErr("AUTH_JWT_KEY_ID_DUPLICATE_001", `duplicate keyId in ring: "${desc.keyId}"`);
|
|
27
|
+
}
|
|
28
|
+
// Secret length guard (reuses AUTH_CREDENTIAL_KEY_CONFIG_INVALID_001)
|
|
29
|
+
if (desc.secret == null || desc.secret.length < MIN_SECRET_BYTES) {
|
|
30
|
+
throwErr("AUTH_CREDENTIAL_KEY_CONFIG_INVALID_001", `key "${desc.keyId}" secret must be a Uint8Array of at least ${MIN_SECRET_BYTES} bytes`);
|
|
31
|
+
}
|
|
32
|
+
// Temporal string validation — parse at construction to fail fast
|
|
33
|
+
if (desc.notBefore !== undefined && isNaN(Date.parse(desc.notBefore))) {
|
|
34
|
+
throwErr("AUTH_CREDENTIAL_KEY_CONFIG_INVALID_001", `key "${desc.keyId}" notBefore is not a valid ISO-8601 instant`);
|
|
35
|
+
}
|
|
36
|
+
if (desc.notAfter !== undefined && isNaN(Date.parse(desc.notAfter))) {
|
|
37
|
+
throwErr("AUTH_CREDENTIAL_KEY_CONFIG_INVALID_001", `key "${desc.keyId}" notAfter is not a valid ISO-8601 instant`);
|
|
38
|
+
}
|
|
39
|
+
// verifying-only must have notAfter to bound the grace window
|
|
40
|
+
// (AUTH_JWT_ROTATION_GRACE_BOUNDED_001)
|
|
41
|
+
if (desc.status === "verifying-only" && desc.notAfter === undefined) {
|
|
42
|
+
throwErr("AUTH_JWT_ROTATION_GRACE_BOUNDED_001", `verifying-only key "${desc.keyId}" must have notAfter to bound the grace window`);
|
|
43
|
+
}
|
|
44
|
+
map.set(desc.keyId, desc);
|
|
45
|
+
}
|
|
46
|
+
// AUTH_JWT_KEY_RING_VALIDATED_001: ring is internally consistent past this point
|
|
47
|
+
this._keys = map;
|
|
48
|
+
}
|
|
49
|
+
// Resolve a key for verification at the given instant (nowMs = epoch milliseconds).
|
|
50
|
+
// Throws on unknown, revoked, not-yet-active, or grace-window-closed keys.
|
|
51
|
+
resolveKey(keyId, nowMs) {
|
|
52
|
+
const desc = this._keys.get(keyId);
|
|
53
|
+
if (desc === undefined) {
|
|
54
|
+
throwErr("AUTH_CREDENTIAL_KEY_ID_UNKNOWN_001", `key "${keyId}" not found in ring`);
|
|
55
|
+
}
|
|
56
|
+
// Revoked: fail closed unconditionally — ignores token exp
|
|
57
|
+
// (AUTH_JWT_KEY_REVOKED_DENIED_001)
|
|
58
|
+
if (desc.status === "revoked") {
|
|
59
|
+
throwErr("AUTH_JWT_KEY_REVOKED_DENIED_001", `key "${keyId}" has been revoked`);
|
|
60
|
+
}
|
|
61
|
+
// notBefore: key not yet active (use parsed instant, not string comparison)
|
|
62
|
+
// (AUTH_JWT_KEY_REVOKED_DENIED_001 — pre-active treated as revoked/unavailable)
|
|
63
|
+
if (desc.notBefore !== undefined && nowMs < Date.parse(desc.notBefore)) {
|
|
64
|
+
throwErr("AUTH_JWT_KEY_REVOKED_DENIED_001", `key "${keyId}" is not yet active (notBefore)`);
|
|
65
|
+
}
|
|
66
|
+
// notAfter: grace window closed (AUTH_JWT_KEY_EXPIRED_DENIED_001)
|
|
67
|
+
if (desc.notAfter !== undefined && nowMs >= Date.parse(desc.notAfter)) {
|
|
68
|
+
throwErr("AUTH_JWT_KEY_EXPIRED_DENIED_001", `key "${keyId}" grace window has closed (notAfter)`);
|
|
69
|
+
}
|
|
70
|
+
return Buffer.from(desc.secret);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=static-jwt-key-ring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-jwt-key-ring.js","sourceRoot":"","sources":["../../src/auth/static-jwt-key-ring.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { PersonId } from "../types/ids.js";
|
|
2
|
+
import type { ErasureStatus } from "../erasure/tombstone.js";
|
|
3
|
+
import type { QueryContractsInput, ContextQueryResult } from "../surface/evidence-backed-context-query.js";
|
|
4
|
+
import type { LifeApi } from "../sdk/life-api.js";
|
|
5
|
+
import type { MintedContext } from "./types.js";
|
|
6
|
+
export declare class SubjectScopedLifeApi {
|
|
7
|
+
private readonly _api;
|
|
8
|
+
private readonly _minted;
|
|
9
|
+
constructor(_api: LifeApi, _minted: MintedContext);
|
|
10
|
+
requestErasure(subject: PersonId): Promise<void>;
|
|
11
|
+
getErasureStatus(subject: PersonId): Promise<ErasureStatus | undefined>;
|
|
12
|
+
queryContracts(input: QueryContractsInput): Promise<ContextQueryResult>;
|
|
13
|
+
}
|
|
14
|
+
export declare function createSubjectScopedLifeApi(api: LifeApi, minted: MintedContext): SubjectScopedLifeApi;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// AUTH_CONTEXT_SUBJECT_SCOPE_ENFORCED_001 — Production-01c
|
|
2
|
+
//
|
|
3
|
+
// Facade: binds a LifeApi instance + a MintedContext. No ctx parameter on any facade method —
|
|
4
|
+
// context is bound at construction time. assertAuthorizedForSubject() fires BEFORE any
|
|
5
|
+
// subject-bearing LifeApi call. Excluded methods are intentionally absent.
|
|
6
|
+
//
|
|
7
|
+
// SubjectScopedLifeApi does NOT implement LifeApi.
|
|
8
|
+
// Callers that need non-facade methods must call LifeApi directly with minted.context.
|
|
9
|
+
//
|
|
10
|
+
// PROPOSAL METHODS ARE EXCLUDED (Production-01c hardening):
|
|
11
|
+
// ProposalId-only is not subject-free proof — a Proposal's candidateClaims may contain
|
|
12
|
+
// subject-scoped data. getProposal/listProposals/acceptProposal/rejectProposal are deferred
|
|
13
|
+
// to Production-01d where explicit Proposal-scope enforcement will be implemented.
|
|
14
|
+
import { assertAuthorizedForSubject } from "./assert-authorized-for-subject.js";
|
|
15
|
+
export class SubjectScopedLifeApi {
|
|
16
|
+
_api;
|
|
17
|
+
_minted;
|
|
18
|
+
constructor(_api, _minted) {
|
|
19
|
+
this._api = _api;
|
|
20
|
+
this._minted = _minted;
|
|
21
|
+
}
|
|
22
|
+
// ── Subject-enforced ──────────────────────────────────────────────────────────
|
|
23
|
+
// assertAuthorizedForSubject() fires BEFORE any LifeApi call.
|
|
24
|
+
async requestErasure(subject) {
|
|
25
|
+
assertAuthorizedForSubject(this._minted, subject);
|
|
26
|
+
return this._api.requestErasure(this._minted.context, subject);
|
|
27
|
+
}
|
|
28
|
+
async getErasureStatus(subject) {
|
|
29
|
+
assertAuthorizedForSubject(this._minted, subject);
|
|
30
|
+
return this._api.getErasureStatus(this._minted.context, subject);
|
|
31
|
+
}
|
|
32
|
+
async queryContracts(input) {
|
|
33
|
+
if (input.selector.subject !== undefined) {
|
|
34
|
+
// Case A: subject present — enforce exact match against authorizedPersonId
|
|
35
|
+
assertAuthorizedForSubject(this._minted, input.selector.subject);
|
|
36
|
+
}
|
|
37
|
+
else if (this._minted.authorizedPersonId !== undefined) {
|
|
38
|
+
// Case B: person-scoped credential cannot execute cross-subject queries.
|
|
39
|
+
// A missing subject selector would return data across all subjects in the tenant.
|
|
40
|
+
throw Object.assign(new Error("AUTH_SUBJECT_SCOPE_VIOLATION_001: person-scoped credential may not execute " +
|
|
41
|
+
"a cross-subject query (input.selector.subject is absent but " +
|
|
42
|
+
"MintedContext.authorizedPersonId is set)"), { code: "AUTH_SUBJECT_SCOPE_VIOLATION_001" });
|
|
43
|
+
}
|
|
44
|
+
// Case C: subject absent + authorizedPersonId absent → tenant/system scope, no restriction
|
|
45
|
+
return this._api.queryContracts(this._minted.context, input);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function createSubjectScopedLifeApi(api, minted) {
|
|
49
|
+
return new SubjectScopedLifeApi(api, minted);
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=subject-scoped-life-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subject-scoped-life-api.js","sourceRoot":"","sources":["../../src/auth/subject-scoped-life-api.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,EAAE;AACF,8FAA8F;AAC9F,uFAAuF;AACvF,2EAA2E;AAC3E,EAAE;AACF,mDAAmD;AACnD,uFAAuF;AACvF,EAAE;AACF,4DAA4D;AAC5D,uFAAuF;AACvF,4FAA4F;AAC5F,mFAAmF;AAQnF,OAAO,EAAE,0BAA0B,EAAE,MAAc,oCAAoC,CAAC;AAExF,MAAM,OAAO,oBAAoB;IAEZ;IACA;IAFnB,YACmB,IAAgB,EAChB,OAAsB;QADtB,SAAI,GAAJ,IAAI,CAAY;QAChB,YAAO,GAAP,OAAO,CAAe;IACtC,CAAC;IAEJ,iFAAiF;IACjF,8DAA8D;IAE9D,KAAK,CAAC,cAAc,CAAC,OAAiB;QACpC,0BAA0B,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,OAAkC,EAAE,OAAO,CAAC,CAAC;IAC5F,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,OAAiB;QACtC,0BAA0B,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,OAAkC,EAAE,OAAO,CAAC,CAAC;IAC9F,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,KAA0B;QAC7C,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACzC,2EAA2E;YAC3E,0BAA0B,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACnE,CAAC;aAAM,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,KAAK,SAAS,EAAE,CAAC;YACzD,yEAAyE;YACzE,kFAAkF;YAClF,MAAM,MAAM,CAAC,MAAM,CACjB,IAAI,KAAK,CACP,6EAA6E;gBAC7E,8DAA8D;gBAC9D,0CAA0C,CAC3C,EACD,EAAE,IAAI,EAAE,kCAAkC,EAAE,CAC7C,CAAC;QACJ,CAAC;QACD,2FAA2F;QAC3F,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC/D,CAAC;CAUF;AAED,MAAM,UAAU,0BAA0B,CACxC,GAAe,EACf,MAAqB;IAErB,OAAO,IAAI,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AuthAdapter, AuthorizationPolicy, Clock, ContextMintingBoundary, MintedContext } from "./types.js";
|
|
2
|
+
import type { AccessContextIssuer } from "./access-context-issuer.js";
|
|
3
|
+
/** @remarks TEST/DEV ONLY — not for production use. */
|
|
4
|
+
export declare class TestContextMintingBoundary implements ContextMintingBoundary {
|
|
5
|
+
private readonly _opts;
|
|
6
|
+
constructor(_opts: {
|
|
7
|
+
readonly adapter: AuthAdapter;
|
|
8
|
+
readonly policy: AuthorizationPolicy;
|
|
9
|
+
readonly issuer: AccessContextIssuer;
|
|
10
|
+
readonly clock: Clock;
|
|
11
|
+
});
|
|
12
|
+
mint(credential: string, targetPersonId: string, requestedKind: "owner" | "agent" | "system" | "audit"): Promise<MintedContext>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// TEST/DEV ONLY — AUTH_CONTEXT_MINTING_BOUNDARY_001 (first concrete implementation).
|
|
2
|
+
// Do NOT export from src/index.ts. Do NOT use in production.
|
|
3
|
+
// AUTH_TOKEN_SECRETS_NOT_AUDITED_001: raw credential never enters MintedContext or errors.
|
|
4
|
+
import { asPersonId, asGrantId, asISOTime } from "../types/ids.js";
|
|
5
|
+
/** @remarks TEST/DEV ONLY — not for production use. */
|
|
6
|
+
export class TestContextMintingBoundary {
|
|
7
|
+
_opts;
|
|
8
|
+
constructor(_opts) {
|
|
9
|
+
this._opts = _opts;
|
|
10
|
+
}
|
|
11
|
+
async mint(credential, targetPersonId, requestedKind) {
|
|
12
|
+
const { adapter, policy, issuer, clock } = this._opts;
|
|
13
|
+
// 1. Verify credential → VerifiedPrincipal (no raw credential stored beyond this call)
|
|
14
|
+
const principal = await adapter.verify(credential);
|
|
15
|
+
// 2. Expiry check before policy — AUTH_TOKEN_EXPIRY_CHECKED_001
|
|
16
|
+
if (principal.expiresAt <= clock.now()) {
|
|
17
|
+
throw Object.assign(new Error("AUTH_CREDENTIAL_EXPIRED_001: credential has expired"), { code: "AUTH_CREDENTIAL_EXPIRED_001" });
|
|
18
|
+
}
|
|
19
|
+
// 3. Resolve authorization decision
|
|
20
|
+
const decision = await policy.resolve(principal, targetPersonId);
|
|
21
|
+
// 4. Kind check — AUTH_DECISION_KIND_MISMATCH_001 (with specific sub-codes)
|
|
22
|
+
if (decision.kind !== requestedKind) {
|
|
23
|
+
// AUTH_AGENT_CANNOT_MINT_OWNER_001: specific invariant for this well-known violation
|
|
24
|
+
if (requestedKind === "owner" && principal.principalType === "agent") {
|
|
25
|
+
throw Object.assign(new Error("AUTH_AGENT_CANNOT_MINT_OWNER_001: an agent principal may not receive an OwnerContext"), { code: "AUTH_AGENT_CANNOT_MINT_OWNER_001" });
|
|
26
|
+
}
|
|
27
|
+
// AUTH_SERVICE_PRINCIPAL_REQUIRED_FOR_SYSTEM_CONTEXT_001
|
|
28
|
+
if (requestedKind === "system" && principal.principalType !== "service") {
|
|
29
|
+
throw Object.assign(new Error("AUTH_SERVICE_PRINCIPAL_REQUIRED_FOR_SYSTEM_CONTEXT_001: " +
|
|
30
|
+
"only service principals may mint a SystemProjectionContext"), { code: "AUTH_SERVICE_PRINCIPAL_REQUIRED_FOR_SYSTEM_CONTEXT_001" });
|
|
31
|
+
}
|
|
32
|
+
throw Object.assign(new Error(`AUTH_DECISION_KIND_MISMATCH_001: policy resolved "${decision.kind}" ` +
|
|
33
|
+
`but "${requestedKind}" was requested`), { code: "AUTH_DECISION_KIND_MISMATCH_001" });
|
|
34
|
+
}
|
|
35
|
+
// 5. Mint context and build MintedContext — credential is NOT carried forward
|
|
36
|
+
const base = {
|
|
37
|
+
principalId: principal.principalId,
|
|
38
|
+
principalType: principal.principalType,
|
|
39
|
+
tenantId: principal.tenantId,
|
|
40
|
+
};
|
|
41
|
+
switch (decision.kind) {
|
|
42
|
+
case "owner": {
|
|
43
|
+
const ctx = issuer.mintOwner(asPersonId(decision.personId));
|
|
44
|
+
return {
|
|
45
|
+
...base,
|
|
46
|
+
context: ctx,
|
|
47
|
+
authorizedPersonId: principal.authorizedPersonId ?? decision.personId,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
case "agent": {
|
|
51
|
+
const ctx = issuer.mintAgent({
|
|
52
|
+
agentId: decision.agentId,
|
|
53
|
+
grantId: asGrantId(decision.grantId),
|
|
54
|
+
purpose: decision.purpose,
|
|
55
|
+
notAfter: asISOTime(decision.notAfter),
|
|
56
|
+
});
|
|
57
|
+
return {
|
|
58
|
+
...base,
|
|
59
|
+
context: ctx,
|
|
60
|
+
authorizedGrantId: decision.grantId,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
case "system": {
|
|
64
|
+
const ctx = issuer.mintSystemProjection();
|
|
65
|
+
return { ...base, context: ctx };
|
|
66
|
+
}
|
|
67
|
+
case "audit": {
|
|
68
|
+
const ctx = issuer.mintAudit(asPersonId(targetPersonId));
|
|
69
|
+
return { ...base, context: ctx };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=test-context-minting-boundary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-context-minting-boundary.js","sourceRoot":"","sources":["../../src/auth/test-context-minting-boundary.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { AccessContext, PurposeTag } from "../types/access-context.js";
|
|
2
|
+
import type { PersonId } from "../types/ids.js";
|
|
3
|
+
export type PrincipalType = "user" | "agent" | "service" | "audit";
|
|
4
|
+
export interface VerifiedPrincipal {
|
|
5
|
+
readonly principalId: string;
|
|
6
|
+
readonly principalType: PrincipalType;
|
|
7
|
+
readonly tenantId: string;
|
|
8
|
+
readonly roles: ReadonlyArray<"owner" | "agent" | "system" | "audit">;
|
|
9
|
+
readonly grantIds: ReadonlyArray<string>;
|
|
10
|
+
readonly authorizedPersonId?: string;
|
|
11
|
+
readonly expiresAt: string;
|
|
12
|
+
readonly issuedAt: string;
|
|
13
|
+
}
|
|
14
|
+
export interface AuthAdapter {
|
|
15
|
+
verify(credential: string): Promise<VerifiedPrincipal>;
|
|
16
|
+
}
|
|
17
|
+
export type AuthorizationDecision = {
|
|
18
|
+
readonly kind: "owner";
|
|
19
|
+
readonly personId: string;
|
|
20
|
+
} | {
|
|
21
|
+
readonly kind: "agent";
|
|
22
|
+
readonly agentId: string;
|
|
23
|
+
readonly grantId: string;
|
|
24
|
+
readonly purpose: PurposeTag;
|
|
25
|
+
readonly notAfter: string;
|
|
26
|
+
} | {
|
|
27
|
+
readonly kind: "system";
|
|
28
|
+
readonly projection: string;
|
|
29
|
+
} | {
|
|
30
|
+
readonly kind: "audit";
|
|
31
|
+
};
|
|
32
|
+
export interface AuthorizationPolicy {
|
|
33
|
+
resolve(principal: VerifiedPrincipal, targetPersonId: string): Promise<AuthorizationDecision>;
|
|
34
|
+
}
|
|
35
|
+
export interface TenantBoundary {
|
|
36
|
+
assertOwnership(tenantId: string, personId: string): Promise<void>;
|
|
37
|
+
}
|
|
38
|
+
export interface GrantDescriptor {
|
|
39
|
+
readonly grantId: string;
|
|
40
|
+
readonly agentId: string;
|
|
41
|
+
readonly tenantId: string;
|
|
42
|
+
readonly notAfter: string;
|
|
43
|
+
readonly personId?: PersonId;
|
|
44
|
+
readonly purpose?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface GrantResolver {
|
|
47
|
+
resolveActiveGrant(agentId: string, grantId: string, tenantId: string): Promise<GrantDescriptor | undefined>;
|
|
48
|
+
}
|
|
49
|
+
export interface Clock {
|
|
50
|
+
now(): string;
|
|
51
|
+
}
|
|
52
|
+
export interface MintedContext {
|
|
53
|
+
readonly context: AccessContext;
|
|
54
|
+
readonly principalId: string;
|
|
55
|
+
readonly principalType: PrincipalType;
|
|
56
|
+
readonly tenantId: string;
|
|
57
|
+
readonly authorizedPersonId?: string;
|
|
58
|
+
readonly authorizedGrantId?: string;
|
|
59
|
+
readonly guardianOf?: PersonId;
|
|
60
|
+
readonly guardianScopes?: ReadonlyArray<string>;
|
|
61
|
+
readonly declaredPurpose?: PurposeTag;
|
|
62
|
+
}
|
|
63
|
+
export interface MintOptions {
|
|
64
|
+
readonly declaredPurpose?: PurposeTag;
|
|
65
|
+
}
|
|
66
|
+
export interface ContextMintingBoundary {
|
|
67
|
+
mint(credential: string, targetPersonId: string, requestedKind: "owner" | "agent" | "system" | "audit", options?: MintOptions): Promise<MintedContext>;
|
|
68
|
+
}
|
|
69
|
+
export interface GuardianContextMintingBoundary extends ContextMintingBoundary {
|
|
70
|
+
/**
|
|
71
|
+
* Mint a guardian context on behalf of wardId.
|
|
72
|
+
* The returned context is an OwnerContext for wardId, marked with guardianOf = wardId.
|
|
73
|
+
* Denials throw AUTH_GUARDIAN_CONTEXT_MINT_DENIED_001 (opaque — internal reason not propagated).
|
|
74
|
+
* GUARDIAN_REGISTRY_NOT_CONFIGURED_001: no registry → throws that specific code.
|
|
75
|
+
*/
|
|
76
|
+
mintGuardianContext(credential: string, wardId: string): Promise<MintedContext>;
|
|
77
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Auth boundary types — Production-01a.
|
|
2
|
+
//
|
|
3
|
+
// AUTH_CONTEXT_MINTING_BOUNDARY_001: ContextMintingBoundary is the only production
|
|
4
|
+
// path to a trusted AccessContext; raw AccessContextIssuer.mint*() must not be
|
|
5
|
+
// called outside this boundary in production deployments.
|
|
6
|
+
// AUTH_NO_PUBLIC_ISSUER_EXPORT_001: these interfaces are exported; the
|
|
7
|
+
// AccessContextIssuer class and FakeAuthAdapter are NOT.
|
|
8
|
+
// AUTH_HOST_ADAPTER_REQUIRED_001: production factory requires an AuthAdapter.
|
|
9
|
+
// AUTH_CONTEXT_SUBJECT_SCOPE_ENFORCED_001: MintedContext carries authorizedPersonId /
|
|
10
|
+
// authorizedGrantId so call sites can enforce subject scope beyond WeakSet trust.
|
|
11
|
+
// AUTH_CONTEXT_INSTANCE_BOUND_001 (WeakSet) prevents cross-instance replay only —
|
|
12
|
+
// cross-subject misuse within the same instance requires authorizedPersonId enforcement.
|
|
13
|
+
// AUTH_SERVICE_PRINCIPAL_REQUIRED_FOR_SYSTEM_CONTEXT_001: principalType "service"
|
|
14
|
+
// is the only allowed source for SystemProjectionContext minting.
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,EAAE;AACF,mFAAmF;AACnF,iFAAiF;AACjF,4DAA4D;AAC5D,uEAAuE;AACvE,2DAA2D;AAC3D,8EAA8E;AAC9E,sFAAsF;AACtF,oFAAoF;AACpF,oFAAoF;AACpF,2FAA2F;AAC3F,kFAAkF;AAClF,oEAAoE"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Database } from "better-sqlite3";
|
|
2
|
+
export interface GrantSummary {
|
|
3
|
+
readonly grantId: string;
|
|
4
|
+
readonly agentId: string;
|
|
5
|
+
readonly status: string;
|
|
6
|
+
readonly purpose?: string;
|
|
7
|
+
readonly notBefore?: string;
|
|
8
|
+
readonly notAfter: string;
|
|
9
|
+
readonly createdAt: string;
|
|
10
|
+
readonly updatedAt: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ProposalSummary {
|
|
13
|
+
readonly proposalId: string;
|
|
14
|
+
readonly status: string;
|
|
15
|
+
readonly proposedByAgent: string;
|
|
16
|
+
readonly underGrant: string;
|
|
17
|
+
readonly createdAt: string;
|
|
18
|
+
readonly updatedAt: string;
|
|
19
|
+
readonly decidedAt?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface AuditEventSummary {
|
|
22
|
+
readonly eventId: string;
|
|
23
|
+
readonly recordedAt: string;
|
|
24
|
+
readonly actor: string;
|
|
25
|
+
readonly decision: string;
|
|
26
|
+
readonly reasonCode: string;
|
|
27
|
+
readonly grantId?: string;
|
|
28
|
+
readonly actingAsGuardian?: boolean;
|
|
29
|
+
readonly wardId?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface SubjectDataReport {
|
|
32
|
+
readonly generatedAt: string;
|
|
33
|
+
readonly subjectId: string;
|
|
34
|
+
readonly schemaVersion: number;
|
|
35
|
+
readonly grants: GrantSummary[];
|
|
36
|
+
readonly proposals: ProposalSummary[];
|
|
37
|
+
readonly auditEvents: AuditEventSummary[];
|
|
38
|
+
readonly dataIntegrityHash: string;
|
|
39
|
+
}
|
|
40
|
+
export interface SubjectDataReportOptions {
|
|
41
|
+
readonly now: string;
|
|
42
|
+
}
|
|
43
|
+
export declare function generateSubjectDataReport(db: Database, personId: string, opts: SubjectDataReportOptions): SubjectDataReport;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// DSGVO Art. 15 (Auskunftsrecht) + Art. 20 (Datenportabilität) — Subject Data Report.
|
|
2
|
+
//
|
|
3
|
+
// SUBJECT_DATA_REPORT_GDPR_ART15_001: generateSubjectDataReport() produces a complete,
|
|
4
|
+
// structured account of all data held about a personId: active + expired grants,
|
|
5
|
+
// proposals linked to those grants, and audit events linked to those grants.
|
|
6
|
+
// SUBJECT_DATA_REPORT_INTEGRITY_HASH_001: dataIntegrityHash = SHA-256 over the canonical
|
|
7
|
+
// JSON of the report (fields sorted, hash field excluded) — makes the report tamper-evident
|
|
8
|
+
// and admissible as evidence. Hosts wishing formal notarisation must additionally timestamp
|
|
9
|
+
// the hash with a qualified TSA.
|
|
10
|
+
// SUBJECT_DATA_REPORT_INCLUDES_EXPIRED_GRANTS_001: all grants (status "active" + "revoked" +
|
|
11
|
+
// "expired") are included — GDPR right of access covers historical data.
|
|
12
|
+
// SUBJECT_DATA_REPORT_NO_PLAINTEXT_PAYLOAD_001: proposal encrypted payloads are NOT included.
|
|
13
|
+
// The report records proposal metadata (id, status, agent, grant, timestamps) only —
|
|
14
|
+
// PROPOSAL_QUEUE_SCHEMA_ENCRYPTED_PAYLOAD_001 is respected; the key material required for
|
|
15
|
+
// decryption is not available to this layer.
|
|
16
|
+
// SUBJECT_DATA_REPORT_AUDIT_VIA_GRANT_JOIN_001: audit events are linked to the subject via
|
|
17
|
+
// their grant_id → auth_grants.grant_id → auth_grants.person_id join. Events without a
|
|
18
|
+
// grant_id are per-subject owner actions (actor matches "user:<principalId>") included via
|
|
19
|
+
// the owner-event path. Events with an unknown/cross-subject grant_id are excluded.
|
|
20
|
+
// SUBJECT_DATA_REPORT_GUARDIAN_EVENTS_INCLUDED_001: audit events with acting_as_guardian=1
|
|
21
|
+
// AND ward_id = personId are included — they represent actions taken on behalf of this person.
|
|
22
|
+
// SUBJECT_DATA_REPORT_OWNER_ONLY_001: callers must enforce that only the subject (owner
|
|
23
|
+
// context or authorised guardian) may call this function. The function itself does NOT
|
|
24
|
+
// enforce caller identity — enforcement is the host's responsibility.
|
|
25
|
+
import { sha256hexSync } from "../crypto/sha256.js";
|
|
26
|
+
// ─── Canonical JSON (for integrity hash) ─────────────────────────────────────
|
|
27
|
+
// SUBJECT_DATA_REPORT_INTEGRITY_HASH_001: sorted keys, no undefined/null values,
|
|
28
|
+
// dataIntegrityHash field excluded. The sort is deterministic across V8 versions
|
|
29
|
+
// because we sort recursively using Array.from(Object.keys()).sort().
|
|
30
|
+
function canonicalJson(value) {
|
|
31
|
+
if (value === null || value === undefined)
|
|
32
|
+
return "null";
|
|
33
|
+
if (typeof value !== "object" && !Array.isArray(value))
|
|
34
|
+
return JSON.stringify(value);
|
|
35
|
+
if (Array.isArray(value)) {
|
|
36
|
+
return "[" + value.map(canonicalJson).join(",") + "]";
|
|
37
|
+
}
|
|
38
|
+
const obj = value;
|
|
39
|
+
const keys = Object.keys(obj).sort();
|
|
40
|
+
const pairs = keys
|
|
41
|
+
.filter(k => obj[k] !== undefined)
|
|
42
|
+
.map(k => JSON.stringify(k) + ":" + canonicalJson(obj[k]));
|
|
43
|
+
return "{" + pairs.join(",") + "}";
|
|
44
|
+
}
|
|
45
|
+
// ─── generateSubjectDataReport ────────────────────────────────────────────────
|
|
46
|
+
export function generateSubjectDataReport(db, personId, opts) {
|
|
47
|
+
// 1. Grants — all statuses (SUBJECT_DATA_REPORT_INCLUDES_EXPIRED_GRANTS_001)
|
|
48
|
+
const grantRows = db.prepare(`SELECT grant_id, agent_id, status, not_before, not_after, created_at, updated_at
|
|
49
|
+
FROM auth_grants
|
|
50
|
+
WHERE person_id = ?
|
|
51
|
+
ORDER BY created_at ASC`).all(personId);
|
|
52
|
+
const grants = grantRows.map(r => {
|
|
53
|
+
const g = {
|
|
54
|
+
grantId: r.grant_id,
|
|
55
|
+
agentId: r.agent_id,
|
|
56
|
+
status: r.status,
|
|
57
|
+
notAfter: r.not_after,
|
|
58
|
+
createdAt: r.created_at,
|
|
59
|
+
updatedAt: r.updated_at,
|
|
60
|
+
};
|
|
61
|
+
const withOptionals = { ...g };
|
|
62
|
+
if (r.not_before !== null && r.not_before !== undefined) {
|
|
63
|
+
withOptionals["notBefore"] = r.not_before;
|
|
64
|
+
}
|
|
65
|
+
return withOptionals;
|
|
66
|
+
});
|
|
67
|
+
const grantIds = grantRows.map(r => r.grant_id);
|
|
68
|
+
// 2. Proposals — linked via grants (SUBJECT_DATA_REPORT_NO_PLAINTEXT_PAYLOAD_001)
|
|
69
|
+
let proposals = [];
|
|
70
|
+
if (grantIds.length > 0) {
|
|
71
|
+
const placeholders = grantIds.map(() => "?").join(",");
|
|
72
|
+
const proposalRows = db.prepare(`SELECT proposal_id, status, proposed_by_agent, under_grant,
|
|
73
|
+
created_at, updated_at, decided_at
|
|
74
|
+
FROM proposals
|
|
75
|
+
WHERE under_grant IN (${placeholders})
|
|
76
|
+
ORDER BY created_at ASC`).all(...grantIds);
|
|
77
|
+
proposals = proposalRows.map(r => {
|
|
78
|
+
const p = {
|
|
79
|
+
proposalId: r.proposal_id,
|
|
80
|
+
status: r.status,
|
|
81
|
+
proposedByAgent: r.proposed_by_agent,
|
|
82
|
+
underGrant: r.under_grant,
|
|
83
|
+
createdAt: r.created_at,
|
|
84
|
+
updatedAt: r.updated_at,
|
|
85
|
+
};
|
|
86
|
+
if (r.decided_at !== null && r.decided_at !== undefined) {
|
|
87
|
+
p["decidedAt"] = r.decided_at;
|
|
88
|
+
}
|
|
89
|
+
return p;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
// 3. Audit events — via grant join + guardian ward events
|
|
93
|
+
// (SUBJECT_DATA_REPORT_AUDIT_VIA_GRANT_JOIN_001 + SUBJECT_DATA_REPORT_GUARDIAN_EVENTS_INCLUDED_001)
|
|
94
|
+
let auditEvents = [];
|
|
95
|
+
{
|
|
96
|
+
const parts = [];
|
|
97
|
+
const params = [];
|
|
98
|
+
if (grantIds.length > 0) {
|
|
99
|
+
const placeholders = grantIds.map(() => "?").join(",");
|
|
100
|
+
parts.push(`SELECT id, recorded_at, actor, decision, reason_code, grant_id,
|
|
101
|
+
acting_as_guardian, ward_id
|
|
102
|
+
FROM audit_events
|
|
103
|
+
WHERE grant_id IN (${placeholders})`);
|
|
104
|
+
params.push(...grantIds);
|
|
105
|
+
}
|
|
106
|
+
// Guardian events: acting on behalf of this person as ward
|
|
107
|
+
parts.push(`SELECT id, recorded_at, actor, decision, reason_code, grant_id,
|
|
108
|
+
acting_as_guardian, ward_id
|
|
109
|
+
FROM audit_events
|
|
110
|
+
WHERE acting_as_guardian = 1 AND ward_id = ?`);
|
|
111
|
+
params.push(personId);
|
|
112
|
+
if (parts.length > 0) {
|
|
113
|
+
const sql = parts.join(" UNION ") + " ORDER BY recorded_at ASC";
|
|
114
|
+
const rows = db.prepare(sql).all(...params);
|
|
115
|
+
// Deduplicate by id (a row may appear in both queries)
|
|
116
|
+
const seen = new Set();
|
|
117
|
+
auditEvents = rows
|
|
118
|
+
.filter(r => {
|
|
119
|
+
if (seen.has(r.id))
|
|
120
|
+
return false;
|
|
121
|
+
seen.add(r.id);
|
|
122
|
+
return true;
|
|
123
|
+
})
|
|
124
|
+
.map(r => {
|
|
125
|
+
const ev = {
|
|
126
|
+
eventId: r.id,
|
|
127
|
+
recordedAt: r.recorded_at,
|
|
128
|
+
actor: r.actor,
|
|
129
|
+
decision: r.decision,
|
|
130
|
+
reasonCode: r.reason_code,
|
|
131
|
+
};
|
|
132
|
+
if (r.grant_id !== null && r.grant_id !== undefined)
|
|
133
|
+
ev["grantId"] = r.grant_id;
|
|
134
|
+
if (r.acting_as_guardian === 1)
|
|
135
|
+
ev["actingAsGuardian"] = true;
|
|
136
|
+
if (r.ward_id !== null && r.ward_id !== undefined)
|
|
137
|
+
ev["wardId"] = r.ward_id;
|
|
138
|
+
return ev;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// 4. Assemble report without hash
|
|
143
|
+
const reportWithoutHash = {
|
|
144
|
+
generatedAt: opts.now,
|
|
145
|
+
subjectId: personId,
|
|
146
|
+
schemaVersion: 10,
|
|
147
|
+
grants,
|
|
148
|
+
proposals,
|
|
149
|
+
auditEvents,
|
|
150
|
+
};
|
|
151
|
+
// SUBJECT_DATA_REPORT_INTEGRITY_HASH_001: SHA-256 over canonical JSON
|
|
152
|
+
const dataIntegrityHash = sha256hexSync(Buffer.from(canonicalJson(reportWithoutHash), "utf8"));
|
|
153
|
+
return { ...reportWithoutHash, dataIntegrityHash };
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=subject-data-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subject-data-report.js","sourceRoot":"","sources":["../../src/compliance/subject-data-report.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,EAAE;AACF,uFAAuF;AACvF,mFAAmF;AACnF,+EAA+E;AAC/E,yFAAyF;AACzF,8FAA8F;AAC9F,8FAA8F;AAC9F,mCAAmC;AACnC,6FAA6F;AAC7F,2EAA2E;AAC3E,8FAA8F;AAC9F,uFAAuF;AACvF,4FAA4F;AAC5F,+CAA+C;AAC/C,2FAA2F;AAC3F,yFAAyF;AACzF,6FAA6F;AAC7F,sFAAsF;AACtF,2FAA2F;AAC3F,iGAAiG;AACjG,wFAAwF;AACxF,yFAAyF;AACzF,wEAAwE;AAGxE,OAAO,EAAE,aAAa,EAAE,MAAO,qBAAqB,CAAC;AAsFrD,gFAAgF;AAChF,iFAAiF;AACjF,iFAAiF;AACjF,sEAAsE;AAEtE,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACzD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACrF,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,GAAG,GAAI,KAAmB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACvE,CAAC;IACD,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI;SACf,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;SACjC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7D,OAAO,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AACrC,CAAC;AAED,iFAAiF;AAEjF,MAAM,UAAU,yBAAyB,CACvC,EAAkB,EAClB,QAAgB,EAChB,IAAkC;IAElC,6EAA6E;IAC7E,MAAM,SAAS,GAAG,EAAE,CAAC,OAAO,CAC1B;;;6BAGyB,CAC1B,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAEhB,MAAM,MAAM,GAAmB,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;QAC/C,MAAM,CAAC,GAAiB;YACtB,OAAO,EAAI,CAAC,CAAC,QAAQ;YACrB,OAAO,EAAI,CAAC,CAAC,QAAQ;YACrB,MAAM,EAAK,CAAC,CAAC,MAAM;YACnB,QAAQ,EAAG,CAAC,CAAC,SAAS;YACtB,SAAS,EAAE,CAAC,CAAC,UAAU;YACvB,SAAS,EAAE,CAAC,CAAC,UAAU;SACxB,CAAC;QACF,MAAM,aAAa,GAA4B,EAAE,GAAG,CAAC,EAAE,CAAC;QACxD,IAAI,CAAC,CAAC,UAAU,KAAK,IAAI,IAAI,CAAC,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACxD,aAAa,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC;QAC5C,CAAC;QACD,OAAO,aAAwC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAEhD,kFAAkF;IAClF,IAAI,SAAS,GAAsB,EAAE,CAAC;IACtC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvD,MAAM,YAAY,GAAG,EAAE,CAAC,OAAO,CAC7B;;;+BAGyB,YAAY;+BACZ,CAC1B,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;QAEnB,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YAC/B,MAAM,CAAC,GAA4B;gBACjC,UAAU,EAAO,CAAC,CAAC,WAAW;gBAC9B,MAAM,EAAW,CAAC,CAAC,MAAM;gBACzB,eAAe,EAAE,CAAC,CAAC,iBAAiB;gBACpC,UAAU,EAAO,CAAC,CAAC,WAAW;gBAC9B,SAAS,EAAQ,CAAC,CAAC,UAAU;gBAC7B,SAAS,EAAQ,CAAC,CAAC,UAAU;aAC9B,CAAC;YACF,IAAI,CAAC,CAAC,UAAU,KAAK,IAAI,IAAI,CAAC,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;gBACxD,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC;YAChC,CAAC;YACD,OAAO,CAA+B,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,0DAA0D;IAC1D,oGAAoG;IACpG,IAAI,WAAW,GAAwB,EAAE,CAAC;IAC1C,CAAC;QACC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAc,EAAE,CAAC;QAE7B,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACvD,KAAK,CAAC,IAAI,CACR;;;8BAGsB,YAAY,GAAG,CACtC,CAAC;YACF,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;QAC3B,CAAC;QAED,2DAA2D;QAC3D,KAAK,CAAC,IAAI,CACR;;;oDAG8C,CAC/C,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEtB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,2BAA2B,CAAC;YAChE,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAsB,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;YAEjE,uDAAuD;YACvD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;YAC/B,WAAW,GAAG,IAAI;iBACf,MAAM,CAAC,CAAC,CAAC,EAAE;gBACV,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;oBAAE,OAAO,KAAK,CAAC;gBACjC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACf,OAAO,IAAI,CAAC;YACd,CAAC,CAAC;iBACD,GAAG,CAAC,CAAC,CAAC,EAAE;gBACP,MAAM,EAAE,GAA4B;oBAClC,OAAO,EAAK,CAAC,CAAC,EAAE;oBAChB,UAAU,EAAE,CAAC,CAAC,WAAW;oBACzB,KAAK,EAAO,CAAC,CAAC,KAAK;oBACnB,QAAQ,EAAI,CAAC,CAAC,QAAQ;oBACtB,UAAU,EAAE,CAAC,CAAC,WAAW;iBAC1B,CAAC;gBACF,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS;oBAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;gBAChF,IAAI,CAAC,CAAC,kBAAkB,KAAK,CAAC;oBAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC;gBAC9D,IAAI,CAAC,CAAC,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS;oBAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;gBAC5E,OAAO,EAAkC,CAAC;YAC5C,CAAC,CAAC,CAAC;QACP,CAAC;IACH,CAAC;IAED,kCAAkC;IAClC,MAAM,iBAAiB,GAAG;QACxB,WAAW,EAAI,IAAI,CAAC,GAAG;QACvB,SAAS,EAAM,QAAQ;QACvB,aAAa,EAAE,EAAE;QACjB,MAAM;QACN,SAAS;QACT,WAAW;KACZ,CAAC;IAEF,sEAAsE;IACtE,MAAM,iBAAiB,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAE/F,OAAO,EAAE,GAAG,iBAAiB,EAAE,iBAAiB,EAAE,CAAC;AACrD,CAAC"}
|