@noy-db/hub 0.2.0-pre.1 → 0.2.0-pre.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aggregate/index.cjs.map +1 -1
- package/dist/aggregate/index.js +2 -2
- package/dist/attestation/index.cjs +305 -0
- package/dist/attestation/index.cjs.map +1 -0
- package/dist/attestation/index.d.cts +52 -0
- package/dist/attestation/index.d.ts +52 -0
- package/dist/attestation/index.js +36 -0
- package/dist/attestation/index.js.map +1 -0
- package/dist/blobs/index.cjs.map +1 -1
- package/dist/blobs/index.d.cts +4 -3
- package/dist/blobs/index.d.ts +4 -3
- package/dist/blobs/index.js +9 -7
- package/dist/blobs/index.js.map +1 -1
- package/dist/bundle/index.cjs +16701 -129
- package/dist/bundle/index.cjs.map +1 -1
- package/dist/bundle/index.d.cts +172 -3
- package/dist/bundle/index.d.ts +172 -3
- package/dist/bundle/index.js +533 -5
- package/dist/bundle/index.js.map +1 -1
- package/dist/{chunk-5SCJ5UEF.js → chunk-243PNUA6.js} +2 -2
- package/dist/{chunk-WCA2NROQ.js → chunk-2PAQNPE3.js} +2 -2
- package/dist/chunk-3QAKZ37R.js +83 -0
- package/dist/chunk-3QAKZ37R.js.map +1 -0
- package/dist/chunk-3S4BJX25.js +36 -0
- package/dist/chunk-3S4BJX25.js.map +1 -0
- package/dist/chunk-3XHOCQK4.js +118 -0
- package/dist/chunk-3XHOCQK4.js.map +1 -0
- package/dist/{chunk-4TFSM22V.js → chunk-3Y53S2SA.js} +3 -3
- package/dist/{chunk-6HPZY4ON.js → chunk-3Z2TPHC4.js} +3 -3
- package/dist/chunk-4HIL6AHQ.js +57 -0
- package/dist/chunk-4HIL6AHQ.js.map +1 -0
- package/dist/{chunk-DYECX3IX.js → chunk-7BRE6EUA.js} +2 -2
- package/dist/{chunk-DYBQG5PQ.js → chunk-7BUTTVMR.js} +2 -2
- package/dist/{chunk-KESP7GOK.js → chunk-7Q5PLD5C.js} +3 -3
- package/dist/{chunk-UA4RI7OT.js → chunk-7Z23ZFLV.js} +4 -4
- package/dist/chunk-AHPFONIL.js +59 -0
- package/dist/chunk-AHPFONIL.js.map +1 -0
- package/dist/{chunk-EGQYGYIU.js → chunk-CXSCDO5T.js} +2 -2
- package/dist/chunk-E535SAN4.js +8834 -0
- package/dist/chunk-E535SAN4.js.map +1 -0
- package/dist/{chunk-CBAHB2BF.js → chunk-EUYOGYGV.js} +6 -69
- package/dist/chunk-EUYOGYGV.js.map +1 -0
- package/dist/{chunk-OMLIZL2P.js → chunk-FAQVNJD4.js} +2 -2
- package/dist/{chunk-I6MX32UC.js → chunk-G6FRSBKK.js} +4 -4
- package/dist/{chunk-FCXOFQAJ.js → chunk-GIV6DWBG.js} +2 -2
- package/dist/{chunk-34YSDCDP.js → chunk-HXJXPZRE.js} +2 -2
- package/dist/{chunk-23TTQXVO.js → chunk-J4KLMEUL.js} +2 -2
- package/dist/{chunk-VMIO4IXG.js → chunk-JYQTXEIO.js} +5 -228
- package/dist/chunk-JYQTXEIO.js.map +1 -0
- package/dist/{chunk-NIOHFJPJ.js → chunk-LRAZDV5X.js} +6 -118
- package/dist/chunk-LRAZDV5X.js.map +1 -0
- package/dist/{chunk-P7EQ2S5O.js → chunk-MUWOSVEP.js} +2 -2
- package/dist/chunk-NWZ3I6R6.js +79 -0
- package/dist/chunk-NWZ3I6R6.js.map +1 -0
- package/dist/{chunk-HB3Z2GCR.js → chunk-OVZDFEOR.js} +2 -2
- package/dist/chunk-PFSNOPBQ.js +233 -0
- package/dist/chunk-PFSNOPBQ.js.map +1 -0
- package/dist/{chunk-UZXLQCHP.js → chunk-PLI5TV7N.js} +2 -2
- package/dist/{chunk-PA6R5ZCI.js → chunk-Q6W2CMEJ.js} +3 -3
- package/dist/{chunk-537VFZTR.js → chunk-QPEXPHJR.js} +4 -4
- package/dist/{chunk-ZNOEIM6Y.js → chunk-QXQRKXCU.js} +2 -2
- package/dist/{chunk-RD5LYKD6.js → chunk-RTZVQAJ7.js} +2 -2
- package/dist/{chunk-DPMFBCV6.js → chunk-TBKOGSYR.js} +2 -2
- package/dist/{chunk-DPMFBCV6.js.map → chunk-TBKOGSYR.js.map} +1 -1
- package/dist/chunk-UND4XIB6.js +251 -0
- package/dist/chunk-UND4XIB6.js.map +1 -0
- package/dist/{chunk-7H6DOO3E.js → chunk-VCGTOS2A.js} +211 -36
- package/dist/chunk-VCGTOS2A.js.map +1 -0
- package/dist/{chunk-MKSA2V7A.js → chunk-VE6YVP32.js} +2 -2
- package/dist/{chunk-5DWL3JBF.js → chunk-VK5EER6C.js} +2 -2
- package/dist/{chunk-MIQHZESA.js → chunk-VPSUZLOJ.js} +4 -4
- package/dist/{chunk-MIQHZESA.js.map → chunk-VPSUZLOJ.js.map} +1 -1
- package/dist/{chunk-XGSOTWYX.js → chunk-VRBCTEKQ.js} +2 -2
- package/dist/{chunk-ADQ5MQ54.js → chunk-W3XXT26A.js} +29 -1
- package/dist/{chunk-ADQ5MQ54.js.map → chunk-W3XXT26A.js.map} +1 -1
- package/dist/{chunk-2AXFIYHT.js → chunk-XG3PTSCD.js} +1 -1
- package/dist/chunk-XG3PTSCD.js.map +1 -0
- package/dist/{chunk-SIZWEV2Y.js → chunk-Y2RKOPNC.js} +4 -4
- package/dist/{chunk-SIZWEV2Y.js.map → chunk-Y2RKOPNC.js.map} +1 -1
- package/dist/{chunk-Z72JH4KG.js → chunk-YTXSFG3C.js} +4 -34
- package/dist/chunk-YTXSFG3C.js.map +1 -0
- package/dist/consent/index.cjs.map +1 -1
- package/dist/consent/index.d.cts +4 -3
- package/dist/consent/index.d.ts +4 -3
- package/dist/consent/index.js +3 -3
- package/dist/{crypto-A7FRXYHC.js → crypto-5ZDIY3NG.js} +3 -3
- package/dist/{delegation-YBA4X4JN.js → delegation-QYXZW25W.js} +5 -5
- package/dist/derivations/index.cjs.map +1 -1
- package/dist/derivations/index.d.cts +5 -4
- package/dist/derivations/index.d.ts +5 -4
- package/dist/derivations/index.js +4 -4
- package/dist/{dev-unlock-DRwVSy2S.d.cts → dev-unlock-DQCNDfFp.d.cts} +1 -1
- package/dist/{dev-unlock-D9s-loPr.d.ts → dev-unlock-utkybTKb.d.ts} +1 -1
- package/dist/executor-AS2IDHKZ.js +11 -0
- package/dist/executor-HLXFXNFM.js +8 -0
- package/dist/executor-HN6YBHZ5.js +8 -0
- package/dist/guards/index.cjs.map +1 -1
- package/dist/guards/index.d.cts +5 -4
- package/dist/guards/index.d.ts +5 -4
- package/dist/guards/index.js +3 -3
- package/dist/{hash-DXXXusyk.d.ts → hash-DcoYWfJ_.d.ts} +1 -1
- package/dist/{hash-DtRih9MQ.d.cts → hash-jDowCrK2.d.cts} +1 -1
- package/dist/history/index.cjs +1 -1
- package/dist/history/index.cjs.map +1 -1
- package/dist/history/index.d.cts +5 -4
- package/dist/history/index.d.ts +5 -4
- package/dist/history/index.js +5 -5
- package/dist/i18n/index.cjs.map +1 -1
- package/dist/i18n/index.d.cts +4 -3
- package/dist/i18n/index.d.ts +4 -3
- package/dist/i18n/index.js +13 -11
- package/dist/i18n/index.js.map +1 -1
- package/dist/{index-CNwA-B6-.d.ts → index-BCKdioeh.d.ts} +29 -1
- package/dist/{index-CmVgTkqk.d.cts → index-BMjrzNZr.d.cts} +29 -1
- package/dist/index.cjs +507 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -11
- package/dist/index.d.ts +12 -11
- package/dist/index.js +106 -8817
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.cjs.map +1 -1
- package/dist/indexing/index.js +2 -2
- package/dist/issue-ORP37MVW.js +12 -0
- package/dist/{ledger-3TXNP47J.js → ledger-3IU5GMXA.js} +5 -5
- package/dist/materialized-views/index.cjs.map +1 -1
- package/dist/materialized-views/index.d.cts +6 -5
- package/dist/materialized-views/index.d.ts +6 -5
- package/dist/materialized-views/index.js +6 -6
- package/dist/noydb-5H3C24GG.js +34 -0
- package/dist/overlay-views/index.cjs.map +1 -1
- package/dist/overlay-views/index.d.cts +5 -4
- package/dist/overlay-views/index.d.ts +5 -4
- package/dist/overlay-views/index.js +6 -4
- package/dist/periods/index.cjs.map +1 -1
- package/dist/periods/index.d.cts +4 -3
- package/dist/periods/index.d.ts +4 -3
- package/dist/periods/index.js +5 -5
- package/dist/{public-envelope-PY6NKFLI.js → public-envelope-U3CMEOMV.js} +3 -3
- package/dist/query/index.cjs.map +1 -1
- package/dist/query/index.d.cts +1 -1
- package/dist/query/index.d.ts +1 -1
- package/dist/query/index.js +3 -3
- package/dist/{registry-3L3N3PTG.js → registry-3ALP62P6.js} +3 -3
- package/dist/registry-7HE6VJGC.js +8 -0
- package/dist/registry-PSIPG2QR.js +8 -0
- package/dist/registry-PSIPG2QR.js.map +1 -0
- package/dist/revoke-KY2GB4KP.js +17 -0
- package/dist/revoke-KY2GB4KP.js.map +1 -0
- package/dist/session/index.cjs.map +1 -1
- package/dist/session/index.d.cts +5 -4
- package/dist/session/index.d.ts +5 -4
- package/dist/session/index.js +3 -3
- package/dist/shadow/index.cjs.map +1 -1
- package/dist/shadow/index.d.cts +4 -3
- package/dist/shadow/index.d.ts +4 -3
- package/dist/shadow/index.js +2 -2
- package/dist/signer-GRI5TZKH.js +18 -0
- package/dist/signer-GRI5TZKH.js.map +1 -0
- package/dist/{stale-HSC5YO2O.js → stale-OTOF3FH7.js} +2 -2
- package/dist/stale-OTOF3FH7.js.map +1 -0
- package/dist/store/index.cjs.map +1 -1
- package/dist/store/index.d.cts +4 -3
- package/dist/store/index.d.ts +4 -3
- package/dist/store/index.js +2 -2
- package/dist/sync/index.cjs.map +1 -1
- package/dist/sync/index.d.cts +3 -2
- package/dist/sync/index.d.ts +3 -2
- package/dist/sync/index.js +3 -3
- package/dist/team/index.cjs.map +1 -1
- package/dist/team/index.d.cts +4 -3
- package/dist/team/index.d.ts +4 -3
- package/dist/team/index.js +12 -10
- package/dist/tx/index.cjs.map +1 -1
- package/dist/tx/index.d.cts +4 -3
- package/dist/tx/index.d.ts +4 -3
- package/dist/tx/index.js +2 -2
- package/dist/{types-DW9RGSSs.d.ts → types-BoFFiskX.d.ts} +119 -3
- package/dist/{types-C4lwMKKF.d.cts → types-DJG8HG6F.d.cts} +119 -3
- package/dist/{index-hdFvZkBP.d.cts → ulid-BmBgooGm.d.ts} +51 -33
- package/dist/{index-4agOpzqd.d.ts → ulid-C7ms9oli.d.cts} +51 -33
- package/dist/util/index.cjs.map +1 -1
- package/dist/util/index.js +1 -1
- package/dist/{with-derivation-g-pGoMzL.d.ts → with-derivation-BKXXa8Vt.d.ts} +1 -1
- package/dist/{with-derivation-C8LDlV7t.d.cts → with-derivation-BjQ7q4NE.d.cts} +1 -1
- package/dist/{with-guard-DWOCK4Ca.d.ts → with-guard-C25yNjzd.d.ts} +1 -1
- package/dist/{with-guard-jI1x9Z3k.d.cts → with-guard-DQme5DKE.d.cts} +1 -1
- package/dist/{with-materialized-view-DcTx4H3j.d.cts → with-materialized-view-BbEPFIIJ.d.cts} +1 -1
- package/dist/{with-materialized-view-DaKR-N6J.d.ts → with-materialized-view-CqnRwI2S.d.ts} +1 -1
- package/dist/{with-overlayed-view-N7jYuNOS.d.ts → with-overlayed-view-Ct1fSJt-.d.ts} +1 -1
- package/dist/{with-overlayed-view-D-6oWAgM.d.cts → with-overlayed-view-bwlmmFjx.d.cts} +1 -1
- package/package.json +15 -3
- package/dist/chunk-2AXFIYHT.js.map +0 -1
- package/dist/chunk-7H6DOO3E.js.map +0 -1
- package/dist/chunk-CBAHB2BF.js.map +0 -1
- package/dist/chunk-NIOHFJPJ.js.map +0 -1
- package/dist/chunk-VMIO4IXG.js.map +0 -1
- package/dist/chunk-Z72JH4KG.js.map +0 -1
- package/dist/executor-7E3VFGW7.js +0 -11
- package/dist/executor-CEWX2FQI.js +0 -8
- package/dist/executor-X4SQ3ZLC.js +0 -8
- package/dist/registry-O47PUPSY.js +0 -8
- package/dist/registry-WLLMODKN.js +0 -8
- /package/dist/{chunk-5SCJ5UEF.js.map → chunk-243PNUA6.js.map} +0 -0
- /package/dist/{chunk-WCA2NROQ.js.map → chunk-2PAQNPE3.js.map} +0 -0
- /package/dist/{chunk-4TFSM22V.js.map → chunk-3Y53S2SA.js.map} +0 -0
- /package/dist/{chunk-6HPZY4ON.js.map → chunk-3Z2TPHC4.js.map} +0 -0
- /package/dist/{chunk-DYECX3IX.js.map → chunk-7BRE6EUA.js.map} +0 -0
- /package/dist/{chunk-DYBQG5PQ.js.map → chunk-7BUTTVMR.js.map} +0 -0
- /package/dist/{chunk-KESP7GOK.js.map → chunk-7Q5PLD5C.js.map} +0 -0
- /package/dist/{chunk-UA4RI7OT.js.map → chunk-7Z23ZFLV.js.map} +0 -0
- /package/dist/{chunk-EGQYGYIU.js.map → chunk-CXSCDO5T.js.map} +0 -0
- /package/dist/{chunk-OMLIZL2P.js.map → chunk-FAQVNJD4.js.map} +0 -0
- /package/dist/{chunk-I6MX32UC.js.map → chunk-G6FRSBKK.js.map} +0 -0
- /package/dist/{chunk-FCXOFQAJ.js.map → chunk-GIV6DWBG.js.map} +0 -0
- /package/dist/{chunk-34YSDCDP.js.map → chunk-HXJXPZRE.js.map} +0 -0
- /package/dist/{chunk-23TTQXVO.js.map → chunk-J4KLMEUL.js.map} +0 -0
- /package/dist/{chunk-P7EQ2S5O.js.map → chunk-MUWOSVEP.js.map} +0 -0
- /package/dist/{chunk-HB3Z2GCR.js.map → chunk-OVZDFEOR.js.map} +0 -0
- /package/dist/{chunk-UZXLQCHP.js.map → chunk-PLI5TV7N.js.map} +0 -0
- /package/dist/{chunk-PA6R5ZCI.js.map → chunk-Q6W2CMEJ.js.map} +0 -0
- /package/dist/{chunk-537VFZTR.js.map → chunk-QPEXPHJR.js.map} +0 -0
- /package/dist/{chunk-ZNOEIM6Y.js.map → chunk-QXQRKXCU.js.map} +0 -0
- /package/dist/{chunk-RD5LYKD6.js.map → chunk-RTZVQAJ7.js.map} +0 -0
- /package/dist/{chunk-MKSA2V7A.js.map → chunk-VE6YVP32.js.map} +0 -0
- /package/dist/{chunk-5DWL3JBF.js.map → chunk-VK5EER6C.js.map} +0 -0
- /package/dist/{chunk-XGSOTWYX.js.map → chunk-VRBCTEKQ.js.map} +0 -0
- /package/dist/{crypto-A7FRXYHC.js.map → crypto-5ZDIY3NG.js.map} +0 -0
- /package/dist/{delegation-YBA4X4JN.js.map → delegation-QYXZW25W.js.map} +0 -0
- /package/dist/{executor-7E3VFGW7.js.map → executor-AS2IDHKZ.js.map} +0 -0
- /package/dist/{executor-CEWX2FQI.js.map → executor-HLXFXNFM.js.map} +0 -0
- /package/dist/{executor-X4SQ3ZLC.js.map → executor-HN6YBHZ5.js.map} +0 -0
- /package/dist/{ledger-3TXNP47J.js.map → issue-ORP37MVW.js.map} +0 -0
- /package/dist/{public-envelope-PY6NKFLI.js.map → ledger-3IU5GMXA.js.map} +0 -0
- /package/dist/{registry-3L3N3PTG.js.map → noydb-5H3C24GG.js.map} +0 -0
- /package/dist/{registry-O47PUPSY.js.map → public-envelope-U3CMEOMV.js.map} +0 -0
- /package/dist/{registry-WLLMODKN.js.map → registry-3ALP62P6.js.map} +0 -0
- /package/dist/{stale-HSC5YO2O.js.map → registry-7HE6VJGC.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -46,7 +46,7 @@ var init_types = __esm({
|
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
// src/errors.ts
|
|
49
|
-
var NoydbError, DecryptionError, TamperedError, InvalidKeyError, KeyringCorruptError, NoAccessError, ReadOnlyError, ReadOnlyAtInstantError, ReadOnlyFrameError, PermissionDeniedError, ExportCapabilityError, KeyringExpiredError, ImportCapabilityError, StoreCapabilityError, PrivilegeEscalationError, PeriodClosedError, RecordLockedError, FieldFrozenError, InvariantError, AmendmentForbiddenError, DirectoryDisabledError, TierNotGrantedError, ElevationExpiredError, AlreadyElevatedError, TierDemoteDeniedError, DelegationTargetMissingError, ConflictError, LedgerContentionError, BundleVersionConflictError, NetworkError, NotFoundError, ValidationError, SchemaValidationError, GroupCardinalityError, IndexRequiredError, IndexWriteFailureError, BundleIntegrityError, BundleSealMismatchError, ReservedCollectionNameError, DictKeyMissingError, DictKeyInUseError, MissingTranslationError, LocaleNotSpecifiedError, TranslatorNotConfiguredError, BackupLedgerError, BackupCorruptedError, SessionExpiredError, SessionNotFoundError, SessionPolicyError, JoinTooLargeError, DanglingReferenceError, FilenameSanitizationError, PathEscapeError, DerivationCycleError, DerivationDepthError, DerivationOutputUnknownError, DerivationOutputShapeError, DerivationCapExceededError, MaterializedViewCycleError, MaterializedViewSourceUnknownError, MaterializedViewTooLargeError, MaterializedViewConfigError, OverlayBaseIsVirtualError, OverlayCollectionUnavailableError, OverlayNameCollisionError, OverlayIdMismatchError;
|
|
49
|
+
var NoydbError, DecryptionError, TamperedError, InvalidKeyError, KeyringCorruptError, NoAccessError, ReadOnlyError, ReadOnlyAtInstantError, ReadOnlyFrameError, PermissionDeniedError, ExportCapabilityError, KeyringExpiredError, ImportCapabilityError, StoreCapabilityError, PrivilegeEscalationError, PeriodClosedError, RecordLockedError, FieldFrozenError, InvariantError, AmendmentForbiddenError, DirectoryDisabledError, TierNotGrantedError, ElevationExpiredError, AlreadyElevatedError, TierDemoteDeniedError, DelegationTargetMissingError, ConflictError, LedgerContentionError, BundleVersionConflictError, NetworkError, NotFoundError, ValidationError, SchemaValidationError, GroupCardinalityError, IndexRequiredError, IndexWriteFailureError, BundleIntegrityError, BundleSealMismatchError, ReservedCollectionNameError, DictKeyMissingError, DictKeyInUseError, MissingTranslationError, LocaleNotSpecifiedError, TranslatorNotConfiguredError, BackupLedgerError, BackupCorruptedError, AttestationError, SessionExpiredError, SessionNotFoundError, SessionPolicyError, JoinTooLargeError, DanglingReferenceError, FilenameSanitizationError, PathEscapeError, DerivationCycleError, DerivationDepthError, DerivationOutputUnknownError, DerivationOutputShapeError, DerivationCapExceededError, MaterializedViewCycleError, MaterializedViewSourceUnknownError, MaterializedViewTooLargeError, MaterializedViewConfigError, OverlayBaseIsVirtualError, OverlayCollectionUnavailableError, OverlayNameCollisionError, OverlayIdMismatchError;
|
|
50
50
|
var init_errors = __esm({
|
|
51
51
|
"src/errors.ts"() {
|
|
52
52
|
"use strict";
|
|
@@ -563,6 +563,12 @@ Resolutions:
|
|
|
563
563
|
this.id = id;
|
|
564
564
|
}
|
|
565
565
|
};
|
|
566
|
+
AttestationError = class extends NoydbError {
|
|
567
|
+
constructor(message) {
|
|
568
|
+
super("ATTESTATION", message);
|
|
569
|
+
this.name = "AttestationError";
|
|
570
|
+
}
|
|
571
|
+
};
|
|
566
572
|
SessionExpiredError = class extends NoydbError {
|
|
567
573
|
sessionId;
|
|
568
574
|
constructor(sessionId) {
|
|
@@ -3298,6 +3304,185 @@ var init_fanout_sidecar = __esm({
|
|
|
3298
3304
|
}
|
|
3299
3305
|
});
|
|
3300
3306
|
|
|
3307
|
+
// src/attestation/signer.ts
|
|
3308
|
+
var signer_exports = {};
|
|
3309
|
+
__export(signer_exports, {
|
|
3310
|
+
ATTESTATIONS_COLLECTION: () => ATTESTATIONS_COLLECTION,
|
|
3311
|
+
REVOKED_RECORD_ID: () => REVOKED_RECORD_ID,
|
|
3312
|
+
SIGNER_RECORD_ID: () => SIGNER_RECORD_ID,
|
|
3313
|
+
loadOrCreateSigner: () => loadOrCreateSigner,
|
|
3314
|
+
loadSigner: () => loadSigner
|
|
3315
|
+
});
|
|
3316
|
+
async function loadSigner(store, vault, getDEK) {
|
|
3317
|
+
const existing = await store.get(vault, ATTESTATIONS_COLLECTION, SIGNER_RECORD_ID);
|
|
3318
|
+
if (!existing) return null;
|
|
3319
|
+
const dek = await getDEK(ATTESTATIONS_COLLECTION);
|
|
3320
|
+
const json = await decrypt(existing._iv, existing._data, dek);
|
|
3321
|
+
return JSON.parse(json);
|
|
3322
|
+
}
|
|
3323
|
+
async function loadOrCreateSigner(store, vault, getDEK) {
|
|
3324
|
+
const existing = await loadSigner(store, vault, getDEK);
|
|
3325
|
+
if (existing) return existing;
|
|
3326
|
+
const dek = await getDEK(ATTESTATIONS_COLLECTION);
|
|
3327
|
+
const signer = await (0, import_attestation.generateDocSigningKeyPair)();
|
|
3328
|
+
const { iv, data } = await encrypt(JSON.stringify(signer), dek);
|
|
3329
|
+
const env = {
|
|
3330
|
+
_noydb: NOYDB_FORMAT_VERSION,
|
|
3331
|
+
_v: 1,
|
|
3332
|
+
_ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3333
|
+
_iv: iv,
|
|
3334
|
+
_data: data
|
|
3335
|
+
};
|
|
3336
|
+
try {
|
|
3337
|
+
await store.put(vault, ATTESTATIONS_COLLECTION, SIGNER_RECORD_ID, env, 0);
|
|
3338
|
+
return signer;
|
|
3339
|
+
} catch (e) {
|
|
3340
|
+
if (!(e instanceof ConflictError)) throw e;
|
|
3341
|
+
const winner = await loadSigner(store, vault, getDEK);
|
|
3342
|
+
if (!winner) {
|
|
3343
|
+
throw new ConflictError(0, "loadOrCreateSigner: signer mint lost a concurrent race but the winning record could not be re-read.");
|
|
3344
|
+
}
|
|
3345
|
+
return winner;
|
|
3346
|
+
}
|
|
3347
|
+
}
|
|
3348
|
+
var import_attestation, ATTESTATIONS_COLLECTION, SIGNER_RECORD_ID, REVOKED_RECORD_ID;
|
|
3349
|
+
var init_signer = __esm({
|
|
3350
|
+
"src/attestation/signer.ts"() {
|
|
3351
|
+
"use strict";
|
|
3352
|
+
init_types();
|
|
3353
|
+
init_crypto();
|
|
3354
|
+
init_errors();
|
|
3355
|
+
import_attestation = require("@noy-db/attestation");
|
|
3356
|
+
ATTESTATIONS_COLLECTION = "_attestations";
|
|
3357
|
+
SIGNER_RECORD_ID = "_signer";
|
|
3358
|
+
REVOKED_RECORD_ID = "_revoked";
|
|
3359
|
+
}
|
|
3360
|
+
});
|
|
3361
|
+
|
|
3362
|
+
// src/attestation/issue.ts
|
|
3363
|
+
var issue_exports = {};
|
|
3364
|
+
__export(issue_exports, {
|
|
3365
|
+
issueAttestationCore: () => issueAttestationCore
|
|
3366
|
+
});
|
|
3367
|
+
async function issueAttestationCore(ctx, args) {
|
|
3368
|
+
if (ctx.role !== "owner") {
|
|
3369
|
+
throw new AttestationError(`issueAttestation requires the 'owner' role; caller is '${ctx.role}'. Issuing a signed attestation is the firm's identity operation.`);
|
|
3370
|
+
}
|
|
3371
|
+
const src = await ctx.readRecord(args.collection, args.id);
|
|
3372
|
+
if (!src) throw new AttestationError(`issueAttestation: source record '${args.collection}/${args.id}' not found.`);
|
|
3373
|
+
const dek = await ctx.getDEK();
|
|
3374
|
+
const signer = await loadOrCreateSigner(ctx.store, ctx.vault, () => Promise.resolve(dek));
|
|
3375
|
+
const saltB64 = (0, import_attestation2.bytesToB64url)(crypto.getRandomValues(new Uint8Array(16)));
|
|
3376
|
+
let fieldHashes;
|
|
3377
|
+
try {
|
|
3378
|
+
fieldHashes = await (0, import_attestation2.computeFieldHashes)(saltB64, args.fieldSchema, src.record);
|
|
3379
|
+
} catch (e) {
|
|
3380
|
+
throw new AttestationError(`issueAttestation: ${e.message}`);
|
|
3381
|
+
}
|
|
3382
|
+
const docId = generateULID();
|
|
3383
|
+
const sig = await (0, import_attestation2.signPayloadCore)({ v: 1, docId, salt: saltB64, keyId: signer.keyId, fieldHashes }, signer.privateKeyPkcs8B64);
|
|
3384
|
+
const payload = { v: 1, docId, salt: saltB64, alg: "ed25519", keyId: signer.keyId, fieldHashes, sig };
|
|
3385
|
+
const index = {
|
|
3386
|
+
docId,
|
|
3387
|
+
issuedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3388
|
+
keyId: signer.keyId,
|
|
3389
|
+
fieldPaths: args.fieldSchema.fields.map((f) => f.path),
|
|
3390
|
+
sourceRefs: [{ collection: args.collection, id: args.id, version: src.version }]
|
|
3391
|
+
};
|
|
3392
|
+
const { iv, data } = await encrypt(JSON.stringify(index), dek);
|
|
3393
|
+
const env = { _noydb: NOYDB_FORMAT_VERSION, _v: 1, _ts: index.issuedAt, _iv: iv, _data: data };
|
|
3394
|
+
await ctx.store.put(ctx.vault, ATTESTATIONS_COLLECTION, docId, env);
|
|
3395
|
+
return { docId, qr: (0, import_attestation2.encodeQr)(payload), payload, keyId: signer.keyId, publicKeyB64: signer.publicKeyB64 };
|
|
3396
|
+
}
|
|
3397
|
+
var import_attestation2;
|
|
3398
|
+
var init_issue = __esm({
|
|
3399
|
+
"src/attestation/issue.ts"() {
|
|
3400
|
+
"use strict";
|
|
3401
|
+
init_types();
|
|
3402
|
+
init_crypto();
|
|
3403
|
+
init_errors();
|
|
3404
|
+
init_ulid();
|
|
3405
|
+
init_signer();
|
|
3406
|
+
import_attestation2 = require("@noy-db/attestation");
|
|
3407
|
+
}
|
|
3408
|
+
});
|
|
3409
|
+
|
|
3410
|
+
// src/attestation/revoke.ts
|
|
3411
|
+
var revoke_exports = {};
|
|
3412
|
+
__export(revoke_exports, {
|
|
3413
|
+
getRevokedDocIdsCore: () => getRevokedDocIdsCore,
|
|
3414
|
+
publishRevocationListCore: () => publishRevocationListCore,
|
|
3415
|
+
revokeDocCore: () => revokeDocCore,
|
|
3416
|
+
unrevokeDocCore: () => unrevokeDocCore
|
|
3417
|
+
});
|
|
3418
|
+
function requireOwner(ctx, op) {
|
|
3419
|
+
if (ctx.role !== "owner") {
|
|
3420
|
+
throw new AttestationError(`${op} requires the 'owner' role; caller is '${ctx.role}'. Revocation is the firm's identity operation.`);
|
|
3421
|
+
}
|
|
3422
|
+
}
|
|
3423
|
+
async function readSet(store, vault, dek) {
|
|
3424
|
+
const env = await store.get(vault, ATTESTATIONS_COLLECTION, REVOKED_RECORD_ID);
|
|
3425
|
+
if (!env) return { docIds: /* @__PURE__ */ new Set(), version: void 0 };
|
|
3426
|
+
const set = JSON.parse(await decrypt(env._iv, env._data, dek));
|
|
3427
|
+
return { docIds: new Set(set.docIds), version: env._v };
|
|
3428
|
+
}
|
|
3429
|
+
async function mutateSet(ctx, mutate) {
|
|
3430
|
+
const dek = await ctx.getDEK();
|
|
3431
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
3432
|
+
const { docIds, version } = await readSet(ctx.store, ctx.vault, dek);
|
|
3433
|
+
mutate(docIds);
|
|
3434
|
+
const payload = { docIds: [...docIds].sort(), updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
3435
|
+
const { iv, data } = await encrypt(JSON.stringify(payload), dek);
|
|
3436
|
+
const expectedVersion = version ?? 0;
|
|
3437
|
+
const env = {
|
|
3438
|
+
_noydb: NOYDB_FORMAT_VERSION,
|
|
3439
|
+
_v: expectedVersion + 1,
|
|
3440
|
+
_ts: payload.updatedAt,
|
|
3441
|
+
_iv: iv,
|
|
3442
|
+
_data: data
|
|
3443
|
+
};
|
|
3444
|
+
try {
|
|
3445
|
+
await ctx.store.put(ctx.vault, ATTESTATIONS_COLLECTION, REVOKED_RECORD_ID, env, expectedVersion);
|
|
3446
|
+
return;
|
|
3447
|
+
} catch (e) {
|
|
3448
|
+
if (e instanceof ConflictError && attempt === 0) continue;
|
|
3449
|
+
throw e;
|
|
3450
|
+
}
|
|
3451
|
+
}
|
|
3452
|
+
}
|
|
3453
|
+
async function revokeDocCore(ctx, docId) {
|
|
3454
|
+
requireOwner(ctx, "revokeAttestation");
|
|
3455
|
+
const issued = await ctx.store.get(ctx.vault, ATTESTATIONS_COLLECTION, docId);
|
|
3456
|
+
if (!issued) throw new AttestationError(`revokeAttestation: attestation '${docId}' not found (was it issued by this vault?).`);
|
|
3457
|
+
await mutateSet(ctx, (ids) => ids.add(docId));
|
|
3458
|
+
}
|
|
3459
|
+
async function unrevokeDocCore(ctx, docId) {
|
|
3460
|
+
requireOwner(ctx, "unrevokeAttestation");
|
|
3461
|
+
await mutateSet(ctx, (ids) => ids.delete(docId));
|
|
3462
|
+
}
|
|
3463
|
+
async function getRevokedDocIdsCore(ctx) {
|
|
3464
|
+
const dek = await ctx.getDEK();
|
|
3465
|
+
const { docIds } = await readSet(ctx.store, ctx.vault, dek);
|
|
3466
|
+
return [...docIds].sort();
|
|
3467
|
+
}
|
|
3468
|
+
async function publishRevocationListCore(ctx) {
|
|
3469
|
+
requireOwner(ctx, "publishRevocationList");
|
|
3470
|
+
const docIds = await getRevokedDocIdsCore(ctx);
|
|
3471
|
+
const signer = await loadOrCreateSigner(ctx.store, ctx.vault, () => ctx.getDEK());
|
|
3472
|
+
return (0, import_attestation3.signRevocationList)(docIds, (/* @__PURE__ */ new Date()).toISOString(), signer.keyId, signer.privateKeyPkcs8B64);
|
|
3473
|
+
}
|
|
3474
|
+
var import_attestation3;
|
|
3475
|
+
var init_revoke = __esm({
|
|
3476
|
+
"src/attestation/revoke.ts"() {
|
|
3477
|
+
"use strict";
|
|
3478
|
+
init_types();
|
|
3479
|
+
init_crypto();
|
|
3480
|
+
init_errors();
|
|
3481
|
+
init_signer();
|
|
3482
|
+
import_attestation3 = require("@noy-db/attestation");
|
|
3483
|
+
}
|
|
3484
|
+
});
|
|
3485
|
+
|
|
3301
3486
|
// src/guards/registry.ts
|
|
3302
3487
|
var registry_exports2 = {};
|
|
3303
3488
|
__export(registry_exports2, {
|
|
@@ -3695,6 +3880,7 @@ __export(src_exports, {
|
|
|
3695
3880
|
Aggregation: () => Aggregation,
|
|
3696
3881
|
AlreadyElevatedError: () => AlreadyElevatedError,
|
|
3697
3882
|
AmendmentForbiddenError: () => AmendmentForbiddenError,
|
|
3883
|
+
AttestationError: () => AttestationError,
|
|
3698
3884
|
BLOB_CHUNKS_COLLECTION: () => BLOB_CHUNKS_COLLECTION,
|
|
3699
3885
|
BLOB_COLLECTION: () => BLOB_COLLECTION,
|
|
3700
3886
|
BLOB_INDEX_COLLECTION: () => BLOB_INDEX_COLLECTION,
|
|
@@ -3768,6 +3954,7 @@ __export(src_exports, {
|
|
|
3768
3954
|
MaterializedViewCycleError: () => MaterializedViewCycleError,
|
|
3769
3955
|
MaterializedViewSourceUnknownError: () => MaterializedViewSourceUnknownError,
|
|
3770
3956
|
MaterializedViewTooLargeError: () => MaterializedViewTooLargeError,
|
|
3957
|
+
MemoryRecipientSealer: () => MemoryRecipientSealer,
|
|
3771
3958
|
MemorySealingKeyProvider: () => MemorySealingKeyProvider,
|
|
3772
3959
|
MissingTranslationError: () => MissingTranslationError,
|
|
3773
3960
|
NOYDB_BACKUP_VERSION: () => NOYDB_BACKUP_VERSION,
|
|
@@ -5878,7 +6065,9 @@ var ALLOWED_HEADER_KEYS = /* @__PURE__ */ new Set([
|
|
|
5878
6065
|
"bodyBytes",
|
|
5879
6066
|
"bodySha256",
|
|
5880
6067
|
"publicEnvelope",
|
|
5881
|
-
"autoUnlock"
|
|
6068
|
+
"autoUnlock",
|
|
6069
|
+
"bundleKind",
|
|
6070
|
+
"transferSeal"
|
|
5882
6071
|
]);
|
|
5883
6072
|
function validateBundleHeader(parsed) {
|
|
5884
6073
|
if (parsed === null || typeof parsed !== "object") {
|
|
@@ -5941,6 +6130,47 @@ function validateBundleHeader(parsed) {
|
|
|
5941
6130
|
);
|
|
5942
6131
|
}
|
|
5943
6132
|
}
|
|
6133
|
+
if (h["bundleKind"] !== void 0) {
|
|
6134
|
+
if (h["bundleKind"] !== "snapshot" && h["bundleKind"] !== "extracted-partition") {
|
|
6135
|
+
const got = typeof h["bundleKind"] === "string" ? `"${h["bundleKind"]}"` : typeof h["bundleKind"];
|
|
6136
|
+
throw new Error(
|
|
6137
|
+
`.noydb bundle header.bundleKind must be 'snapshot' or 'extracted-partition' when present, got ${got}.`
|
|
6138
|
+
);
|
|
6139
|
+
}
|
|
6140
|
+
}
|
|
6141
|
+
if (h["transferSeal"] !== void 0) {
|
|
6142
|
+
const ts = h["transferSeal"];
|
|
6143
|
+
if (ts === null || typeof ts !== "object" || Array.isArray(ts)) {
|
|
6144
|
+
throw new Error(`.noydb bundle header.transferSeal must be a JSON object when present, got ${typeof ts}.`);
|
|
6145
|
+
}
|
|
6146
|
+
const t = ts;
|
|
6147
|
+
if (t["v"] !== 1) {
|
|
6148
|
+
throw new Error(`.noydb bundle header.transferSeal.v must be 1, got ${String(t["v"])}.`);
|
|
6149
|
+
}
|
|
6150
|
+
if (t["alg"] !== "aes-256-gcm-pre-shared") {
|
|
6151
|
+
throw new Error(`.noydb bundle header.transferSeal.alg must be 'aes-256-gcm-pre-shared', got ${String(t["alg"])}.`);
|
|
6152
|
+
}
|
|
6153
|
+
if (typeof t["sealId"] !== "string" || t["sealId"].length === 0) {
|
|
6154
|
+
throw new Error(`.noydb bundle header.transferSeal.sealId must be a non-empty string, got ${String(t["sealId"])}.`);
|
|
6155
|
+
}
|
|
6156
|
+
}
|
|
6157
|
+
const isExtracted = h["bundleKind"] === "extracted-partition";
|
|
6158
|
+
const hasSeal = h["transferSeal"] !== void 0;
|
|
6159
|
+
if (hasSeal && !isExtracted) {
|
|
6160
|
+
throw new Error(
|
|
6161
|
+
`.noydb bundle header.transferSeal requires bundleKind === 'extracted-partition'.`
|
|
6162
|
+
);
|
|
6163
|
+
}
|
|
6164
|
+
if (isExtracted && !hasSeal) {
|
|
6165
|
+
throw new Error(
|
|
6166
|
+
`.noydb bundle header with bundleKind === 'extracted-partition' must carry a transferSeal indicator.`
|
|
6167
|
+
);
|
|
6168
|
+
}
|
|
6169
|
+
if (isExtracted && h["autoUnlock"] !== void 0) {
|
|
6170
|
+
throw new Error(
|
|
6171
|
+
`.noydb bundle header cannot carry both autoUnlock and bundleKind === 'extracted-partition' \u2014 an extracted partition is unlocked via its transfer seal, not an auto-credential.`
|
|
6172
|
+
);
|
|
6173
|
+
}
|
|
5944
6174
|
}
|
|
5945
6175
|
function encodeBundleHeader(header) {
|
|
5946
6176
|
validateBundleHeader(header);
|
|
@@ -5950,7 +6180,9 @@ function encodeBundleHeader(header) {
|
|
|
5950
6180
|
bodyBytes: header.bodyBytes,
|
|
5951
6181
|
bodySha256: header.bodySha256,
|
|
5952
6182
|
...header.publicEnvelope !== void 0 ? { publicEnvelope: header.publicEnvelope } : {},
|
|
5953
|
-
...header.autoUnlock !== void 0 ? { autoUnlock: header.autoUnlock } : {}
|
|
6183
|
+
...header.autoUnlock !== void 0 ? { autoUnlock: header.autoUnlock } : {},
|
|
6184
|
+
...header.bundleKind !== void 0 ? { bundleKind: header.bundleKind } : {},
|
|
6185
|
+
...header.transferSeal !== void 0 ? { transferSeal: header.transferSeal } : {}
|
|
5954
6186
|
});
|
|
5955
6187
|
return new TextEncoder().encode(json);
|
|
5956
6188
|
}
|
|
@@ -6012,10 +6244,19 @@ function normalizeAutoUnlock(opts) {
|
|
|
6012
6244
|
return { mode: "unsealed", perUser: toAutoCredentials(opts.autoPassphrases.perUser) };
|
|
6013
6245
|
}
|
|
6014
6246
|
if (opts.sealedCredentials !== void 0) {
|
|
6015
|
-
|
|
6247
|
+
if (opts.sealedCredentials.mode === "recipient-target") {
|
|
6248
|
+
const perUser = {};
|
|
6249
|
+
const hints = {};
|
|
6250
|
+
for (const [userId, entry] of Object.entries(opts.sealedCredentials.perUser)) {
|
|
6251
|
+
perUser[userId] = entry.credential;
|
|
6252
|
+
hints[userId] = entry.hint;
|
|
6253
|
+
}
|
|
6254
|
+
return { mode: "sealed-recipient", provider: opts.sealedCredentials.provider, perUser, hints };
|
|
6255
|
+
}
|
|
6256
|
+
return { mode: "sealed-self", provider: opts.sealedCredentials.provider, perUser: opts.sealedCredentials.perUser };
|
|
6016
6257
|
}
|
|
6017
6258
|
return {
|
|
6018
|
-
mode: "sealed",
|
|
6259
|
+
mode: "sealed-self",
|
|
6019
6260
|
provider: opts.sealedPassphrases.provider,
|
|
6020
6261
|
perUser: toAutoCredentials(opts.sealedPassphrases.perUser)
|
|
6021
6262
|
};
|
|
@@ -6045,10 +6286,52 @@ function validateAutoUnlockOptions(opts, normalized) {
|
|
|
6045
6286
|
}
|
|
6046
6287
|
return "unsealed";
|
|
6047
6288
|
}
|
|
6048
|
-
|
|
6049
|
-
|
|
6289
|
+
if (normalized.mode === "sealed-recipient") {
|
|
6290
|
+
const provider = normalized.provider;
|
|
6291
|
+
if (provider === void 0 || typeof provider.publishRecipientHint !== "function" || typeof provider.sealForRecipient !== "function") {
|
|
6292
|
+
throw new ValidationError(
|
|
6293
|
+
"writeNoydbBundle: `sealedCredentials.provider` for mode 'recipient-target' must be a RecipientSealer (publishRecipientHint + sealForRecipient). Self-only providers (MemorySealingKeyProvider, at-macos-keychain, etc.) do not satisfy this contract."
|
|
6294
|
+
);
|
|
6295
|
+
}
|
|
6296
|
+
const hints = normalized.hints;
|
|
6297
|
+
if (hints === void 0) {
|
|
6298
|
+
throw new Error("unreachable \u2014 sealed-recipient normalization must populate hints");
|
|
6299
|
+
}
|
|
6300
|
+
for (const userId of Object.keys(normalized.perUser)) {
|
|
6301
|
+
const hint = hints[userId];
|
|
6302
|
+
if (hint === void 0) {
|
|
6303
|
+
throw new ValidationError(
|
|
6304
|
+
`writeNoydbBundle: \`sealedCredentials.perUser['${userId}']\` missing required \`hint\` for mode 'recipient-target'.`
|
|
6305
|
+
);
|
|
6306
|
+
}
|
|
6307
|
+
if (hint.v !== 1) {
|
|
6308
|
+
throw new ValidationError(
|
|
6309
|
+
`writeNoydbBundle: \`sealedCredentials.perUser['${userId}'].hint.v\` must be 1 (got ${String(hint.v)}).`
|
|
6310
|
+
);
|
|
6311
|
+
}
|
|
6312
|
+
if (typeof hint.pid !== "string" || hint.pid.length === 0) {
|
|
6313
|
+
throw new ValidationError(
|
|
6314
|
+
`writeNoydbBundle: \`sealedCredentials.perUser['${userId}'].hint.pid\` must be a non-empty string identifying the recipient.`
|
|
6315
|
+
);
|
|
6316
|
+
}
|
|
6317
|
+
if (hint.alg !== "rsa-oaep-sha256") {
|
|
6318
|
+
throw new ValidationError(
|
|
6319
|
+
`writeNoydbBundle: \`sealedCredentials.perUser['${userId}'].hint.alg\` must be 'rsa-oaep-sha256' in slice 1 (got '${String(hint.alg)}').`
|
|
6320
|
+
);
|
|
6321
|
+
}
|
|
6322
|
+
}
|
|
6323
|
+
const userCount2 = Object.keys(normalized.perUser).length;
|
|
6324
|
+
if (userCount2 === 0) {
|
|
6325
|
+
throw new ValidationError(
|
|
6326
|
+
"writeNoydbBundle: `sealedCredentials.perUser` must have at least one entry."
|
|
6327
|
+
);
|
|
6328
|
+
}
|
|
6329
|
+
return "sealed";
|
|
6330
|
+
}
|
|
6331
|
+
const selfTargetMode = opts.sealedCredentials?.mode ?? opts.sealedPassphrases?.mode;
|
|
6332
|
+
if (selfTargetMode !== "self-target") {
|
|
6050
6333
|
throw new ValidationError(
|
|
6051
|
-
`writeNoydbBundle: \`sealedCredentials.mode\` (or \`sealedPassphrases.mode\`) must be 'self-target'
|
|
6334
|
+
`writeNoydbBundle: \`sealedCredentials.mode\` (or \`sealedPassphrases.mode\`) must be 'self-target' or 'recipient-target' (got '${String(selfTargetMode)}').`
|
|
6052
6335
|
);
|
|
6053
6336
|
}
|
|
6054
6337
|
if (normalized.provider === void 0) {
|
|
@@ -6081,14 +6364,35 @@ async function buildAutoUnlockWrapper(dumpJson, normalized) {
|
|
|
6081
6364
|
}
|
|
6082
6365
|
const sealedPerUser = {};
|
|
6083
6366
|
const encoder = new TextEncoder();
|
|
6084
|
-
|
|
6085
|
-
const
|
|
6086
|
-
|
|
6087
|
-
|
|
6088
|
-
|
|
6089
|
-
|
|
6090
|
-
|
|
6091
|
-
|
|
6367
|
+
if (normalized.mode === "sealed-recipient") {
|
|
6368
|
+
const recipientSealer = provider;
|
|
6369
|
+
const hints = normalized.hints;
|
|
6370
|
+
if (hints === void 0) {
|
|
6371
|
+
throw new Error("unreachable \u2014 sealed-recipient normalization must populate hints");
|
|
6372
|
+
}
|
|
6373
|
+
for (const [userId, cred] of Object.entries(normalized.perUser)) {
|
|
6374
|
+
const hint = hints[userId];
|
|
6375
|
+
const sealed = await recipientSealer.sealForRecipient(encoder.encode(cred.value), hint);
|
|
6376
|
+
sealedPerUser[userId] = {
|
|
6377
|
+
pid: hint.pid,
|
|
6378
|
+
// use the recipient's pid, not the sender's
|
|
6379
|
+
sealed: bytesToBase64(sealed),
|
|
6380
|
+
alg: "aes-256-gcm",
|
|
6381
|
+
kind: cred.kind,
|
|
6382
|
+
hint
|
|
6383
|
+
};
|
|
6384
|
+
}
|
|
6385
|
+
} else {
|
|
6386
|
+
const selfSealer = provider;
|
|
6387
|
+
for (const [userId, cred] of Object.entries(normalized.perUser)) {
|
|
6388
|
+
const sealed = await selfSealer.seal(encoder.encode(cred.value));
|
|
6389
|
+
sealedPerUser[userId] = {
|
|
6390
|
+
pid: selfSealer.id,
|
|
6391
|
+
sealed: bytesToBase64(sealed),
|
|
6392
|
+
alg: "aes-256-gcm",
|
|
6393
|
+
kind: cred.kind
|
|
6394
|
+
};
|
|
6395
|
+
}
|
|
6092
6396
|
}
|
|
6093
6397
|
return {
|
|
6094
6398
|
_noydb_bundle_body: 1,
|
|
@@ -6171,11 +6475,19 @@ async function resolveAutoUnlock(blob, opts) {
|
|
|
6171
6475
|
}
|
|
6172
6476
|
}
|
|
6173
6477
|
if (opened === null) {
|
|
6478
|
+
if (entry.hint !== void 0) {
|
|
6479
|
+
unsealedMap[userId] = { kind: credKind, value: entry.sealed };
|
|
6480
|
+
continue;
|
|
6481
|
+
}
|
|
6174
6482
|
throw new BundleSealMismatchError(userId, entry.pid);
|
|
6175
6483
|
}
|
|
6176
6484
|
unsealedMap[userId] = { kind: credKind, value: opened };
|
|
6177
6485
|
continue;
|
|
6178
6486
|
}
|
|
6487
|
+
if (entry.hint !== void 0) {
|
|
6488
|
+
unsealedMap[userId] = { kind: credKind, value: entry.sealed };
|
|
6489
|
+
continue;
|
|
6490
|
+
}
|
|
6179
6491
|
throw new BundleSealMismatchError(userId, entry.pid);
|
|
6180
6492
|
}
|
|
6181
6493
|
const plaintextBytes = await provider.unseal(base64ToBytes(entry.sealed));
|
|
@@ -6343,6 +6655,29 @@ async function applyPlaintextFilters(vault, dumpJson, opts) {
|
|
|
6343
6655
|
backup.collections = next;
|
|
6344
6656
|
return JSON.stringify(backup);
|
|
6345
6657
|
}
|
|
6658
|
+
async function assembleBundleContainer(opts) {
|
|
6659
|
+
const dumpBytes = new TextEncoder().encode(opts.bodyJsonStr);
|
|
6660
|
+
const { format, streamFormat } = selectCompression(opts.compression);
|
|
6661
|
+
const body = streamFormat === null ? dumpBytes : await pumpThroughStream(dumpBytes, new CompressionStream(streamFormat));
|
|
6662
|
+
const bodySha256 = await sha256Hex2(body);
|
|
6663
|
+
const header = {
|
|
6664
|
+
formatVersion: NOYDB_BUNDLE_FORMAT_VERSION,
|
|
6665
|
+
handle: opts.handle,
|
|
6666
|
+
bodyBytes: body.length,
|
|
6667
|
+
bodySha256,
|
|
6668
|
+
...opts.headerExtras?.publicEnvelope !== void 0 ? { publicEnvelope: opts.headerExtras.publicEnvelope } : {},
|
|
6669
|
+
...opts.headerExtras?.autoUnlock !== void 0 ? { autoUnlock: opts.headerExtras.autoUnlock } : {},
|
|
6670
|
+
...opts.headerExtras?.bundleKind !== void 0 ? { bundleKind: opts.headerExtras.bundleKind } : {},
|
|
6671
|
+
...opts.headerExtras?.transferSeal !== void 0 ? { transferSeal: opts.headerExtras.transferSeal } : {}
|
|
6672
|
+
};
|
|
6673
|
+
const headerBytes = encodeBundleHeader(header);
|
|
6674
|
+
const prefix = new Uint8Array(NOYDB_BUNDLE_PREFIX_BYTES);
|
|
6675
|
+
prefix.set(NOYDB_BUNDLE_MAGIC, 0);
|
|
6676
|
+
prefix[4] = (streamFormat === null ? 0 : FLAG_COMPRESSED) | FLAG_HAS_INTEGRITY_HASH;
|
|
6677
|
+
prefix[5] = format;
|
|
6678
|
+
writeUint32BE(prefix, 6, headerBytes.length);
|
|
6679
|
+
return concatBytes([prefix, headerBytes, body]);
|
|
6680
|
+
}
|
|
6346
6681
|
async function writeNoydbBundle(vault, opts = {}) {
|
|
6347
6682
|
if (opts.exportPassphrase !== void 0 && opts.recipients !== void 0) {
|
|
6348
6683
|
throw new Error(
|
|
@@ -6357,26 +6692,16 @@ async function writeNoydbBundle(vault, opts = {}) {
|
|
|
6357
6692
|
const plainFiltered = await applyPlaintextFilters(vault, rekeyed, opts);
|
|
6358
6693
|
const filtered = applySliceFilters(plainFiltered, opts);
|
|
6359
6694
|
const bodyJsonStr = normalizedAutoUnlock === null ? filtered : JSON.stringify(await buildAutoUnlockWrapper(filtered, normalizedAutoUnlock));
|
|
6360
|
-
const dumpBytes = new TextEncoder().encode(bodyJsonStr);
|
|
6361
|
-
const { format, streamFormat } = selectCompression(opts.compression);
|
|
6362
|
-
const body = streamFormat === null ? dumpBytes : await pumpThroughStream(dumpBytes, new CompressionStream(streamFormat));
|
|
6363
|
-
const bodySha256 = await sha256Hex2(body);
|
|
6364
6695
|
const publicEnvelope = await vault.getPublicEnvelope();
|
|
6365
|
-
|
|
6366
|
-
formatVersion: NOYDB_BUNDLE_FORMAT_VERSION,
|
|
6696
|
+
return assembleBundleContainer({
|
|
6367
6697
|
handle,
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
prefix.set(NOYDB_BUNDLE_MAGIC, 0);
|
|
6376
|
-
prefix[4] = (streamFormat === null ? 0 : FLAG_COMPRESSED) | FLAG_HAS_INTEGRITY_HASH;
|
|
6377
|
-
prefix[5] = format;
|
|
6378
|
-
writeUint32BE(prefix, 6, headerBytes.length);
|
|
6379
|
-
return concatBytes([prefix, headerBytes, body]);
|
|
6698
|
+
bodyJsonStr,
|
|
6699
|
+
compression: opts.compression,
|
|
6700
|
+
headerExtras: {
|
|
6701
|
+
...publicEnvelope !== void 0 ? { publicEnvelope } : {},
|
|
6702
|
+
...autoUnlockMode !== null ? { autoUnlock: autoUnlockMode } : {}
|
|
6703
|
+
}
|
|
6704
|
+
});
|
|
6380
6705
|
}
|
|
6381
6706
|
function parsePrefixAndHeader(bytes) {
|
|
6382
6707
|
if (!hasNoydbBundleMagic(bytes)) {
|
|
@@ -6737,7 +7062,7 @@ var CollectionInstant = class {
|
|
|
6737
7062
|
for (const e of entries) {
|
|
6738
7063
|
if (e.collection !== this.name || e.id !== id) continue;
|
|
6739
7064
|
if (e.ts > this.targetTs) break;
|
|
6740
|
-
if (e.op === "amendment") continue;
|
|
7065
|
+
if (e.op === "amendment" || e.op === "lifecycle") continue;
|
|
6741
7066
|
latest = { op: e.op, version: e.version };
|
|
6742
7067
|
}
|
|
6743
7068
|
if (!latest) return null;
|
|
@@ -8926,6 +9251,81 @@ var MemorySealingKeyProvider = class {
|
|
|
8926
9251
|
return out;
|
|
8927
9252
|
}
|
|
8928
9253
|
};
|
|
9254
|
+
var MemoryRecipientSealer = class {
|
|
9255
|
+
id;
|
|
9256
|
+
keypair;
|
|
9257
|
+
constructor(opts) {
|
|
9258
|
+
this.id = opts.id;
|
|
9259
|
+
this.keypair = crypto.subtle.generateKey(
|
|
9260
|
+
{ name: "RSA-OAEP", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" },
|
|
9261
|
+
true,
|
|
9262
|
+
["encrypt", "decrypt"]
|
|
9263
|
+
);
|
|
9264
|
+
}
|
|
9265
|
+
async publishRecipientHint() {
|
|
9266
|
+
const { publicKey } = await this.keypair;
|
|
9267
|
+
const spki = await crypto.subtle.exportKey("spki", publicKey);
|
|
9268
|
+
const pem = "-----BEGIN PUBLIC KEY-----\n" + bytesToBase644(new Uint8Array(spki)).match(/.{1,64}/g).join("\n") + "\n-----END PUBLIC KEY-----\n";
|
|
9269
|
+
return { v: 1, pid: this.id, alg: "rsa-oaep-sha256", material: { publicKeyPem: pem } };
|
|
9270
|
+
}
|
|
9271
|
+
async sealForRecipient(plaintext, hint) {
|
|
9272
|
+
if (hint.v !== 1) {
|
|
9273
|
+
throw new Error(`MemoryRecipientSealer.sealForRecipient: unsupported hint.v ${String(hint.v)} (expected 1)`);
|
|
9274
|
+
}
|
|
9275
|
+
if (hint.alg !== "rsa-oaep-sha256") {
|
|
9276
|
+
throw new Error(`MemoryRecipientSealer.sealForRecipient: unsupported hint.alg '${String(hint.alg)}' (expected 'rsa-oaep-sha256')`);
|
|
9277
|
+
}
|
|
9278
|
+
const pem = hint.material["publicKeyPem"];
|
|
9279
|
+
if (typeof pem !== "string") {
|
|
9280
|
+
throw new Error("MemoryRecipientSealer.sealForRecipient: hint.material.publicKeyPem missing or not a string");
|
|
9281
|
+
}
|
|
9282
|
+
const b64 = pem.replace(/-----BEGIN PUBLIC KEY-----/, "").replace(/-----END PUBLIC KEY-----/, "").replace(/\s+/g, "");
|
|
9283
|
+
const spki = base64ToBytes3(b64);
|
|
9284
|
+
const recipientPub = await crypto.subtle.importKey(
|
|
9285
|
+
"spki",
|
|
9286
|
+
spki,
|
|
9287
|
+
{ name: "RSA-OAEP", hash: "SHA-256" },
|
|
9288
|
+
false,
|
|
9289
|
+
["encrypt"]
|
|
9290
|
+
);
|
|
9291
|
+
const cekBytes = crypto.getRandomValues(new Uint8Array(32));
|
|
9292
|
+
const cek = await crypto.subtle.importKey("raw", cekBytes, "AES-GCM", false, ["encrypt"]);
|
|
9293
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
9294
|
+
const ct = new Uint8Array(await crypto.subtle.encrypt({ name: "AES-GCM", iv }, cek, plaintext));
|
|
9295
|
+
const wrapped = new Uint8Array(await crypto.subtle.encrypt({ name: "RSA-OAEP" }, recipientPub, cekBytes));
|
|
9296
|
+
cekBytes.fill(0);
|
|
9297
|
+
if (wrapped.length !== 256) {
|
|
9298
|
+
throw new Error(`MemoryRecipientSealer.sealForRecipient: expected 256-byte RSA-OAEP wrap, got ${wrapped.length}`);
|
|
9299
|
+
}
|
|
9300
|
+
const out = new Uint8Array(1 + 256 + 12 + ct.length);
|
|
9301
|
+
out[0] = 1;
|
|
9302
|
+
out.set(wrapped, 1);
|
|
9303
|
+
out.set(iv, 1 + 256);
|
|
9304
|
+
out.set(ct, 1 + 256 + 12);
|
|
9305
|
+
return out;
|
|
9306
|
+
}
|
|
9307
|
+
async seal(plaintext) {
|
|
9308
|
+
const hint = await this.publishRecipientHint();
|
|
9309
|
+
return this.sealForRecipient(plaintext, hint);
|
|
9310
|
+
}
|
|
9311
|
+
async unseal(bytes) {
|
|
9312
|
+
if (bytes.length < 1 + 256 + 12 + 16) {
|
|
9313
|
+
throw new Error("MemoryRecipientSealer.unseal: sealed input too short");
|
|
9314
|
+
}
|
|
9315
|
+
if (bytes[0] !== 1) {
|
|
9316
|
+
throw new Error(`MemoryRecipientSealer.unseal: unknown TLV version ${bytes[0]}`);
|
|
9317
|
+
}
|
|
9318
|
+
const wrapped = bytes.subarray(1, 1 + 256);
|
|
9319
|
+
const iv = bytes.subarray(1 + 256, 1 + 256 + 12);
|
|
9320
|
+
const ct = bytes.subarray(1 + 256 + 12);
|
|
9321
|
+
const { privateKey } = await this.keypair;
|
|
9322
|
+
const cekBytes = new Uint8Array(await crypto.subtle.decrypt({ name: "RSA-OAEP" }, privateKey, wrapped));
|
|
9323
|
+
const cek = await crypto.subtle.importKey("raw", cekBytes, "AES-GCM", false, ["decrypt"]);
|
|
9324
|
+
const pt = new Uint8Array(await crypto.subtle.decrypt({ name: "AES-GCM", iv }, cek, ct));
|
|
9325
|
+
cekBytes.fill(0);
|
|
9326
|
+
return pt;
|
|
9327
|
+
}
|
|
9328
|
+
};
|
|
8929
9329
|
var SEALED_PASSPHRASE_RECORD_ID = "sealed-passphrase";
|
|
8930
9330
|
function bytesToBase644(bytes) {
|
|
8931
9331
|
let binary = "";
|
|
@@ -15377,6 +15777,12 @@ var Vault = class {
|
|
|
15377
15777
|
* `vault.compact()`. Indexed by collection name.
|
|
15378
15778
|
*/
|
|
15379
15779
|
blobFieldsRegistry = /* @__PURE__ */ new Map();
|
|
15780
|
+
/**
|
|
15781
|
+
* Per-collection attestation field-schema (issue side). Populated on
|
|
15782
|
+
* `collection({ attestation })` and read by `issueAttestation()`.
|
|
15783
|
+
* Indexed by collection name.
|
|
15784
|
+
*/
|
|
15785
|
+
attestationRegistry = /* @__PURE__ */ new Map();
|
|
15380
15786
|
/**
|
|
15381
15787
|
* Per-vault ledger store. Lazy-initialized on first
|
|
15382
15788
|
* `collection()` call (which passes it through to the Collection)
|
|
@@ -15578,6 +15984,9 @@ var Vault = class {
|
|
|
15578
15984
|
if (options?.blobFields) {
|
|
15579
15985
|
this.blobFieldsRegistry.set(collectionName, options.blobFields);
|
|
15580
15986
|
}
|
|
15987
|
+
if (options?.attestation !== void 0) {
|
|
15988
|
+
this.attestationRegistry.set(collectionName, options.attestation);
|
|
15989
|
+
}
|
|
15581
15990
|
if (options?.dictKeyFields) {
|
|
15582
15991
|
const dictFieldMap = {};
|
|
15583
15992
|
for (const [field, desc] of Object.entries(options.dictKeyFields)) {
|
|
@@ -15636,7 +16045,6 @@ var Vault = class {
|
|
|
15636
16045
|
} : {},
|
|
15637
16046
|
...this.materializedViewRegistry !== null ? {
|
|
15638
16047
|
materializedViewSource: {
|
|
15639
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
15640
16048
|
registry: () => this.materializedViewRegistry,
|
|
15641
16049
|
getCollection: (name) => this.collection(name),
|
|
15642
16050
|
getActiveTxContext: () => this.noydb._activeTxContextOrNull,
|
|
@@ -16032,6 +16440,66 @@ var Vault = class {
|
|
|
16032
16440
|
options
|
|
16033
16441
|
);
|
|
16034
16442
|
}
|
|
16443
|
+
async issueAttestation(collectionName, id) {
|
|
16444
|
+
const fieldSchema = this.attestationRegistry.get(collectionName);
|
|
16445
|
+
if (!fieldSchema) {
|
|
16446
|
+
throw new AttestationError(`issueAttestation: collection '${collectionName}' has no attestation field-schema. Declare it via vault.collection('${collectionName}', { attestation: { fields: [...] } }).`);
|
|
16447
|
+
}
|
|
16448
|
+
const { issueAttestationCore: issueAttestationCore2 } = await Promise.resolve().then(() => (init_issue(), issue_exports));
|
|
16449
|
+
const out = await issueAttestationCore2(this.makeIssueContext(), { collection: collectionName, id, fieldSchema });
|
|
16450
|
+
return { docId: out.docId, qr: out.qr, keyId: out.keyId, publicKeyB64: out.publicKeyB64 };
|
|
16451
|
+
}
|
|
16452
|
+
async getDocumentSigningPublicKey() {
|
|
16453
|
+
const { loadSigner: loadSigner2, loadOrCreateSigner: loadOrCreateSigner2 } = await Promise.resolve().then(() => (init_signer(), signer_exports));
|
|
16454
|
+
const existing = await loadSigner2(this.adapter, this.name, this.getDEK);
|
|
16455
|
+
if (existing) return { keyId: existing.keyId, publicKeyB64: existing.publicKeyB64 };
|
|
16456
|
+
if (this.keyring.role !== "owner") {
|
|
16457
|
+
throw new AttestationError(`getDocumentSigningPublicKey: no document-signing key exists yet; only the 'owner' may mint it. Caller is '${this.keyring.role}'. Have the owner issue an attestation (or call this) first.`);
|
|
16458
|
+
}
|
|
16459
|
+
const signer = await loadOrCreateSigner2(this.adapter, this.name, this.getDEK);
|
|
16460
|
+
return { keyId: signer.keyId, publicKeyB64: signer.publicKeyB64 };
|
|
16461
|
+
}
|
|
16462
|
+
makeIssueContext() {
|
|
16463
|
+
const adapter = this.adapter, vaultName = this.name, getDEK = this.getDEK;
|
|
16464
|
+
return {
|
|
16465
|
+
store: adapter,
|
|
16466
|
+
vault: vaultName,
|
|
16467
|
+
role: this.keyring.role,
|
|
16468
|
+
getDEK: async () => getDEK("_attestations"),
|
|
16469
|
+
readRecord: async (collection, recId) => {
|
|
16470
|
+
const env = await adapter.get(vaultName, collection, recId);
|
|
16471
|
+
if (!env) return null;
|
|
16472
|
+
const record = await this.collection(collection).get(recId, { locale: "raw" });
|
|
16473
|
+
if (record === null) return null;
|
|
16474
|
+
return { record, version: env._v };
|
|
16475
|
+
}
|
|
16476
|
+
};
|
|
16477
|
+
}
|
|
16478
|
+
async revokeAttestation(docId) {
|
|
16479
|
+
const { revokeDocCore: revokeDocCore2 } = await Promise.resolve().then(() => (init_revoke(), revoke_exports));
|
|
16480
|
+
await revokeDocCore2(this.makeRevokeContext(), docId);
|
|
16481
|
+
}
|
|
16482
|
+
async unrevokeAttestation(docId) {
|
|
16483
|
+
const { unrevokeDocCore: unrevokeDocCore2 } = await Promise.resolve().then(() => (init_revoke(), revoke_exports));
|
|
16484
|
+
await unrevokeDocCore2(this.makeRevokeContext(), docId);
|
|
16485
|
+
}
|
|
16486
|
+
async getRevokedDocIds() {
|
|
16487
|
+
const { getRevokedDocIdsCore: getRevokedDocIdsCore2 } = await Promise.resolve().then(() => (init_revoke(), revoke_exports));
|
|
16488
|
+
return getRevokedDocIdsCore2(this.makeRevokeContext());
|
|
16489
|
+
}
|
|
16490
|
+
async publishRevocationList() {
|
|
16491
|
+
const { publishRevocationListCore: publishRevocationListCore2 } = await Promise.resolve().then(() => (init_revoke(), revoke_exports));
|
|
16492
|
+
return publishRevocationListCore2(this.makeRevokeContext());
|
|
16493
|
+
}
|
|
16494
|
+
makeRevokeContext() {
|
|
16495
|
+
const adapter = this.adapter, vaultName = this.name, getDEK = this.getDEK;
|
|
16496
|
+
return {
|
|
16497
|
+
store: adapter,
|
|
16498
|
+
vault: vaultName,
|
|
16499
|
+
role: this.keyring.role,
|
|
16500
|
+
getDEK: async () => getDEK("_attestations")
|
|
16501
|
+
};
|
|
16502
|
+
}
|
|
16035
16503
|
async writeExportAudit(entry) {
|
|
16036
16504
|
const json = JSON.stringify(entry);
|
|
16037
16505
|
const envelope = this.encrypted ? await (async () => {
|
|
@@ -17355,7 +17823,7 @@ var Vault = class {
|
|
|
17355
17823
|
for (let i = allEntries.length - 1; i >= 0; i--) {
|
|
17356
17824
|
const entry = allEntries[i];
|
|
17357
17825
|
if (!entry) continue;
|
|
17358
|
-
if (entry.op === "amendment") continue;
|
|
17826
|
+
if (entry.op === "amendment" || entry.op === "lifecycle") continue;
|
|
17359
17827
|
const key = `${entry.collection}/${entry.id}`;
|
|
17360
17828
|
if (seen.has(key)) continue;
|
|
17361
17829
|
seen.add(key);
|
|
@@ -21557,6 +22025,7 @@ function shortJSON(value) {
|
|
|
21557
22025
|
Aggregation,
|
|
21558
22026
|
AlreadyElevatedError,
|
|
21559
22027
|
AmendmentForbiddenError,
|
|
22028
|
+
AttestationError,
|
|
21560
22029
|
BLOB_CHUNKS_COLLECTION,
|
|
21561
22030
|
BLOB_COLLECTION,
|
|
21562
22031
|
BLOB_INDEX_COLLECTION,
|
|
@@ -21630,6 +22099,7 @@ function shortJSON(value) {
|
|
|
21630
22099
|
MaterializedViewCycleError,
|
|
21631
22100
|
MaterializedViewSourceUnknownError,
|
|
21632
22101
|
MaterializedViewTooLargeError,
|
|
22102
|
+
MemoryRecipientSealer,
|
|
21633
22103
|
MemorySealingKeyProvider,
|
|
21634
22104
|
MissingTranslationError,
|
|
21635
22105
|
NOYDB_BACKUP_VERSION,
|