@baruk/core 0.3.1 → 0.4.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/.baruk-provenance.json +10 -0
- package/CHANGELOG.md +85 -0
- package/dist/auth/password-reset.d.ts +30 -1
- package/dist/auth/password-reset.d.ts.map +1 -1
- package/dist/auth/password-reset.js +139 -11
- package/dist/auth/password-reset.js.map +1 -1
- package/dist/auth/service.d.ts +39 -2
- package/dist/auth/service.d.ts.map +1 -1
- package/dist/auth/service.js +75 -10
- package/dist/auth/service.js.map +1 -1
- package/dist/billing/ar-repository.d.ts +334 -0
- package/dist/billing/ar-repository.d.ts.map +1 -0
- package/dist/billing/ar-repository.js +707 -0
- package/dist/billing/ar-repository.js.map +1 -0
- package/dist/billing/auto-generation.d.ts +87 -0
- package/dist/billing/auto-generation.d.ts.map +1 -0
- package/dist/billing/auto-generation.js +181 -0
- package/dist/billing/auto-generation.js.map +1 -0
- package/dist/billing/live-guard.d.ts +64 -0
- package/dist/billing/live-guard.d.ts.map +1 -0
- package/dist/billing/live-guard.js +68 -0
- package/dist/billing/live-guard.js.map +1 -0
- package/dist/billing/payment-means-catalog.d.ts +17 -0
- package/dist/billing/payment-means-catalog.d.ts.map +1 -0
- package/dist/billing/payment-means-catalog.js +21 -0
- package/dist/billing/payment-means-catalog.js.map +1 -0
- package/dist/billing/payment-means.d.ts +38 -0
- package/dist/billing/payment-means.d.ts.map +1 -0
- package/dist/billing/payment-means.js +29 -0
- package/dist/billing/payment-means.js.map +1 -0
- package/dist/billing/payment-rail.d.ts +118 -0
- package/dist/billing/payment-rail.d.ts.map +1 -0
- package/dist/billing/payment-rail.js +295 -0
- package/dist/billing/payment-rail.js.map +1 -0
- package/dist/billing/provider/asaas.d.ts +46 -1
- package/dist/billing/provider/asaas.d.ts.map +1 -1
- package/dist/billing/provider/asaas.js +194 -14
- package/dist/billing/provider/asaas.js.map +1 -1
- package/dist/billing/provider/manual.js +1 -1
- package/dist/billing/provider/manual.js.map +1 -1
- package/dist/billing/provider/types.d.ts +115 -8
- package/dist/billing/provider/types.d.ts.map +1 -1
- package/dist/billing/provider-account.d.ts +89 -0
- package/dist/billing/provider-account.d.ts.map +1 -0
- package/dist/billing/provider-account.js +161 -0
- package/dist/billing/provider-account.js.map +1 -0
- package/dist/billing/provider-onboarding.d.ts +67 -0
- package/dist/billing/provider-onboarding.d.ts.map +1 -0
- package/dist/billing/provider-onboarding.js +234 -0
- package/dist/billing/provider-onboarding.js.map +1 -0
- package/dist/billing/receivable.d.ts +5 -1
- package/dist/billing/receivable.d.ts.map +1 -1
- package/dist/billing/reconcile.d.ts +58 -0
- package/dist/billing/reconcile.d.ts.map +1 -0
- package/dist/billing/reconcile.js +138 -0
- package/dist/billing/reconcile.js.map +1 -0
- package/dist/billing/repository.d.ts +90 -1
- package/dist/billing/repository.d.ts.map +1 -1
- package/dist/billing/repository.js +148 -19
- package/dist/billing/repository.js.map +1 -1
- package/dist/cjs/auth/password-reset.js +141 -11
- package/dist/cjs/auth/password-reset.js.map +1 -1
- package/dist/cjs/auth/service.js +75 -9
- package/dist/cjs/auth/service.js.map +1 -1
- package/dist/cjs/billing/ar-repository.js +728 -0
- package/dist/cjs/billing/ar-repository.js.map +1 -0
- package/dist/cjs/billing/auto-generation.js +186 -0
- package/dist/cjs/billing/auto-generation.js.map +1 -0
- package/dist/cjs/billing/live-guard.js +72 -0
- package/dist/cjs/billing/live-guard.js.map +1 -0
- package/dist/cjs/billing/payment-means-catalog.js +25 -0
- package/dist/cjs/billing/payment-means-catalog.js.map +1 -0
- package/dist/cjs/billing/payment-means.js +33 -0
- package/dist/cjs/billing/payment-means.js.map +1 -0
- package/dist/cjs/billing/payment-rail.js +301 -0
- package/dist/cjs/billing/payment-rail.js.map +1 -0
- package/dist/cjs/billing/provider/asaas.js +194 -14
- package/dist/cjs/billing/provider/asaas.js.map +1 -1
- package/dist/cjs/billing/provider/manual.js +1 -1
- package/dist/cjs/billing/provider/manual.js.map +1 -1
- package/dist/cjs/billing/provider-account.js +170 -0
- package/dist/cjs/billing/provider-account.js.map +1 -0
- package/dist/cjs/billing/provider-onboarding.js +239 -0
- package/dist/cjs/billing/provider-onboarding.js.map +1 -0
- package/dist/cjs/billing/reconcile.js +143 -0
- package/dist/cjs/billing/reconcile.js.map +1 -0
- package/dist/cjs/billing/repository.js +150 -18
- package/dist/cjs/billing/repository.js.map +1 -1
- package/dist/cjs/clients/repository.js +96 -20
- package/dist/cjs/clients/repository.js.map +1 -1
- package/dist/cjs/collection/branding.js +140 -0
- package/dist/cjs/collection/branding.js.map +1 -0
- package/dist/cjs/collection/channel-accounts.js +137 -0
- package/dist/cjs/collection/channel-accounts.js.map +1 -0
- package/dist/cjs/collection/channel.js +17 -0
- package/dist/cjs/collection/channel.js.map +1 -0
- package/dist/cjs/collection/communication-bridge.js +140 -0
- package/dist/cjs/collection/communication-bridge.js.map +1 -0
- package/dist/cjs/collection/communication-runtime.js +193 -0
- package/dist/cjs/collection/communication-runtime.js.map +1 -0
- package/dist/cjs/collection/consent-repository.js +84 -0
- package/dist/cjs/collection/consent-repository.js.map +1 -0
- package/dist/cjs/collection/copy.js +125 -0
- package/dist/cjs/collection/copy.js.map +1 -0
- package/dist/cjs/collection/delivery-callback.js +151 -0
- package/dist/cjs/collection/delivery-callback.js.map +1 -0
- package/dist/cjs/collection/email-layout.js +252 -0
- package/dist/cjs/collection/email-layout.js.map +1 -0
- package/dist/cjs/collection/engine.js +414 -0
- package/dist/cjs/collection/engine.js.map +1 -0
- package/dist/cjs/collection/format.js +76 -0
- package/dist/cjs/collection/format.js.map +1 -0
- package/dist/cjs/collection/payment-block.js +3 -0
- package/dist/cjs/collection/payment-block.js.map +1 -0
- package/dist/cjs/collection/policy.js +147 -0
- package/dist/cjs/collection/policy.js.map +1 -0
- package/dist/cjs/collection/repository.js +260 -0
- package/dist/cjs/collection/repository.js.map +1 -0
- package/dist/cjs/collection/subject.js +104 -0
- package/dist/cjs/collection/subject.js.map +1 -0
- package/dist/cjs/collection/template-catalog.js +165 -0
- package/dist/cjs/collection/template-catalog.js.map +1 -0
- package/dist/cjs/collection/template.js +78 -0
- package/dist/cjs/collection/template.js.map +1 -0
- package/dist/cjs/communication/adapters/email.js +132 -0
- package/dist/cjs/communication/adapters/email.js.map +1 -0
- package/dist/cjs/communication/adapters/sms.js +127 -0
- package/dist/cjs/communication/adapters/sms.js.map +1 -0
- package/dist/cjs/communication/adapters/whatsapp-language.js +39 -0
- package/dist/cjs/communication/adapters/whatsapp-language.js.map +1 -0
- package/dist/cjs/communication/adapters/whatsapp-templates.js +100 -0
- package/dist/cjs/communication/adapters/whatsapp-templates.js.map +1 -0
- package/dist/cjs/communication/adapters/whatsapp.js +213 -0
- package/dist/cjs/communication/adapters/whatsapp.js.map +1 -0
- package/dist/cjs/communication/audit.js +61 -0
- package/dist/cjs/communication/audit.js.map +1 -0
- package/dist/cjs/communication/capabilities.js +76 -0
- package/dist/cjs/communication/capabilities.js.map +1 -0
- package/dist/cjs/communication/channel.js +53 -0
- package/dist/cjs/communication/channel.js.map +1 -0
- package/dist/cjs/communication/claim.js +228 -0
- package/dist/cjs/communication/claim.js.map +1 -0
- package/dist/cjs/communication/consent.js +43 -0
- package/dist/cjs/communication/consent.js.map +1 -0
- package/dist/cjs/communication/context.js +45 -0
- package/dist/cjs/communication/context.js.map +1 -0
- package/dist/cjs/communication/credentials.js +121 -0
- package/dist/cjs/communication/credentials.js.map +1 -0
- package/dist/cjs/communication/dry-run-scenario.js +161 -0
- package/dist/cjs/communication/dry-run-scenario.js.map +1 -0
- package/dist/cjs/communication/dry-run.js +97 -0
- package/dist/cjs/communication/dry-run.js.map +1 -0
- package/dist/cjs/communication/engine.js +483 -0
- package/dist/cjs/communication/engine.js.map +1 -0
- package/dist/cjs/communication/graph.js +50 -0
- package/dist/cjs/communication/graph.js.map +1 -0
- package/dist/cjs/communication/idempotency.js +26 -0
- package/dist/cjs/communication/idempotency.js.map +1 -0
- package/dist/cjs/communication/identity.js +110 -0
- package/dist/cjs/communication/identity.js.map +1 -0
- package/dist/cjs/communication/index.js +135 -0
- package/dist/cjs/communication/index.js.map +1 -0
- package/dist/cjs/communication/onboarding.js +297 -0
- package/dist/cjs/communication/onboarding.js.map +1 -0
- package/dist/cjs/communication/policy.js +16 -0
- package/dist/cjs/communication/policy.js.map +1 -0
- package/dist/cjs/communication/routing.js +77 -0
- package/dist/cjs/communication/routing.js.map +1 -0
- package/dist/cjs/communication/sender-profile.js +128 -0
- package/dist/cjs/communication/sender-profile.js.map +1 -0
- package/dist/cjs/communication/status.js +86 -0
- package/dist/cjs/communication/status.js.map +1 -0
- package/dist/cjs/communication/stores/onboarding.js +135 -0
- package/dist/cjs/communication/stores/onboarding.js.map +1 -0
- package/dist/cjs/communication/stores/postgres.js +458 -0
- package/dist/cjs/communication/stores/postgres.js.map +1 -0
- package/dist/cjs/communication/stores/routing.js +334 -0
- package/dist/cjs/communication/stores/routing.js.map +1 -0
- package/dist/cjs/communication/stores/secrets.js +126 -0
- package/dist/cjs/communication/stores/secrets.js.map +1 -0
- package/dist/cjs/communication/template-provider.js +22 -0
- package/dist/cjs/communication/template-provider.js.map +1 -0
- package/dist/cjs/communication/template.js +63 -0
- package/dist/cjs/communication/template.js.map +1 -0
- package/dist/cjs/communication/webhook-subscription.js +258 -0
- package/dist/cjs/communication/webhook-subscription.js.map +1 -0
- package/dist/cjs/communication/webhook.js +292 -0
- package/dist/cjs/communication/webhook.js.map +1 -0
- package/dist/cjs/competence/repository.js +309 -0
- package/dist/cjs/competence/repository.js.map +1 -0
- package/dist/cjs/contacts/phone.js +192 -0
- package/dist/cjs/contacts/phone.js.map +1 -0
- package/dist/cjs/db/seed-catalog.js +48 -0
- package/dist/cjs/db/seed-catalog.js.map +1 -0
- package/dist/cjs/db/seed.js +15 -7
- package/dist/cjs/db/seed.js.map +1 -1
- package/dist/cjs/documents/repository.js +244 -0
- package/dist/cjs/documents/repository.js.map +1 -0
- package/dist/cjs/documents/requests.js +136 -0
- package/dist/cjs/documents/requests.js.map +1 -0
- package/dist/cjs/index.js +406 -39
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/legal/documents.js +125 -3
- package/dist/cjs/legal/documents.js.map +1 -1
- package/dist/cjs/legal/types.js +1 -0
- package/dist/cjs/legal/types.js.map +1 -1
- package/dist/cjs/mail/auth-templates.js +29 -0
- package/dist/cjs/mail/auth-templates.js.map +1 -0
- package/dist/cjs/mail/dedup-store.js +12 -51
- package/dist/cjs/mail/dedup-store.js.map +1 -1
- package/dist/cjs/mail/index.js +16 -4
- package/dist/cjs/mail/index.js.map +1 -1
- package/dist/cjs/mail/provider.js +12 -247
- package/dist/cjs/mail/provider.js.map +1 -1
- package/dist/cjs/mail/resend.js +14 -18
- package/dist/cjs/mail/resend.js.map +1 -1
- package/dist/cjs/mail/sender-resolver.js +12 -11
- package/dist/cjs/mail/sender-resolver.js.map +1 -1
- package/dist/cjs/mail/template-renderer.js +11 -16
- package/dist/cjs/mail/template-renderer.js.map +1 -1
- package/dist/cjs/mail/transactional-outbound.js +117 -0
- package/dist/cjs/mail/transactional-outbound.js.map +1 -0
- package/dist/cjs/mail/types.js +8 -35
- package/dist/cjs/mail/types.js.map +1 -1
- package/dist/cjs/portal/provisioning.js +144 -0
- package/dist/cjs/portal/provisioning.js.map +1 -0
- package/dist/cjs/pricing-engine/canonical.js +42 -0
- package/dist/cjs/pricing-engine/canonical.js.map +1 -0
- package/dist/cjs/pricing-engine/errors.js +6 -1
- package/dist/cjs/pricing-engine/errors.js.map +1 -1
- package/dist/cjs/pricing-engine/index.js +12 -1
- package/dist/cjs/pricing-engine/index.js.map +1 -1
- package/dist/cjs/pricing-engine/pipeline.js +200 -26
- package/dist/cjs/pricing-engine/pipeline.js.map +1 -1
- package/dist/cjs/pricing-engine/shadow-adapter.js +79 -0
- package/dist/cjs/pricing-engine/shadow-adapter.js.map +1 -0
- package/dist/cjs/pricing-engine/shadow-diff.js +55 -0
- package/dist/cjs/pricing-engine/shadow-diff.js.map +1 -0
- package/dist/cjs/pricing-engine/shadow-facade.js +85 -0
- package/dist/cjs/pricing-engine/shadow-facade.js.map +1 -0
- package/dist/cjs/pricing-engine/shadow-legacy-types.js +19 -0
- package/dist/cjs/pricing-engine/shadow-legacy-types.js.map +1 -0
- package/dist/cjs/pricing-engine/shadow-metrics.js +34 -0
- package/dist/cjs/pricing-engine/shadow-metrics.js.map +1 -0
- package/dist/cjs/pricing-engine/shadow-normalizer.js +42 -0
- package/dist/cjs/pricing-engine/shadow-normalizer.js.map +1 -0
- package/dist/cjs/rbac/authorize.js +28 -0
- package/dist/cjs/rbac/authorize.js.map +1 -1
- package/dist/cjs/rbac/catalog.js +67 -1
- package/dist/cjs/rbac/catalog.js.map +1 -1
- package/dist/cjs/rbac/workload-provisioning.js +160 -0
- package/dist/cjs/rbac/workload-provisioning.js.map +1 -0
- package/dist/cjs/rbac/workload.js +191 -0
- package/dist/cjs/rbac/workload.js.map +1 -0
- package/dist/cjs/storage/checksum.js +15 -0
- package/dist/cjs/storage/checksum.js.map +1 -0
- package/dist/cjs/storage/key.js +72 -0
- package/dist/cjs/storage/key.js.map +1 -0
- package/dist/cjs/storage/local.js +100 -0
- package/dist/cjs/storage/local.js.map +1 -0
- package/dist/cjs/storage/r2.js +181 -0
- package/dist/cjs/storage/r2.js.map +1 -0
- package/dist/cjs/storage/registry.js +41 -0
- package/dist/cjs/storage/registry.js.map +1 -0
- package/dist/cjs/storage/types.js +50 -0
- package/dist/cjs/storage/types.js.map +1 -0
- package/dist/cjs/subscription-billing/provider/asaas.js +32 -7
- package/dist/cjs/subscription-billing/provider/asaas.js.map +1 -1
- package/dist/cjs/subscription-billing/provider/disabled.js +8 -0
- package/dist/cjs/subscription-billing/provider/disabled.js.map +1 -1
- package/dist/cjs/subscription-billing/provider/registry.js +17 -0
- package/dist/cjs/subscription-billing/provider/registry.js.map +1 -1
- package/dist/cjs/subscription-billing/service.js +57 -8
- package/dist/cjs/subscription-billing/service.js.map +1 -1
- package/dist/cjs/subscription-billing/types.js.map +1 -1
- package/dist/cjs/tenancy/provisioning.js +32 -8
- package/dist/cjs/tenancy/provisioning.js.map +1 -1
- package/dist/cjs/users/repository.js +119 -2
- package/dist/cjs/users/repository.js.map +1 -1
- package/dist/cjs/vault/repository.js +81 -0
- package/dist/cjs/vault/repository.js.map +1 -1
- package/dist/clients/repository.d.ts +42 -0
- package/dist/clients/repository.d.ts.map +1 -1
- package/dist/clients/repository.js +94 -21
- package/dist/clients/repository.js.map +1 -1
- package/dist/collection/branding.d.ts +72 -0
- package/dist/collection/branding.d.ts.map +1 -0
- package/dist/collection/branding.js +136 -0
- package/dist/collection/branding.js.map +1 -0
- package/dist/collection/channel-accounts.d.ts +57 -0
- package/dist/collection/channel-accounts.d.ts.map +1 -0
- package/dist/collection/channel-accounts.js +133 -0
- package/dist/collection/channel-accounts.js.map +1 -0
- package/dist/collection/channel.d.ts +24 -0
- package/dist/collection/channel.d.ts.map +1 -0
- package/dist/collection/channel.js +16 -0
- package/dist/collection/channel.js.map +1 -0
- package/dist/collection/communication-bridge.d.ts +66 -0
- package/dist/collection/communication-bridge.d.ts.map +1 -0
- package/dist/collection/communication-bridge.js +134 -0
- package/dist/collection/communication-bridge.js.map +1 -0
- package/dist/collection/communication-runtime.d.ts +95 -0
- package/dist/collection/communication-runtime.d.ts.map +1 -0
- package/dist/collection/communication-runtime.js +187 -0
- package/dist/collection/communication-runtime.js.map +1 -0
- package/dist/collection/consent-repository.d.ts +32 -0
- package/dist/collection/consent-repository.d.ts.map +1 -0
- package/dist/collection/consent-repository.js +79 -0
- package/dist/collection/consent-repository.js.map +1 -0
- package/dist/collection/copy.d.ts +50 -0
- package/dist/collection/copy.d.ts.map +1 -0
- package/dist/collection/copy.js +122 -0
- package/dist/collection/copy.js.map +1 -0
- package/dist/collection/delivery-callback.d.ts +49 -0
- package/dist/collection/delivery-callback.d.ts.map +1 -0
- package/dist/collection/delivery-callback.js +147 -0
- package/dist/collection/delivery-callback.js.map +1 -0
- package/dist/collection/email-layout.d.ts +45 -0
- package/dist/collection/email-layout.d.ts.map +1 -0
- package/dist/collection/email-layout.js +247 -0
- package/dist/collection/email-layout.js.map +1 -0
- package/dist/collection/engine.d.ts +177 -0
- package/dist/collection/engine.d.ts.map +1 -0
- package/dist/collection/engine.js +407 -0
- package/dist/collection/engine.js.map +1 -0
- package/dist/collection/format.d.ts +32 -0
- package/dist/collection/format.d.ts.map +1 -0
- package/dist/collection/format.js +70 -0
- package/dist/collection/format.js.map +1 -0
- package/dist/collection/payment-block.d.ts +24 -0
- package/dist/collection/payment-block.d.ts.map +1 -0
- package/dist/collection/payment-block.js +2 -0
- package/dist/collection/payment-block.js.map +1 -0
- package/dist/collection/policy.d.ts +53 -0
- package/dist/collection/policy.d.ts.map +1 -0
- package/dist/collection/policy.js +141 -0
- package/dist/collection/policy.js.map +1 -0
- package/dist/collection/repository.d.ts +129 -0
- package/dist/collection/repository.d.ts.map +1 -0
- package/dist/collection/repository.js +246 -0
- package/dist/collection/repository.js.map +1 -0
- package/dist/collection/subject.d.ts +66 -0
- package/dist/collection/subject.d.ts.map +1 -0
- package/dist/collection/subject.js +99 -0
- package/dist/collection/subject.js.map +1 -0
- package/dist/collection/template-catalog.d.ts +16 -0
- package/dist/collection/template-catalog.d.ts.map +1 -0
- package/dist/collection/template-catalog.js +162 -0
- package/dist/collection/template-catalog.js.map +1 -0
- package/dist/collection/template.d.ts +37 -0
- package/dist/collection/template.d.ts.map +1 -0
- package/dist/collection/template.js +73 -0
- package/dist/collection/template.js.map +1 -0
- package/dist/communication/adapters/email.d.ts +28 -0
- package/dist/communication/adapters/email.d.ts.map +1 -0
- package/dist/communication/adapters/email.js +129 -0
- package/dist/communication/adapters/email.js.map +1 -0
- package/dist/communication/adapters/sms.d.ts +95 -0
- package/dist/communication/adapters/sms.d.ts.map +1 -0
- package/dist/communication/adapters/sms.js +121 -0
- package/dist/communication/adapters/sms.js.map +1 -0
- package/dist/communication/adapters/whatsapp-language.d.ts +34 -0
- package/dist/communication/adapters/whatsapp-language.d.ts.map +1 -0
- package/dist/communication/adapters/whatsapp-language.js +36 -0
- package/dist/communication/adapters/whatsapp-language.js.map +1 -0
- package/dist/communication/adapters/whatsapp-templates.d.ts +18 -0
- package/dist/communication/adapters/whatsapp-templates.d.ts.map +1 -0
- package/dist/communication/adapters/whatsapp-templates.js +97 -0
- package/dist/communication/adapters/whatsapp-templates.js.map +1 -0
- package/dist/communication/adapters/whatsapp.d.ts +29 -0
- package/dist/communication/adapters/whatsapp.d.ts.map +1 -0
- package/dist/communication/adapters/whatsapp.js +210 -0
- package/dist/communication/adapters/whatsapp.js.map +1 -0
- package/dist/communication/audit.d.ts +105 -0
- package/dist/communication/audit.d.ts.map +1 -0
- package/dist/communication/audit.js +56 -0
- package/dist/communication/audit.js.map +1 -0
- package/dist/communication/capabilities.d.ts +88 -0
- package/dist/communication/capabilities.d.ts.map +1 -0
- package/dist/communication/capabilities.js +72 -0
- package/dist/communication/capabilities.js.map +1 -0
- package/dist/communication/channel.d.ts +125 -0
- package/dist/communication/channel.d.ts.map +1 -0
- package/dist/communication/channel.js +47 -0
- package/dist/communication/channel.js.map +1 -0
- package/dist/communication/claim.d.ts +368 -0
- package/dist/communication/claim.d.ts.map +1 -0
- package/dist/communication/claim.js +224 -0
- package/dist/communication/claim.js.map +1 -0
- package/dist/communication/consent.d.ts +65 -0
- package/dist/communication/consent.d.ts.map +1 -0
- package/dist/communication/consent.js +40 -0
- package/dist/communication/consent.js.map +1 -0
- package/dist/communication/context.d.ts +48 -0
- package/dist/communication/context.d.ts.map +1 -0
- package/dist/communication/context.js +41 -0
- package/dist/communication/context.js.map +1 -0
- package/dist/communication/credentials.d.ts +74 -0
- package/dist/communication/credentials.d.ts.map +1 -0
- package/dist/communication/credentials.js +115 -0
- package/dist/communication/credentials.js.map +1 -0
- package/dist/communication/dry-run-scenario.d.ts +37 -0
- package/dist/communication/dry-run-scenario.d.ts.map +1 -0
- package/dist/communication/dry-run-scenario.js +158 -0
- package/dist/communication/dry-run-scenario.js.map +1 -0
- package/dist/communication/dry-run.d.ts +40 -0
- package/dist/communication/dry-run.d.ts.map +1 -0
- package/dist/communication/dry-run.js +92 -0
- package/dist/communication/dry-run.js.map +1 -0
- package/dist/communication/engine.d.ts +153 -0
- package/dist/communication/engine.d.ts.map +1 -0
- package/dist/communication/engine.js +480 -0
- package/dist/communication/engine.js.map +1 -0
- package/dist/communication/graph.d.ts +38 -0
- package/dist/communication/graph.d.ts.map +1 -0
- package/dist/communication/graph.js +45 -0
- package/dist/communication/graph.js.map +1 -0
- package/dist/communication/idempotency.d.ts +33 -0
- package/dist/communication/idempotency.d.ts.map +1 -0
- package/dist/communication/idempotency.js +23 -0
- package/dist/communication/idempotency.js.map +1 -0
- package/dist/communication/identity.d.ts +127 -0
- package/dist/communication/identity.d.ts.map +1 -0
- package/dist/communication/identity.js +105 -0
- package/dist/communication/identity.js.map +1 -0
- package/dist/communication/index.d.ts +66 -0
- package/dist/communication/index.d.ts.map +1 -0
- package/dist/communication/index.js +42 -0
- package/dist/communication/index.js.map +1 -0
- package/dist/communication/onboarding.d.ts +223 -0
- package/dist/communication/onboarding.d.ts.map +1 -0
- package/dist/communication/onboarding.js +287 -0
- package/dist/communication/onboarding.js.map +1 -0
- package/dist/communication/policy.d.ts +99 -0
- package/dist/communication/policy.d.ts.map +1 -0
- package/dist/communication/policy.js +13 -0
- package/dist/communication/policy.js.map +1 -0
- package/dist/communication/routing.d.ts +99 -0
- package/dist/communication/routing.d.ts.map +1 -0
- package/dist/communication/routing.js +73 -0
- package/dist/communication/routing.js.map +1 -0
- package/dist/communication/sender-profile.d.ts +100 -0
- package/dist/communication/sender-profile.d.ts.map +1 -0
- package/dist/communication/sender-profile.js +123 -0
- package/dist/communication/sender-profile.js.map +1 -0
- package/dist/communication/status.d.ts +48 -0
- package/dist/communication/status.d.ts.map +1 -0
- package/dist/communication/status.js +79 -0
- package/dist/communication/status.js.map +1 -0
- package/dist/communication/stores/onboarding.d.ts +88 -0
- package/dist/communication/stores/onboarding.d.ts.map +1 -0
- package/dist/communication/stores/onboarding.js +127 -0
- package/dist/communication/stores/onboarding.js.map +1 -0
- package/dist/communication/stores/postgres.d.ts +81 -0
- package/dist/communication/stores/postgres.d.ts.map +1 -0
- package/dist/communication/stores/postgres.js +453 -0
- package/dist/communication/stores/postgres.js.map +1 -0
- package/dist/communication/stores/routing.d.ts +169 -0
- package/dist/communication/stores/routing.d.ts.map +1 -0
- package/dist/communication/stores/routing.js +324 -0
- package/dist/communication/stores/routing.js.map +1 -0
- package/dist/communication/stores/secrets.d.ts +89 -0
- package/dist/communication/stores/secrets.d.ts.map +1 -0
- package/dist/communication/stores/secrets.js +122 -0
- package/dist/communication/stores/secrets.js.map +1 -0
- package/dist/communication/template-provider.d.ts +85 -0
- package/dist/communication/template-provider.d.ts.map +1 -0
- package/dist/communication/template-provider.js +21 -0
- package/dist/communication/template-provider.js.map +1 -0
- package/dist/communication/template.d.ts +87 -0
- package/dist/communication/template.d.ts.map +1 -0
- package/dist/communication/template.js +59 -0
- package/dist/communication/template.js.map +1 -0
- package/dist/communication/webhook-subscription.d.ts +156 -0
- package/dist/communication/webhook-subscription.d.ts.map +1 -0
- package/dist/communication/webhook-subscription.js +252 -0
- package/dist/communication/webhook-subscription.js.map +1 -0
- package/dist/communication/webhook.d.ts +121 -0
- package/dist/communication/webhook.d.ts.map +1 -0
- package/dist/communication/webhook.js +283 -0
- package/dist/communication/webhook.js.map +1 -0
- package/dist/competence/repository.d.ts +147 -0
- package/dist/competence/repository.d.ts.map +1 -0
- package/dist/competence/repository.js +294 -0
- package/dist/competence/repository.js.map +1 -0
- package/dist/contacts/phone.d.ts +70 -0
- package/dist/contacts/phone.d.ts.map +1 -0
- package/dist/contacts/phone.js +186 -0
- package/dist/contacts/phone.js.map +1 -0
- package/dist/db/migrate.js +17 -11
- package/dist/db/migrate.js.map +1 -1
- package/dist/db/seed-catalog.d.ts +18 -0
- package/dist/db/seed-catalog.d.ts.map +1 -0
- package/dist/db/seed-catalog.js +45 -0
- package/dist/db/seed-catalog.js.map +1 -0
- package/dist/db/seed.js +16 -8
- package/dist/db/seed.js.map +1 -1
- package/dist/documents/repository.d.ts +97 -0
- package/dist/documents/repository.d.ts.map +1 -0
- package/dist/documents/repository.js +236 -0
- package/dist/documents/repository.js.map +1 -0
- package/dist/documents/requests.d.ts +73 -0
- package/dist/documents/requests.d.ts.map +1 -0
- package/dist/documents/requests.js +127 -0
- package/dist/documents/requests.js.map +1 -0
- package/dist/index.d.ts +109 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +100 -8
- package/dist/index.js.map +1 -1
- package/dist/legal/documents.d.ts.map +1 -1
- package/dist/legal/documents.js +125 -3
- package/dist/legal/documents.js.map +1 -1
- package/dist/legal/index.d.ts +1 -1
- package/dist/legal/index.d.ts.map +1 -1
- package/dist/legal/types.d.ts +32 -1
- package/dist/legal/types.d.ts.map +1 -1
- package/dist/legal/types.js +1 -0
- package/dist/legal/types.js.map +1 -1
- package/dist/mail/auth-templates.d.ts +15 -0
- package/dist/mail/auth-templates.d.ts.map +1 -0
- package/dist/mail/auth-templates.js +26 -0
- package/dist/mail/auth-templates.js.map +1 -0
- package/dist/mail/dedup-store.d.ts +1 -24
- package/dist/mail/dedup-store.d.ts.map +1 -1
- package/dist/mail/dedup-store.js +9 -48
- package/dist/mail/dedup-store.js.map +1 -1
- package/dist/mail/index.d.ts +2 -1
- package/dist/mail/index.d.ts.map +1 -1
- package/dist/mail/index.js +13 -2
- package/dist/mail/index.js.map +1 -1
- package/dist/mail/provider.d.ts +2 -30
- package/dist/mail/provider.d.ts.map +1 -1
- package/dist/mail/provider.js +10 -246
- package/dist/mail/provider.js.map +1 -1
- package/dist/mail/resend.d.ts +2 -12
- package/dist/mail/resend.d.ts.map +1 -1
- package/dist/mail/resend.js +11 -17
- package/dist/mail/resend.js.map +1 -1
- package/dist/mail/sender-resolver.d.ts +1 -7
- package/dist/mail/sender-resolver.d.ts.map +1 -1
- package/dist/mail/sender-resolver.js +11 -10
- package/dist/mail/sender-resolver.js.map +1 -1
- package/dist/mail/template-renderer.d.ts +1 -9
- package/dist/mail/template-renderer.d.ts.map +1 -1
- package/dist/mail/template-renderer.js +10 -15
- package/dist/mail/template-renderer.js.map +1 -1
- package/dist/mail/transactional-outbound.d.ts +115 -0
- package/dist/mail/transactional-outbound.d.ts.map +1 -0
- package/dist/mail/transactional-outbound.js +113 -0
- package/dist/mail/transactional-outbound.js.map +1 -0
- package/dist/mail/types.d.ts +2 -142
- package/dist/mail/types.d.ts.map +1 -1
- package/dist/mail/types.js +1 -33
- package/dist/mail/types.js.map +1 -1
- package/dist/portal/provisioning.d.ts +58 -0
- package/dist/portal/provisioning.d.ts.map +1 -0
- package/dist/portal/provisioning.js +139 -0
- package/dist/portal/provisioning.js.map +1 -0
- package/dist/pricing-engine/canonical.d.ts +14 -0
- package/dist/pricing-engine/canonical.d.ts.map +1 -0
- package/dist/pricing-engine/canonical.js +39 -0
- package/dist/pricing-engine/canonical.js.map +1 -0
- package/dist/pricing-engine/errors.d.ts.map +1 -1
- package/dist/pricing-engine/errors.js +6 -1
- package/dist/pricing-engine/errors.js.map +1 -1
- package/dist/pricing-engine/index.d.ts +12 -2
- package/dist/pricing-engine/index.d.ts.map +1 -1
- package/dist/pricing-engine/index.js +6 -1
- package/dist/pricing-engine/index.js.map +1 -1
- package/dist/pricing-engine/pipeline.d.ts.map +1 -1
- package/dist/pricing-engine/pipeline.js +202 -28
- package/dist/pricing-engine/pipeline.js.map +1 -1
- package/dist/pricing-engine/shadow-adapter.d.ts +37 -0
- package/dist/pricing-engine/shadow-adapter.d.ts.map +1 -0
- package/dist/pricing-engine/shadow-adapter.js +75 -0
- package/dist/pricing-engine/shadow-adapter.js.map +1 -0
- package/dist/pricing-engine/shadow-diff.d.ts +26 -0
- package/dist/pricing-engine/shadow-diff.d.ts.map +1 -0
- package/dist/pricing-engine/shadow-diff.js +52 -0
- package/dist/pricing-engine/shadow-diff.js.map +1 -0
- package/dist/pricing-engine/shadow-facade.d.ts +42 -0
- package/dist/pricing-engine/shadow-facade.d.ts.map +1 -0
- package/dist/pricing-engine/shadow-facade.js +82 -0
- package/dist/pricing-engine/shadow-facade.js.map +1 -0
- package/dist/pricing-engine/shadow-legacy-types.d.ts +64 -0
- package/dist/pricing-engine/shadow-legacy-types.d.ts.map +1 -0
- package/dist/pricing-engine/shadow-legacy-types.js +18 -0
- package/dist/pricing-engine/shadow-legacy-types.js.map +1 -0
- package/dist/pricing-engine/shadow-metrics.d.ts +33 -0
- package/dist/pricing-engine/shadow-metrics.d.ts.map +1 -0
- package/dist/pricing-engine/shadow-metrics.js +31 -0
- package/dist/pricing-engine/shadow-metrics.js.map +1 -0
- package/dist/pricing-engine/shadow-normalizer.d.ts +17 -0
- package/dist/pricing-engine/shadow-normalizer.d.ts.map +1 -0
- package/dist/pricing-engine/shadow-normalizer.js +39 -0
- package/dist/pricing-engine/shadow-normalizer.js.map +1 -0
- package/dist/pricing-engine/types.d.ts +2 -0
- package/dist/pricing-engine/types.d.ts.map +1 -1
- package/dist/rbac/authorize.d.ts +12 -0
- package/dist/rbac/authorize.d.ts.map +1 -1
- package/dist/rbac/authorize.js +27 -0
- package/dist/rbac/authorize.js.map +1 -1
- package/dist/rbac/catalog.d.ts.map +1 -1
- package/dist/rbac/catalog.js +67 -1
- package/dist/rbac/catalog.js.map +1 -1
- package/dist/rbac/workload-provisioning.d.ts +66 -0
- package/dist/rbac/workload-provisioning.d.ts.map +1 -0
- package/dist/rbac/workload-provisioning.js +153 -0
- package/dist/rbac/workload-provisioning.js.map +1 -0
- package/dist/rbac/workload.d.ts +124 -0
- package/dist/rbac/workload.d.ts.map +1 -0
- package/dist/rbac/workload.js +184 -0
- package/dist/rbac/workload.js.map +1 -0
- package/dist/storage/checksum.d.ts +9 -0
- package/dist/storage/checksum.d.ts.map +1 -0
- package/dist/storage/checksum.js +12 -0
- package/dist/storage/checksum.js.map +1 -0
- package/dist/storage/key.d.ts +37 -0
- package/dist/storage/key.d.ts.map +1 -0
- package/dist/storage/key.js +67 -0
- package/dist/storage/key.js.map +1 -0
- package/dist/storage/local.d.ts +40 -0
- package/dist/storage/local.d.ts.map +1 -0
- package/dist/storage/local.js +96 -0
- package/dist/storage/local.js.map +1 -0
- package/dist/storage/r2.d.ts +43 -0
- package/dist/storage/r2.d.ts.map +1 -0
- package/dist/storage/r2.js +177 -0
- package/dist/storage/r2.js.map +1 -0
- package/dist/storage/registry.d.ts +23 -0
- package/dist/storage/registry.d.ts.map +1 -0
- package/dist/storage/registry.js +37 -0
- package/dist/storage/registry.js.map +1 -0
- package/dist/storage/types.d.ts +67 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +45 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/subscription-billing/provider/asaas.d.ts +14 -0
- package/dist/subscription-billing/provider/asaas.d.ts.map +1 -1
- package/dist/subscription-billing/provider/asaas.js +32 -7
- package/dist/subscription-billing/provider/asaas.js.map +1 -1
- package/dist/subscription-billing/provider/disabled.d.ts +9 -0
- package/dist/subscription-billing/provider/disabled.d.ts.map +1 -1
- package/dist/subscription-billing/provider/disabled.js +8 -0
- package/dist/subscription-billing/provider/disabled.js.map +1 -1
- package/dist/subscription-billing/provider/registry.d.ts +10 -0
- package/dist/subscription-billing/provider/registry.d.ts.map +1 -1
- package/dist/subscription-billing/provider/registry.js +17 -0
- package/dist/subscription-billing/provider/registry.js.map +1 -1
- package/dist/subscription-billing/service.d.ts +17 -1
- package/dist/subscription-billing/service.d.ts.map +1 -1
- package/dist/subscription-billing/service.js +57 -8
- package/dist/subscription-billing/service.js.map +1 -1
- package/dist/subscription-billing/types.d.ts +13 -0
- package/dist/subscription-billing/types.d.ts.map +1 -1
- package/dist/subscription-billing/types.js.map +1 -1
- package/dist/tenancy/provisioning.d.ts.map +1 -1
- package/dist/tenancy/provisioning.js +32 -8
- package/dist/tenancy/provisioning.js.map +1 -1
- package/dist/users/repository.d.ts +38 -0
- package/dist/users/repository.d.ts.map +1 -1
- package/dist/users/repository.js +118 -3
- package/dist/users/repository.js.map +1 -1
- package/dist/vault/repository.d.ts +67 -0
- package/dist/vault/repository.d.ts.map +1 -1
- package/dist/vault/repository.js +78 -0
- package/dist/vault/repository.js.map +1 -1
- package/package.json +13 -4
- package/src/db/migrations/0023_user_invite_activation.sql +15 -0
- package/src/db/migrations/0024_set_user_password_function.sql +32 -0
- package/src/db/migrations/0025_revoke_user_session_function.sql +28 -0
- package/src/db/migrations/0026_documents_and_competence.sql +353 -0
- package/src/db/migrations/0027_receivable_client_isolation.sql +58 -0
- package/src/db/migrations/0028_collection_engine.sql +94 -0
- package/src/db/migrations/0029_payment_rail.sql +107 -0
- package/src/db/migrations/0030_provider_account_uniqueness.sql +22 -0
- package/src/db/migrations/0031_provider_account_environment_scope.sql +21 -0
- package/src/db/migrations/0032_settlement_reversal.sql +76 -0
- package/src/db/migrations/0033_receivable_idempotency.sql +28 -0
- package/src/db/migrations/0034_payment_customer_reconcile.sql +30 -0
- package/src/db/migrations/0035_payment_account_environments.sql +61 -0
- package/src/db/migrations/0036_primary_backfill_under_force_rls.sql +41 -0
- package/src/db/migrations/0037_receivable_generation_source.sql +29 -0
- package/src/db/migrations/0038_notification_channels.sql +175 -0
- package/src/db/migrations/0039_communication_dispatch_claim.sql +193 -0
- package/src/db/migrations/0040_communication_unknown_outcome.sql +99 -0
- package/src/db/migrations/0041_channel_binding_routing.sql +146 -0
- package/src/db/migrations/0042_channel_route_read_isolation.sql +165 -0
- package/src/db/migrations/0043_workload_identity.sql +105 -0
- package/src/db/migrations/0044_channel_onboarding_session.sql +96 -0
- package/dist/cjs/mail/resend-client.js +0 -103
- package/dist/cjs/mail/resend-client.js.map +0 -1
- package/dist/mail/resend-client.d.ts +0 -16
- package/dist/mail/resend-client.d.ts.map +0 -1
- package/dist/mail/resend-client.js +0 -100
- package/dist/mail/resend-client.js.map +0 -1
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Provisionamento de identidade e autoridade de workload — **lado owner**.
|
|
4
|
+
*
|
|
5
|
+
* Tudo aqui escreve em `service_principal` / `service_principal_grant`, e o
|
|
6
|
+
* papel `baruk_app` não tem INSERT/UPDATE/DELETE nessas tabelas. Chamar estas
|
|
7
|
+
* funções com a conexão da aplicação falha no Postgres, não numa checagem de
|
|
8
|
+
* aplicação que alguém possa remover: é essa assimetria que sustenta
|
|
9
|
+
* `GRANT_FORGEABLE_BY_INTERNAL_CALLER = false`.
|
|
10
|
+
*
|
|
11
|
+
* O caminho previsto é o provisionamento operado com a credencial de migração
|
|
12
|
+
* (mesma que aplica `db:migrate`), ou — quando existir tela — uma rota de admin
|
|
13
|
+
* que já exija RBAC humano. Nos dois casos a autoridade nasce FORA do processo
|
|
14
|
+
* que a consome.
|
|
15
|
+
*
|
|
16
|
+
* Nenhuma função daqui é importada pelo runtime do motor. Se um dia for, o
|
|
17
|
+
* privilégio do banco continua negando.
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.createServicePrincipal = createServicePrincipal;
|
|
21
|
+
exports.rotateServicePrincipalSecret = rotateServicePrincipalSecret;
|
|
22
|
+
exports.disableServicePrincipal = disableServicePrincipal;
|
|
23
|
+
exports.grantWorkloadPermission = grantWorkloadPermission;
|
|
24
|
+
exports.revokeWorkloadGrant = revokeWorkloadGrant;
|
|
25
|
+
const shared_1 = require("@baruk/shared");
|
|
26
|
+
const password_js_1 = require("../auth/password.js");
|
|
27
|
+
const context_js_1 = require("../db/context.js");
|
|
28
|
+
const workload_js_1 = require("./workload.js");
|
|
29
|
+
function assertKey(key) {
|
|
30
|
+
const k = key?.trim() ?? '';
|
|
31
|
+
// Slug conservador: é identificador operacional, aparece em trilha e em
|
|
32
|
+
// configuração de deploy. Espaço e maiúscula viram divergência silenciosa.
|
|
33
|
+
if (!/^[a-z0-9][a-z0-9-]{2,62}$/.test(k)) {
|
|
34
|
+
throw new shared_1.ValidationError('key do service principal deve ser slug minúsculo (a-z, 0-9, hífen), 3..63 caracteres.');
|
|
35
|
+
}
|
|
36
|
+
return k;
|
|
37
|
+
}
|
|
38
|
+
function assertSecret(secret) {
|
|
39
|
+
// 32 caracteres é o piso para um segredo gerado por máquina. Não há usuário
|
|
40
|
+
// humano digitando isto — não há motivo para aceitar menos.
|
|
41
|
+
if (typeof secret !== 'string' || secret.length < 32) {
|
|
42
|
+
throw new shared_1.ValidationError('secret do service principal precisa de ao menos 32 caracteres.');
|
|
43
|
+
}
|
|
44
|
+
return secret;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Cria (ou reabilita) um principal de workload. **Idempotente por `key`**, e
|
|
48
|
+
* o segredo de um principal existente é PRESERVADO por padrão — a mesma
|
|
49
|
+
* armadilha que `upsertUserWithPassword` já documenta: um provisionamento que
|
|
50
|
+
* roda de novo e troca o segredo em silêncio derruba o workload sem erro.
|
|
51
|
+
*/
|
|
52
|
+
async function createServicePrincipal(owner, input) {
|
|
53
|
+
const key = assertKey(input.key);
|
|
54
|
+
const secret = assertSecret(input.secret);
|
|
55
|
+
const displayName = input.displayName?.trim() ?? '';
|
|
56
|
+
if (!displayName)
|
|
57
|
+
throw new shared_1.ValidationError('displayName é obrigatório.');
|
|
58
|
+
const existing = await owner `
|
|
59
|
+
SELECT id, key FROM service_principal WHERE lower(key) = lower(${key}) AND deleted_at IS NULL
|
|
60
|
+
`;
|
|
61
|
+
if (existing[0]) {
|
|
62
|
+
if (input.overwriteSecret) {
|
|
63
|
+
await owner `
|
|
64
|
+
UPDATE service_principal
|
|
65
|
+
SET secret_hash = ${(0, password_js_1.hashPassword)(secret)}, secret_rotated_at = now(),
|
|
66
|
+
display_name = ${displayName}, status = 'active', disabled_at = NULL,
|
|
67
|
+
updated_at = now()
|
|
68
|
+
WHERE id = ${existing[0].id}
|
|
69
|
+
`;
|
|
70
|
+
}
|
|
71
|
+
return existing[0];
|
|
72
|
+
}
|
|
73
|
+
const id = (0, shared_1.uuidv7)();
|
|
74
|
+
await owner `
|
|
75
|
+
INSERT INTO service_principal (id, key, display_name, secret_hash)
|
|
76
|
+
VALUES (${id}, ${key}, ${displayName}, ${(0, password_js_1.hashPassword)(secret)})
|
|
77
|
+
`;
|
|
78
|
+
return { id, key };
|
|
79
|
+
}
|
|
80
|
+
/** Rotação de segredo. O valor antigo para de autenticar na próxima chamada. */
|
|
81
|
+
async function rotateServicePrincipalSecret(owner, key, newSecret) {
|
|
82
|
+
const rows = await owner `
|
|
83
|
+
UPDATE service_principal
|
|
84
|
+
SET secret_hash = ${(0, password_js_1.hashPassword)(assertSecret(newSecret))},
|
|
85
|
+
secret_rotated_at = now(), updated_at = now()
|
|
86
|
+
WHERE lower(key) = lower(${assertKey(key)}) AND deleted_at IS NULL
|
|
87
|
+
RETURNING id
|
|
88
|
+
`;
|
|
89
|
+
if (rows.count === 0)
|
|
90
|
+
throw new shared_1.NotFoundError('service principal não encontrado');
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Revoga a IDENTIDADE inteira. Vale na próxima chamada, sem esperar a sessão
|
|
94
|
+
* em memória expirar — `authorizeWorkload` relê o principal a cada decisão.
|
|
95
|
+
*/
|
|
96
|
+
async function disableServicePrincipal(owner, key) {
|
|
97
|
+
const rows = await owner `
|
|
98
|
+
UPDATE service_principal
|
|
99
|
+
SET status = 'disabled', disabled_at = now(), updated_at = now()
|
|
100
|
+
WHERE lower(key) = lower(${assertKey(key)}) AND deleted_at IS NULL
|
|
101
|
+
RETURNING id
|
|
102
|
+
`;
|
|
103
|
+
if (rows.count === 0)
|
|
104
|
+
throw new shared_1.NotFoundError('service principal não encontrado');
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Concede a um principal uma permissão ESCOPADA a tenant + propósito + recurso.
|
|
108
|
+
*
|
|
109
|
+
* Roda dentro do contexto do tenant porque `service_principal_grant` está sob
|
|
110
|
+
* RLS FORCE — inclusive para o owner. Uma concessão para um tenant que não é o
|
|
111
|
+
* do contexto é recusada pelo banco, não por um `if`.
|
|
112
|
+
*/
|
|
113
|
+
async function grantWorkloadPermission(owner, input) {
|
|
114
|
+
const key = assertKey(input.principalKey);
|
|
115
|
+
const permission = input.permission?.trim() ?? '';
|
|
116
|
+
const resourceValue = input.resourceValue?.trim() ?? '';
|
|
117
|
+
if (!permission)
|
|
118
|
+
throw new shared_1.ValidationError('permission é obrigatória.');
|
|
119
|
+
if (!workload_js_1.WORKLOAD_PURPOSES.includes(input.purpose)) {
|
|
120
|
+
throw new shared_1.ValidationError(`purpose inválido: ${String(input.purpose)}.`);
|
|
121
|
+
}
|
|
122
|
+
if (input.resourceKind !== 'exact' && input.resourceKind !== 'prefix') {
|
|
123
|
+
throw new shared_1.ValidationError('resourceKind precisa ser "exact" ou "prefix".');
|
|
124
|
+
}
|
|
125
|
+
if (resourceValue.length < 3) {
|
|
126
|
+
throw new shared_1.ValidationError('resourceValue precisa de ao menos 3 caracteres — um escopo vazio alcançaria tudo.');
|
|
127
|
+
}
|
|
128
|
+
const principal = await owner `
|
|
129
|
+
SELECT id FROM service_principal WHERE lower(key) = lower(${key}) AND deleted_at IS NULL
|
|
130
|
+
`;
|
|
131
|
+
if (!principal[0])
|
|
132
|
+
throw new shared_1.NotFoundError('service principal não encontrado');
|
|
133
|
+
const id = (0, shared_1.uuidv7)();
|
|
134
|
+
await (0, context_js_1.withContext)(owner, { tenantId: input.tenantId }, async (tx) => {
|
|
135
|
+
await tx `
|
|
136
|
+
INSERT INTO service_principal_grant (
|
|
137
|
+
id, tenant_id, principal_id, permission_key, purpose,
|
|
138
|
+
resource_kind, resource_value, granted_by, granted_reason, expires_at
|
|
139
|
+
) VALUES (
|
|
140
|
+
${id}, ${input.tenantId}, ${principal[0].id}, ${permission}, ${input.purpose},
|
|
141
|
+
${input.resourceKind}, ${resourceValue}, ${input.grantedBy ?? null},
|
|
142
|
+
${input.grantedReason ?? null}, ${input.expiresAt ?? null}
|
|
143
|
+
)
|
|
144
|
+
`;
|
|
145
|
+
});
|
|
146
|
+
return id;
|
|
147
|
+
}
|
|
148
|
+
/** Revoga UMA concessão. Vale na próxima chamada. */
|
|
149
|
+
async function revokeWorkloadGrant(owner, tenantId, grantId) {
|
|
150
|
+
await (0, context_js_1.withContext)(owner, { tenantId }, async (tx) => {
|
|
151
|
+
const rows = await tx `
|
|
152
|
+
UPDATE service_principal_grant SET revoked_at = now()
|
|
153
|
+
WHERE id = ${grantId} AND revoked_at IS NULL
|
|
154
|
+
RETURNING id
|
|
155
|
+
`;
|
|
156
|
+
if (rows.count === 0)
|
|
157
|
+
throw new shared_1.NotFoundError('grant não encontrado ou já revogado');
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=workload-provisioning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workload-provisioning.js","sourceRoot":"","sources":["../../../src/rbac/workload-provisioning.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Identidade e autorização de workload NÃO-HUMANO.
|
|
4
|
+
*
|
|
5
|
+
* O RBAC de `authorize.ts` responde "este USUÁRIO pode?". Nenhuma linha do
|
|
6
|
+
* repositório respondia "este PROCESSO pode?" — e a diferença não é
|
|
7
|
+
* acadêmica: o `TenantSecretStore` do lote C1A aceitava um `SecretAccessGrant`
|
|
8
|
+
* montado pelo próprio chamador. `principal`, `reason` e as datas eram strings
|
|
9
|
+
* e `Date`s sintaticamente válidas; qualquer módulo interno com acesso ao
|
|
10
|
+
* arquivo podia declará-las e pedir decifração. Isso é ATRIBUIÇÃO — serve para
|
|
11
|
+
* a trilha de auditoria e não serve como fronteira de segurança.
|
|
12
|
+
*
|
|
13
|
+
* Este módulo troca a declaração por três coisas que o chamador não consegue
|
|
14
|
+
* fabricar sozinho:
|
|
15
|
+
*
|
|
16
|
+
* 1. **Autenticação.** O workload apresenta um segredo próprio, verificado
|
|
17
|
+
* contra `service_principal.secret_hash` (scrypt, o mesmo `verifyPassword`
|
|
18
|
+
* da senha humana). Sem o segredo, não há identidade — e o segredo vive no
|
|
19
|
+
* ambiente do deploy que roda AQUELE workload, não no código.
|
|
20
|
+
*
|
|
21
|
+
* 2. **Autorização fora do controlado.** A permissão vem de linhas em
|
|
22
|
+
* `service_principal_grant`, e `baruk_app` tem apenas SELECT nessas tabelas
|
|
23
|
+
* (`db/migrate.ts` §3). O processo que consome a autorização não consegue
|
|
24
|
+
* escrevê-la: não é uma regra de tipo, é um privilégio do Postgres.
|
|
25
|
+
*
|
|
26
|
+
* 3. **Verificação por CHAMADA, dentro da transação.** A decisão não é
|
|
27
|
+
* memorizada na composição. Revogar um principal ou um grant passa a valer
|
|
28
|
+
* na próxima chamada, sem esperar o processo reiniciar.
|
|
29
|
+
*
|
|
30
|
+
* O objeto `WorkloadIdentity` é apenas o transporte da identidade JÁ
|
|
31
|
+
* autenticada. Ele é marcado com um símbolo privado deste módulo e registrado
|
|
32
|
+
* num `WeakSet` privado: um objeto estruturalmente idêntico, montado à mão em
|
|
33
|
+
* outro arquivo, é recusado. Mas a marca não é a fronteira — é a tranca da
|
|
34
|
+
* porta interna. A fronteira é o par (segredo, linha no banco).
|
|
35
|
+
*/
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.WORKLOAD_PURPOSES = void 0;
|
|
38
|
+
exports.authenticateWorkload = authenticateWorkload;
|
|
39
|
+
exports.isMintedWorkloadIdentity = isMintedWorkloadIdentity;
|
|
40
|
+
exports.assertMintedWorkloadIdentity = assertMintedWorkloadIdentity;
|
|
41
|
+
exports.authorizeWorkload = authorizeWorkload;
|
|
42
|
+
const shared_1 = require("@baruk/shared");
|
|
43
|
+
const password_js_1 = require("../auth/password.js");
|
|
44
|
+
exports.WORKLOAD_PURPOSES = [
|
|
45
|
+
'channel_dispatch',
|
|
46
|
+
'onboarding_seal',
|
|
47
|
+
'health_probe',
|
|
48
|
+
];
|
|
49
|
+
/**
|
|
50
|
+
* Marca privada. Não é exportada — logo, nenhum arquivo fora daqui consegue
|
|
51
|
+
* escrever esta propriedade de forma tipada, e `MINTED` recusa o objeto
|
|
52
|
+
* estruturalmente idêntico em tempo de execução.
|
|
53
|
+
*/
|
|
54
|
+
const WORKLOAD_BRAND = Symbol('baruk.workload-identity');
|
|
55
|
+
const MINTED = new WeakSet();
|
|
56
|
+
/** Sessão padrão: 1h. Um cron diário reautentica a cada execução; um worker, de hora em hora. */
|
|
57
|
+
const DEFAULT_TTL_MS = 60 * 60 * 1000;
|
|
58
|
+
/** Teto duro. Uma sessão de dias equivaleria a não ter janela nenhuma. */
|
|
59
|
+
const MAX_TTL_MS = 12 * 60 * 60 * 1000;
|
|
60
|
+
/**
|
|
61
|
+
* Hash descartável com o mesmo custo de um real. Existe para que "principal
|
|
62
|
+
* inexistente" e "segredo errado" levem o mesmo tempo — sem isso, a latência
|
|
63
|
+
* enumera quais principals existem.
|
|
64
|
+
*/
|
|
65
|
+
const DUMMY_HASH = `scrypt$16384$8$1$${'A'.repeat(22)}==$${'a'.repeat(86)}==`;
|
|
66
|
+
/**
|
|
67
|
+
* Autentica um workload e emite a identidade da sessão.
|
|
68
|
+
*
|
|
69
|
+
* **Chame na RAIZ DE COMPOSIÇÃO** — o `main()` do cron, o bootstrap do worker,
|
|
70
|
+
* a borda de request já autenticada — e propague a identidade. Nenhum módulo de
|
|
71
|
+
* domínio deve chamar isto: quem PRECISA do segredo nunca deve ser quem
|
|
72
|
+
* declara ter direito a ele.
|
|
73
|
+
*
|
|
74
|
+
* Falha FECHADA e ruidosa: `UnauthorizedError`. Um workload que não autentica
|
|
75
|
+
* deve parar no boot, com o erro visível, não seguir e falhar seis passos
|
|
76
|
+
* depois como "canal indisponível".
|
|
77
|
+
*
|
|
78
|
+
* Roda FORA de contexto de tenant: `service_principal` é global, como `"user"`.
|
|
79
|
+
* A amarração ao tenant é da autorização (`authorizeWorkload`), não da identidade.
|
|
80
|
+
*/
|
|
81
|
+
async function authenticateWorkload(db, input) {
|
|
82
|
+
const key = input?.key?.trim() ?? '';
|
|
83
|
+
const secret = typeof input?.secret === 'string' ? input.secret : '';
|
|
84
|
+
if (!key)
|
|
85
|
+
throw new shared_1.ValidationError('key do service principal é obrigatória.');
|
|
86
|
+
if (!secret)
|
|
87
|
+
throw new shared_1.ValidationError('secret do service principal é obrigatório.');
|
|
88
|
+
const ttl = input.ttlMs ?? DEFAULT_TTL_MS;
|
|
89
|
+
if (!Number.isFinite(ttl) || ttl <= 0 || ttl > MAX_TTL_MS) {
|
|
90
|
+
throw new shared_1.ValidationError(`ttlMs fora da janela permitida (1..${MAX_TTL_MS}).`);
|
|
91
|
+
}
|
|
92
|
+
const rows = await db `
|
|
93
|
+
SELECT id, key, status, secret_hash
|
|
94
|
+
FROM service_principal
|
|
95
|
+
WHERE lower(key) = lower(${key}) AND deleted_at IS NULL
|
|
96
|
+
`;
|
|
97
|
+
const row = rows[0];
|
|
98
|
+
// Verifica SEMPRE — inclusive contra o hash descartável quando não há linha.
|
|
99
|
+
const matches = (0, password_js_1.verifyPassword)(secret, row?.secret_hash ?? DUMMY_HASH);
|
|
100
|
+
if (!row || row.status !== 'active' || !matches) {
|
|
101
|
+
throw new shared_1.UnauthorizedError('Workload não autenticado.');
|
|
102
|
+
}
|
|
103
|
+
const issuedAt = input.now ?? new Date();
|
|
104
|
+
const identity = {
|
|
105
|
+
principalId: row.id,
|
|
106
|
+
principalKey: row.key,
|
|
107
|
+
issuedAt,
|
|
108
|
+
expiresAt: new Date(issuedAt.getTime() + ttl),
|
|
109
|
+
[WORKLOAD_BRAND]: true,
|
|
110
|
+
};
|
|
111
|
+
MINTED.add(identity);
|
|
112
|
+
return identity;
|
|
113
|
+
}
|
|
114
|
+
/** O objeto veio de `authenticateWorkload`? Recusa qualquer imitação estrutural. */
|
|
115
|
+
function isMintedWorkloadIdentity(value) {
|
|
116
|
+
return typeof value === 'object' && value !== null && MINTED.has(value);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Falha fechada quando a identidade não foi emitida aqui. Chamado por TODO
|
|
120
|
+
* consumidor antes de qualquer trabalho — um `ForbiddenError` no primeiro
|
|
121
|
+
* passo é a diferença entre uma tentativa recusada e um segredo entregue.
|
|
122
|
+
*/
|
|
123
|
+
function assertMintedWorkloadIdentity(value) {
|
|
124
|
+
if (!isMintedWorkloadIdentity(value)) {
|
|
125
|
+
throw new shared_1.ForbiddenError('WorkloadIdentity não emitida por authenticateWorkload — identidade forjada recusada.');
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Decide se ESTE principal pode exercer ESTA permissão, NESTE tenant, para
|
|
130
|
+
* ESTE propósito, sobre ESTE recurso. Quatro dimensões conjuntivas.
|
|
131
|
+
*
|
|
132
|
+
* A quarta é o que fecha confused deputy: um workload legitimamente autorizado
|
|
133
|
+
* no tenant A a despachar canal não decifra a chave do gateway de pagamento do
|
|
134
|
+
* tenant A só porque um `credentialRef` vindo de input pediu. A autorização do
|
|
135
|
+
* workload nunca vira autorização para qualquer recurso que o input nomear.
|
|
136
|
+
*
|
|
137
|
+
* **DEVE rodar dentro de `withContext(db, { tenantId })`** — a RLS FORCE de
|
|
138
|
+
* `service_principal_grant` é a segunda camada; o predicado explícito de
|
|
139
|
+
* `tenant_id` é a primeira. As duas dizem a mesma coisa de propósito: nenhuma
|
|
140
|
+
* das duas sozinha é o desenho.
|
|
141
|
+
*/
|
|
142
|
+
async function authorizeWorkload(tx, identity, req) {
|
|
143
|
+
assertMintedWorkloadIdentity(identity);
|
|
144
|
+
const tenantId = req?.tenantId?.trim() ?? '';
|
|
145
|
+
const permission = req?.permission?.trim() ?? '';
|
|
146
|
+
const resource = req?.resource?.trim() ?? '';
|
|
147
|
+
const purpose = req?.purpose;
|
|
148
|
+
if (!tenantId || !permission || !resource || !exports.WORKLOAD_PURPOSES.includes(purpose)) {
|
|
149
|
+
return { allowed: false, denyReason: 'invalid_request' };
|
|
150
|
+
}
|
|
151
|
+
const now = req.now ?? new Date();
|
|
152
|
+
if (now.getTime() >= identity.expiresAt.getTime() ||
|
|
153
|
+
now.getTime() < identity.issuedAt.getTime()) {
|
|
154
|
+
return { allowed: false, denyReason: 'identity_expired' };
|
|
155
|
+
}
|
|
156
|
+
// Revogação vale AGORA, não no próximo boot: relê o principal a cada chamada.
|
|
157
|
+
const principal = await tx `
|
|
158
|
+
SELECT id FROM service_principal
|
|
159
|
+
WHERE id = ${identity.principalId} AND status = 'active' AND deleted_at IS NULL
|
|
160
|
+
`;
|
|
161
|
+
if (!principal[0]) {
|
|
162
|
+
return { allowed: false, denyReason: 'principal_unknown_or_disabled' };
|
|
163
|
+
}
|
|
164
|
+
// `left(...)` em vez de LIKE: o valor do prefixo é literal, e `_`/`%` são
|
|
165
|
+
// caracteres comuns em nome de credencial (`RESEND_API_KEY`). Um LIKE aqui
|
|
166
|
+
// transformaria um nome legítimo em curinga.
|
|
167
|
+
const grants = await tx `
|
|
168
|
+
SELECT id FROM service_principal_grant
|
|
169
|
+
WHERE tenant_id = ${tenantId}
|
|
170
|
+
AND principal_id = ${identity.principalId}
|
|
171
|
+
AND permission_key = ${permission}
|
|
172
|
+
AND purpose = ${purpose}
|
|
173
|
+
AND revoked_at IS NULL
|
|
174
|
+
AND deleted_at IS NULL
|
|
175
|
+
AND (expires_at IS NULL OR expires_at > ${now})
|
|
176
|
+
AND (
|
|
177
|
+
(resource_kind = 'exact' AND lower(resource_value) = lower(${resource}))
|
|
178
|
+
OR (
|
|
179
|
+
resource_kind = 'prefix'
|
|
180
|
+
AND left(lower(${resource}), length(lower(resource_value))) = lower(resource_value)
|
|
181
|
+
)
|
|
182
|
+
)
|
|
183
|
+
LIMIT 1
|
|
184
|
+
`;
|
|
185
|
+
const grant = grants[0];
|
|
186
|
+
if (!grant) {
|
|
187
|
+
return { allowed: false, denyReason: 'no_matching_grant' };
|
|
188
|
+
}
|
|
189
|
+
return { allowed: true, grantId: grant.id };
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=workload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workload.js","sourceRoot":"","sources":["../../../src/rbac/workload.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sha256Hex = sha256Hex;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
/**
|
|
6
|
+
* SHA-256 em hex minúsculo — a forma exigida pelo CHECK de `blob.checksum_sha256`.
|
|
7
|
+
*
|
|
8
|
+
* É o identificador de conteúdo que sustenta duas coisas na ADR 0007: a
|
|
9
|
+
* deduplicação por tenant e a prova de que a versão baixada é byte-idêntica à
|
|
10
|
+
* que foi enviada.
|
|
11
|
+
*/
|
|
12
|
+
function sha256Hex(data) {
|
|
13
|
+
return (0, node_crypto_1.createHash)('sha256').update(data).digest('hex');
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=checksum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checksum.js","sourceRoot":"","sources":["../../../src/storage/checksum.ts"],"names":[],"mappings":";;AASA,8BAEC;AAXD,6CAAyC;AAEzC;;;;;;GAMG;AACH,SAAgB,SAAS,CAAC,IAAgB;IACxC,OAAO,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzD,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildStorageKey = buildStorageKey;
|
|
4
|
+
exports.sanitizeSegment = sanitizeSegment;
|
|
5
|
+
exports.sanitizeFilename = sanitizeFilename;
|
|
6
|
+
const node_crypto_1 = require("node:crypto");
|
|
7
|
+
/**
|
|
8
|
+
* Construção da chave de objeto (ADR 0007 D7).
|
|
9
|
+
*
|
|
10
|
+
* Formato:
|
|
11
|
+
* {tenant_id}/{client_id}/{yyyy}/{mm}/{category}/{document_id}/{version}-{rand}
|
|
12
|
+
*
|
|
13
|
+
* Três propriedades que a forma garante:
|
|
14
|
+
*
|
|
15
|
+
* 1. **Tenant no primeiro segmento** — a fronteira fica legível no próprio
|
|
16
|
+
* bucket e permite política de acesso por prefixo no provedor.
|
|
17
|
+
* 2. **Não previsível** — o sufixo aleatório impede que alguém que conheça os
|
|
18
|
+
* ids enumere objetos. A URL assinada já expira, mas defesa em profundidade
|
|
19
|
+
* custa 8 bytes.
|
|
20
|
+
* 3. **Sem nome de arquivo do cliente** — o `original_filename` vive na tabela
|
|
21
|
+
* `document_version`, nunca na chave. Nome vindo do cliente não é identidade
|
|
22
|
+
* de objeto e é o vetor clássico de path traversal.
|
|
23
|
+
*/
|
|
24
|
+
function buildStorageKey(input) {
|
|
25
|
+
const { tenantId, clientId, documentId, versionNo } = input;
|
|
26
|
+
// Competência dá a partição temporal quando existe; senão, a data corrente.
|
|
27
|
+
// O formato YYYY-MM já é validado no banco, então o split é seguro.
|
|
28
|
+
let yyyy;
|
|
29
|
+
let mm;
|
|
30
|
+
if (input.competenceLabel && /^\d{4}-\d{2}$/.test(input.competenceLabel)) {
|
|
31
|
+
[yyyy, mm] = input.competenceLabel.split('-');
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
const now = new Date();
|
|
35
|
+
yyyy = String(now.getUTCFullYear());
|
|
36
|
+
mm = String(now.getUTCMonth() + 1).padStart(2, '0');
|
|
37
|
+
}
|
|
38
|
+
const category = sanitizeSegment(input.categoryKey ?? 'geral');
|
|
39
|
+
const rand = (0, node_crypto_1.randomBytes)(8).toString('hex');
|
|
40
|
+
return `${tenantId}/${clientId}/${yyyy}/${mm}/${category}/${documentId}/${versionNo}-${rand}`;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Reduz um segmento a `[a-z0-9_-]`. Qualquer outra coisa — inclusive `.` e `/` —
|
|
44
|
+
* é descartada, o que torna `../` impossível de construir por aqui.
|
|
45
|
+
*/
|
|
46
|
+
function sanitizeSegment(value) {
|
|
47
|
+
const cleaned = value
|
|
48
|
+
.toLowerCase()
|
|
49
|
+
.normalize('NFD')
|
|
50
|
+
.replace(/[\u0300-\u036f]/g, '')
|
|
51
|
+
.replace(/[^a-z0-9_-]/g, '-')
|
|
52
|
+
.replace(/-+/g, '-')
|
|
53
|
+
.replace(/^-|-$/g, '')
|
|
54
|
+
.slice(0, 48);
|
|
55
|
+
return cleaned.length > 0 ? cleaned : 'geral';
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Higieniza o nome exibido ao usuário. Não participa da chave de storage — é só
|
|
59
|
+
* o rótulo guardado em `document_version.original_filename` e devolvido no
|
|
60
|
+
* download. Remove diretório, controla o comprimento e recusa nome vazio.
|
|
61
|
+
*/
|
|
62
|
+
function sanitizeFilename(value) {
|
|
63
|
+
const base = value.split(/[\\/]/).pop() ?? '';
|
|
64
|
+
const cleaned = base
|
|
65
|
+
// eslint-disable-next-line no-control-regex
|
|
66
|
+
.replace(/[\u0000-\u001f\u007f]/g, '')
|
|
67
|
+
.replace(/^\.+/, '')
|
|
68
|
+
.trim()
|
|
69
|
+
.slice(0, 180);
|
|
70
|
+
return cleaned.length > 0 ? cleaned : 'arquivo';
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key.js","sourceRoot":"","sources":["../../../src/storage/key.ts"],"names":[],"mappings":";;AAmBA,0CA0BC;AAMD,0CAUC;AAOD,4CASC;AA7ED,6CAA0C;AAE1C;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,eAAe,CAAC,KAO/B;IACC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAE5D,4EAA4E;IAC5E,oEAAoE;IACpE,IAAI,IAAY,CAAC;IACjB,IAAI,EAAU,CAAC;IACf,IAAI,KAAK,CAAC,eAAe,IAAI,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;QACzE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAC;IACpE,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC;QACpC,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,WAAW,IAAI,OAAO,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,IAAA,yBAAW,EAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE5C,OAAO,GAAG,QAAQ,IAAI,QAAQ,IAAI,IAAI,IAAI,EAAE,IAAI,QAAQ,IAAI,UAAU,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;AAChG,CAAC;AAED;;;GAGG;AACH,SAAgB,eAAe,CAAC,KAAa;IAC3C,MAAM,OAAO,GAAG,KAAK;SAClB,WAAW,EAAE;SACb,SAAS,CAAC,KAAK,CAAC;SAChB,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;SAC/B,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC;SAC5B,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChB,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,SAAgB,gBAAgB,CAAC,KAAa;IAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI;QAClB,4CAA4C;SAC3C,OAAO,CAAC,wBAAwB,EAAE,EAAE,CAAC;SACrC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;SACnB,IAAI,EAAE;SACN,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACjB,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LocalStorageProvider = void 0;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
const promises_1 = require("node:fs/promises");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const types_js_1 = require("./types.js");
|
|
8
|
+
const checksum_js_1 = require("./checksum.js");
|
|
9
|
+
/**
|
|
10
|
+
* Provider de sistema de arquivos — o default seguro (ADR 0007 D4).
|
|
11
|
+
*
|
|
12
|
+
* Usado em desenvolvimento e em toda a suíte de testes: nenhum teste depende de
|
|
13
|
+
* R2 real, o que mantém o CI offline e determinístico.
|
|
14
|
+
*
|
|
15
|
+
* A "URL assinada" aqui é um caminho relativo da própria API com token HMAC e
|
|
16
|
+
* expiração — mesma semântica do presigned do R2 (link temporário, sem
|
|
17
|
+
* credencial embutida), servido pelo backend em vez do provedor.
|
|
18
|
+
*/
|
|
19
|
+
class LocalStorageProvider {
|
|
20
|
+
key = 'local';
|
|
21
|
+
root;
|
|
22
|
+
signingSecret;
|
|
23
|
+
constructor(options) {
|
|
24
|
+
this.root = (0, node_path_1.resolve)(options.rootDir);
|
|
25
|
+
this.signingSecret = options.signingSecret;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Resolve a chave para um caminho absoluto e recusa qualquer coisa que escape
|
|
29
|
+
* da raiz. A chave já é construída por `buildStorageKey`, mas este guard não
|
|
30
|
+
* confia nisso: um provider de storage é o último lugar onde se deve supor
|
|
31
|
+
* que a entrada é boa.
|
|
32
|
+
*/
|
|
33
|
+
pathFor(key) {
|
|
34
|
+
if (key.includes('\0'))
|
|
35
|
+
throw new types_js_1.StorageError('chave inválida', 'invalid');
|
|
36
|
+
const target = (0, node_path_1.resolve)((0, node_path_1.join)(this.root, (0, node_path_1.normalize)(key)));
|
|
37
|
+
if (target !== this.root && !target.startsWith(this.root + node_path_1.sep)) {
|
|
38
|
+
throw new types_js_1.StorageError('chave fora da raiz de storage', 'invalid');
|
|
39
|
+
}
|
|
40
|
+
return target;
|
|
41
|
+
}
|
|
42
|
+
async put(input) {
|
|
43
|
+
const target = this.pathFor(input.key);
|
|
44
|
+
await (0, promises_1.mkdir)((0, node_path_1.dirname)(target), { recursive: true });
|
|
45
|
+
await (0, promises_1.writeFile)(target, input.body);
|
|
46
|
+
return {
|
|
47
|
+
key: input.key,
|
|
48
|
+
checksumSha256: (0, checksum_js_1.sha256Hex)(input.body),
|
|
49
|
+
sizeBytes: input.body.byteLength,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
async getSignedUrl(key, options) {
|
|
53
|
+
const ttl = options?.expiresInSeconds ?? types_js_1.DEFAULT_SIGNED_URL_TTL_SECONDS;
|
|
54
|
+
const expiresAt = Math.floor(Date.now() / 1000) + ttl;
|
|
55
|
+
const signature = this.sign(key, expiresAt);
|
|
56
|
+
const params = new URLSearchParams({ key, expires: String(expiresAt), sig: signature });
|
|
57
|
+
if (options?.downloadFilename)
|
|
58
|
+
params.set('filename', options.downloadFilename);
|
|
59
|
+
return `/v1/documents/blob?${params.toString()}`;
|
|
60
|
+
}
|
|
61
|
+
async head(key) {
|
|
62
|
+
try {
|
|
63
|
+
const info = await (0, promises_1.stat)(this.pathFor(key));
|
|
64
|
+
return { exists: true, sizeBytes: info.size };
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return { exists: false };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async delete(key) {
|
|
71
|
+
await (0, promises_1.rm)(this.pathFor(key), { force: true });
|
|
72
|
+
}
|
|
73
|
+
/** Lê o objeto. Só o LocalStorageProvider expõe isso — o R2 serve direto. */
|
|
74
|
+
async read(key) {
|
|
75
|
+
try {
|
|
76
|
+
return new Uint8Array(await (0, promises_1.readFile)(this.pathFor(key)));
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
throw new types_js_1.StorageError('objeto não encontrado', 'not-found');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
sign(key, expiresAt) {
|
|
83
|
+
return (0, node_crypto_1.createHmac)('sha256', this.signingSecret).update(`${key}:${expiresAt}`).digest('hex');
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Valida assinatura e expiração. Comparação em tempo constante — um HMAC
|
|
87
|
+
* comparado com `===` vaza o prefixo correto byte a byte.
|
|
88
|
+
*/
|
|
89
|
+
verifySignature(key, expiresAt, signature) {
|
|
90
|
+
if (!Number.isFinite(expiresAt) || expiresAt < Math.floor(Date.now() / 1000))
|
|
91
|
+
return false;
|
|
92
|
+
const expected = Buffer.from(this.sign(key, expiresAt), 'utf8');
|
|
93
|
+
const received = Buffer.from(signature, 'utf8');
|
|
94
|
+
if (expected.length !== received.length)
|
|
95
|
+
return false;
|
|
96
|
+
return (0, node_crypto_1.timingSafeEqual)(expected, received);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
exports.LocalStorageProvider = LocalStorageProvider;
|
|
100
|
+
//# sourceMappingURL=local.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local.js","sourceRoot":"","sources":["../../../src/storage/local.ts"],"names":[],"mappings":";;;AAAA,6CAA0D;AAC1D,+CAAwE;AACxE,yCAAmE;AACnE,yCAQoB;AACpB,+CAA0C;AAE1C;;;;;;;;;GASG;AACH,MAAa,oBAAoB;IACtB,GAAG,GAAG,OAAgB,CAAC;IACf,IAAI,CAAS;IACb,aAAa,CAAS;IAEvC,YAAY,OAAmD;QAC7D,IAAI,CAAC,IAAI,GAAG,IAAA,mBAAO,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAC7C,CAAC;IAED;;;;;OAKG;IACK,OAAO,CAAC,GAAW;QACzB,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,uBAAY,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,IAAA,mBAAO,EAAC,IAAA,gBAAI,EAAC,IAAI,CAAC,IAAI,EAAE,IAAA,qBAAS,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACxD,IAAI,MAAM,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,eAAG,CAAC,EAAE,CAAC;YAChE,MAAM,IAAI,uBAAY,CAAC,+BAA+B,EAAE,SAAS,CAAC,CAAC;QACrE,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAAqB;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACvC,MAAM,IAAA,gBAAK,EAAC,IAAA,mBAAO,EAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,MAAM,IAAA,oBAAS,EAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACpC,OAAO;YACL,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,cAAc,EAAE,IAAA,uBAAS,EAAC,KAAK,CAAC,IAAI,CAAC;YACrC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU;SACjC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,GAAW,EAAE,OAA0B;QACxD,MAAM,GAAG,GAAG,OAAO,EAAE,gBAAgB,IAAI,yCAA8B,CAAC;QACxE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC;QACtD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;QACxF,IAAI,OAAO,EAAE,gBAAgB;YAAE,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAChF,OAAO,sBAAsB,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAW;QACpB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAA,eAAI,EAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3C,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,IAAA,aAAE,EAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,6EAA6E;IAC7E,KAAK,CAAC,IAAI,CAAC,GAAW;QACpB,IAAI,CAAC;YACH,OAAO,IAAI,UAAU,CAAC,MAAM,IAAA,mBAAQ,EAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,uBAAY,CAAC,uBAAuB,EAAE,WAAW,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAEO,IAAI,CAAC,GAAW,EAAE,SAAiB;QACzC,OAAO,IAAA,wBAAU,EAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9F,CAAC;IAED;;;OAGG;IACH,eAAe,CAAC,GAAW,EAAE,SAAiB,EAAE,SAAiB;QAC/D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QAC3F,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;QAChE,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAChD,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QACtD,OAAO,IAAA,6BAAe,EAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;CACF;AAlFD,oDAkFC"}
|