@baruk/core 0.4.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.baruk-provenance.json +4 -4
- package/CHANGELOG.md +42 -0
- package/dist/audit/repository.d.ts +33 -1
- package/dist/audit/repository.d.ts.map +1 -1
- package/dist/audit/repository.js +41 -7
- package/dist/audit/repository.js.map +1 -1
- package/dist/auth/service.d.ts +21 -0
- package/dist/auth/service.d.ts.map +1 -1
- package/dist/auth/service.js +46 -1
- package/dist/auth/service.js.map +1 -1
- package/dist/billing/ar-repository.d.ts +41 -1
- package/dist/billing/ar-repository.d.ts.map +1 -1
- package/dist/billing/ar-repository.js +82 -6
- package/dist/billing/ar-repository.js.map +1 -1
- package/dist/billing/provider-account.d.ts +38 -0
- package/dist/billing/provider-account.d.ts.map +1 -1
- package/dist/billing/provider-account.js +58 -2
- package/dist/billing/provider-account.js.map +1 -1
- package/dist/billing/repository.d.ts +44 -0
- package/dist/billing/repository.d.ts.map +1 -1
- package/dist/billing/repository.js +49 -5
- package/dist/billing/repository.js.map +1 -1
- package/dist/cjs/audit/repository.js +41 -7
- package/dist/cjs/audit/repository.js.map +1 -1
- package/dist/cjs/auth/service.js +46 -1
- package/dist/cjs/auth/service.js.map +1 -1
- package/dist/cjs/billing/ar-repository.js +82 -6
- package/dist/cjs/billing/ar-repository.js.map +1 -1
- package/dist/cjs/billing/provider-account.js +60 -1
- package/dist/cjs/billing/provider-account.js.map +1 -1
- package/dist/cjs/billing/repository.js +51 -5
- package/dist/cjs/billing/repository.js.map +1 -1
- package/dist/cjs/clients/ibge.js +117 -0
- package/dist/cjs/clients/ibge.js.map +1 -0
- package/dist/cjs/clients/registry/http.js +157 -0
- package/dist/cjs/clients/registry/http.js.map +1 -0
- package/dist/cjs/clients/registry/ibge-municipios.js +28 -0
- package/dist/cjs/clients/registry/ibge-municipios.js.map +1 -0
- package/dist/cjs/clients/registry/ibge.js +63 -0
- package/dist/cjs/clients/registry/ibge.js.map +1 -0
- package/dist/cjs/clients/registry/lookup.js +191 -0
- package/dist/cjs/clients/registry/lookup.js.map +1 -0
- package/dist/cjs/clients/registry/provider.js +34 -0
- package/dist/cjs/clients/registry/provider.js.map +1 -0
- package/dist/cjs/clients/registry/resolve.js +47 -0
- package/dist/cjs/clients/registry/resolve.js.map +1 -0
- package/dist/cjs/clients/registry/serpro.js +149 -0
- package/dist/cjs/clients/registry/serpro.js.map +1 -0
- package/dist/cjs/clients/registry/service.js +230 -0
- package/dist/cjs/clients/registry/service.js.map +1 -0
- package/dist/cjs/clients/registry/synthetic.js +165 -0
- package/dist/cjs/clients/registry/synthetic.js.map +1 -0
- package/dist/cjs/clients/repository.js +190 -9
- package/dist/cjs/clients/repository.js.map +1 -1
- package/dist/cjs/collection/branding.js +190 -0
- package/dist/cjs/collection/branding.js.map +1 -1
- package/dist/cjs/collection/clearance-store.js +74 -0
- package/dist/cjs/collection/clearance-store.js.map +1 -0
- package/dist/cjs/collection/communication-runtime.js +65 -2
- package/dist/cjs/collection/communication-runtime.js.map +1 -1
- package/dist/cjs/collection/engine.js +20 -0
- package/dist/cjs/collection/engine.js.map +1 -1
- package/dist/cjs/collection/policy.js +29 -1
- package/dist/cjs/collection/policy.js.map +1 -1
- package/dist/cjs/communication/clearance.js +18 -0
- package/dist/cjs/communication/clearance.js.map +1 -0
- package/dist/cjs/communication/dry-run-scenario.js +5 -0
- package/dist/cjs/communication/dry-run-scenario.js.map +1 -1
- package/dist/cjs/communication/engine.js +12 -0
- package/dist/cjs/communication/engine.js.map +1 -1
- package/dist/cjs/communication/policy.js.map +1 -1
- package/dist/cjs/competence/business-days.js +155 -0
- package/dist/cjs/competence/business-days.js.map +1 -0
- package/dist/cjs/competence/catalog-validation.js +174 -0
- package/dist/cjs/competence/catalog-validation.js.map +1 -0
- package/dist/cjs/competence/obligation-preview.js +190 -0
- package/dist/cjs/competence/obligation-preview.js.map +1 -0
- package/dist/cjs/competence/repository.js +330 -17
- package/dist/cjs/competence/repository.js.map +1 -1
- package/dist/cjs/dashboard/pilot-panel.js +90 -0
- package/dist/cjs/dashboard/pilot-panel.js.map +1 -0
- package/dist/cjs/dashboard/repository.js +11 -1
- package/dist/cjs/dashboard/repository.js.map +1 -1
- package/dist/cjs/db/client.js +17 -11
- package/dist/cjs/db/client.js.map +1 -1
- package/dist/cjs/db/provision-e2e-identity.js +116 -0
- package/dist/cjs/db/provision-e2e-identity.js.map +1 -0
- package/dist/cjs/fiscal/applicability.js +164 -0
- package/dist/cjs/fiscal/applicability.js.map +1 -0
- package/dist/cjs/fiscal/collection/authorization.js +186 -0
- package/dist/cjs/fiscal/collection/authorization.js.map +1 -0
- package/dist/cjs/fiscal/collection/competence.js +97 -0
- package/dist/cjs/fiscal/collection/competence.js.map +1 -0
- package/dist/cjs/fiscal/collection/first-contact.js +204 -0
- package/dist/cjs/fiscal/collection/first-contact.js.map +1 -0
- package/dist/cjs/fiscal/collection/plan.js +122 -0
- package/dist/cjs/fiscal/collection/plan.js.map +1 -0
- package/dist/cjs/fiscal/conditions.js +198 -0
- package/dist/cjs/fiscal/conditions.js.map +1 -0
- package/dist/cjs/fiscal/contracts/nfse-adn-contract.js +390 -0
- package/dist/cjs/fiscal/contracts/nfse-adn-contract.js.map +1 -0
- package/dist/cjs/fiscal/contracts/nfse-adn-endpoint.js +108 -0
- package/dist/cjs/fiscal/contracts/nfse-adn-endpoint.js.map +1 -0
- package/dist/cjs/fiscal/contracts/nfse-adn-envelope.js +220 -0
- package/dist/cjs/fiscal/contracts/nfse-adn-envelope.js.map +1 -0
- package/dist/cjs/fiscal/coverage/model.js +137 -0
- package/dist/cjs/fiscal/coverage/model.js.map +1 -0
- package/dist/cjs/fiscal/coverage/requests.js +99 -0
- package/dist/cjs/fiscal/coverage/requests.js.map +1 -0
- package/dist/cjs/fiscal/credentials/inspect.js +182 -0
- package/dist/cjs/fiscal/credentials/inspect.js.map +1 -0
- package/dist/cjs/fiscal/credentials/material.js +168 -0
- package/dist/cjs/fiscal/credentials/material.js.map +1 -0
- package/dist/cjs/fiscal/credentials/onboarding.js +266 -0
- package/dist/cjs/fiscal/credentials/onboarding.js.map +1 -0
- package/dist/cjs/fiscal/credentials/readiness.js +190 -0
- package/dist/cjs/fiscal/credentials/readiness.js.map +1 -0
- package/dist/cjs/fiscal/eligibility.js +199 -0
- package/dist/cjs/fiscal/eligibility.js.map +1 -0
- package/dist/cjs/fiscal/enrollment.js +134 -0
- package/dist/cjs/fiscal/enrollment.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/__fixtures__/nfse.js +128 -0
- package/dist/cjs/fiscal/ingestion/__fixtures__/nfse.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/adn-transport.js +229 -0
- package/dist/cjs/fiscal/ingestion/adn-transport.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/direction.js +36 -0
- package/dist/cjs/fiscal/ingestion/direction.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/nfse-adn.js +228 -0
- package/dist/cjs/fiscal/ingestion/nfse-adn.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/pipeline.js +704 -0
- package/dist/cjs/fiscal/ingestion/pipeline.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/provider.js +51 -0
- package/dist/cjs/fiscal/ingestion/provider.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/repository.js +132 -0
- package/dist/cjs/fiscal/ingestion/repository.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/synthetic-provider.js +103 -0
- package/dist/cjs/fiscal/ingestion/synthetic-provider.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/synthetic-transport-types.js +13 -0
- package/dist/cjs/fiscal/ingestion/synthetic-transport-types.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/synthetic-transport.js +61 -0
- package/dist/cjs/fiscal/ingestion/synthetic-transport.js.map +1 -0
- package/dist/cjs/fiscal/ingestion/xml-reader.js +121 -0
- package/dist/cjs/fiscal/ingestion/xml-reader.js.map +1 -0
- package/dist/cjs/fiscal/repository.js +470 -0
- package/dist/cjs/fiscal/repository.js.map +1 -0
- package/dist/cjs/fiscal/sync/circuit.js +124 -0
- package/dist/cjs/fiscal/sync/circuit.js.map +1 -0
- package/dist/cjs/fiscal/sync/intervention.js +140 -0
- package/dist/cjs/fiscal/sync/intervention.js.map +1 -0
- package/dist/cjs/fiscal/sync/lease.js +146 -0
- package/dist/cjs/fiscal/sync/lease.js.map +1 -0
- package/dist/cjs/fiscal/sync/observability.js +244 -0
- package/dist/cjs/fiscal/sync/observability.js.map +1 -0
- package/dist/cjs/fiscal/sync/orchestrator.js +490 -0
- package/dist/cjs/fiscal/sync/orchestrator.js.map +1 -0
- package/dist/cjs/fiscal/sync/policy.js +143 -0
- package/dist/cjs/fiscal/sync/policy.js.map +1 -0
- package/dist/cjs/fiscal/sync/reprocess.js +241 -0
- package/dist/cjs/fiscal/sync/reprocess.js.map +1 -0
- package/dist/cjs/fiscal/sync/retry.js +183 -0
- package/dist/cjs/fiscal/sync/retry.js.map +1 -0
- package/dist/cjs/fiscal/sync/secret-boundary.js +123 -0
- package/dist/cjs/fiscal/sync/secret-boundary.js.map +1 -0
- package/dist/cjs/fiscal/transport/https.js +309 -0
- package/dist/cjs/fiscal/transport/https.js.map +1 -0
- package/dist/cjs/fiscal/transport/synthetic-tls.js +380 -0
- package/dist/cjs/fiscal/transport/synthetic-tls.js.map +1 -0
- package/dist/cjs/fiscal/transport/types.js +93 -0
- package/dist/cjs/fiscal/transport/types.js.map +1 -0
- package/dist/cjs/import/br-documents.js +85 -0
- package/dist/cjs/import/br-documents.js.map +1 -0
- package/dist/cjs/import/clients-import.js +347 -40
- package/dist/cjs/import/clients-import.js.map +1 -1
- package/dist/cjs/index.js +461 -73
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/legal/documents.js +164 -19
- package/dist/cjs/legal/documents.js.map +1 -1
- package/dist/cjs/legal/index.js +3 -1
- package/dist/cjs/legal/index.js.map +1 -1
- package/dist/cjs/legal/types.js.map +1 -1
- package/dist/cjs/onboarding/persistence.js +4 -4
- package/dist/cjs/onboarding/persistence.js.map +1 -1
- package/dist/cjs/pilot/go-live-checklist.js +212 -0
- package/dist/cjs/pilot/go-live-checklist.js.map +1 -0
- package/dist/cjs/pilot/milestone.js +79 -0
- package/dist/cjs/pilot/milestone.js.map +1 -0
- package/dist/cjs/platform/capabilities.js +173 -0
- package/dist/cjs/platform/capabilities.js.map +1 -0
- package/dist/cjs/platform/job-contract.js +411 -0
- package/dist/cjs/platform/job-contract.js.map +1 -0
- package/dist/cjs/rbac/catalog.js +110 -0
- package/dist/cjs/rbac/catalog.js.map +1 -1
- package/dist/cjs/subscription-billing/index.js +9 -1
- package/dist/cjs/subscription-billing/index.js.map +1 -1
- package/dist/cjs/subscription-billing/platform-exemption.js +121 -0
- package/dist/cjs/subscription-billing/platform-exemption.js.map +1 -0
- package/dist/cjs/subscription-billing/service.js +246 -78
- package/dist/cjs/subscription-billing/service.js.map +1 -1
- package/dist/cjs/tenancy/features.js +131 -0
- package/dist/cjs/tenancy/features.js.map +1 -0
- package/dist/cjs/tenancy/settings.js +224 -0
- package/dist/cjs/tenancy/settings.js.map +1 -0
- package/dist/cjs/users/repository.js +24 -1
- package/dist/cjs/users/repository.js.map +1 -1
- package/dist/cjs/vault/repository.js +92 -5
- package/dist/cjs/vault/repository.js.map +1 -1
- package/dist/clients/ibge.d.ts +17 -0
- package/dist/clients/ibge.d.ts.map +1 -0
- package/dist/clients/ibge.js +112 -0
- package/dist/clients/ibge.js.map +1 -0
- package/dist/clients/registry/http.d.ts +61 -0
- package/dist/clients/registry/http.d.ts.map +1 -0
- package/dist/clients/registry/http.js +151 -0
- package/dist/clients/registry/http.js.map +1 -0
- package/dist/clients/registry/ibge-municipios.d.ts +25 -0
- package/dist/clients/registry/ibge-municipios.d.ts.map +1 -0
- package/dist/clients/registry/ibge-municipios.js +25 -0
- package/dist/clients/registry/ibge-municipios.js.map +1 -0
- package/dist/clients/registry/ibge.d.ts +62 -0
- package/dist/clients/registry/ibge.d.ts.map +1 -0
- package/dist/clients/registry/ibge.js +57 -0
- package/dist/clients/registry/ibge.js.map +1 -0
- package/dist/clients/registry/lookup.d.ts +94 -0
- package/dist/clients/registry/lookup.d.ts.map +1 -0
- package/dist/clients/registry/lookup.js +184 -0
- package/dist/clients/registry/lookup.js.map +1 -0
- package/dist/clients/registry/provider.d.ts +124 -0
- package/dist/clients/registry/provider.d.ts.map +1 -0
- package/dist/clients/registry/provider.js +39 -0
- package/dist/clients/registry/provider.js.map +1 -0
- package/dist/clients/registry/resolve.d.ts +36 -0
- package/dist/clients/registry/resolve.d.ts.map +1 -0
- package/dist/clients/registry/resolve.js +44 -0
- package/dist/clients/registry/resolve.js.map +1 -0
- package/dist/clients/registry/serpro.d.ts +57 -0
- package/dist/clients/registry/serpro.d.ts.map +1 -0
- package/dist/clients/registry/serpro.js +143 -0
- package/dist/clients/registry/serpro.js.map +1 -0
- package/dist/clients/registry/service.d.ts +59 -0
- package/dist/clients/registry/service.d.ts.map +1 -0
- package/dist/clients/registry/service.js +225 -0
- package/dist/clients/registry/service.js.map +1 -0
- package/dist/clients/registry/synthetic.d.ts +30 -0
- package/dist/clients/registry/synthetic.d.ts.map +1 -0
- package/dist/clients/registry/synthetic.js +161 -0
- package/dist/clients/registry/synthetic.js.map +1 -0
- package/dist/clients/repository.d.ts +158 -0
- package/dist/clients/repository.d.ts.map +1 -1
- package/dist/clients/repository.js +186 -9
- package/dist/clients/repository.js.map +1 -1
- package/dist/collection/branding.d.ts +65 -0
- package/dist/collection/branding.d.ts.map +1 -1
- package/dist/collection/branding.js +186 -0
- package/dist/collection/branding.js.map +1 -1
- package/dist/collection/clearance-store.d.ts +39 -0
- package/dist/collection/clearance-store.d.ts.map +1 -0
- package/dist/collection/clearance-store.js +69 -0
- package/dist/collection/clearance-store.js.map +1 -0
- package/dist/collection/communication-runtime.d.ts +37 -0
- package/dist/collection/communication-runtime.d.ts.map +1 -1
- package/dist/collection/communication-runtime.js +63 -1
- package/dist/collection/communication-runtime.js.map +1 -1
- package/dist/collection/engine.d.ts +23 -0
- package/dist/collection/engine.d.ts.map +1 -1
- package/dist/collection/engine.js +20 -0
- package/dist/collection/engine.js.map +1 -1
- package/dist/collection/policy.d.ts +25 -0
- package/dist/collection/policy.d.ts.map +1 -1
- package/dist/collection/policy.js +27 -0
- package/dist/collection/policy.js.map +1 -1
- package/dist/communication/clearance.d.ts +53 -0
- package/dist/communication/clearance.d.ts.map +1 -0
- package/dist/communication/clearance.js +15 -0
- package/dist/communication/clearance.js.map +1 -0
- package/dist/communication/dry-run-scenario.d.ts.map +1 -1
- package/dist/communication/dry-run-scenario.js +5 -0
- package/dist/communication/dry-run-scenario.js.map +1 -1
- package/dist/communication/engine.d.ts +10 -0
- package/dist/communication/engine.d.ts.map +1 -1
- package/dist/communication/engine.js +12 -0
- package/dist/communication/engine.js.map +1 -1
- package/dist/communication/policy.d.ts +16 -0
- package/dist/communication/policy.d.ts.map +1 -1
- package/dist/communication/policy.js.map +1 -1
- package/dist/competence/business-days.d.ts +51 -0
- package/dist/competence/business-days.d.ts.map +1 -0
- package/dist/competence/business-days.js +145 -0
- package/dist/competence/business-days.js.map +1 -0
- package/dist/competence/catalog-validation.d.ts +86 -0
- package/dist/competence/catalog-validation.d.ts.map +1 -0
- package/dist/competence/catalog-validation.js +168 -0
- package/dist/competence/catalog-validation.js.map +1 -0
- package/dist/competence/obligation-preview.d.ts +103 -0
- package/dist/competence/obligation-preview.d.ts.map +1 -0
- package/dist/competence/obligation-preview.js +184 -0
- package/dist/competence/obligation-preview.js.map +1 -0
- package/dist/competence/repository.d.ts +139 -1
- package/dist/competence/repository.d.ts.map +1 -1
- package/dist/competence/repository.js +325 -17
- package/dist/competence/repository.js.map +1 -1
- package/dist/dashboard/pilot-panel.d.ts +100 -0
- package/dist/dashboard/pilot-panel.d.ts.map +1 -0
- package/dist/dashboard/pilot-panel.js +87 -0
- package/dist/dashboard/pilot-panel.js.map +1 -0
- package/dist/dashboard/repository.d.ts.map +1 -1
- package/dist/dashboard/repository.js +11 -1
- package/dist/dashboard/repository.js.map +1 -1
- package/dist/db/client.d.ts +45 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +16 -11
- package/dist/db/client.js.map +1 -1
- package/dist/db/migrate.d.ts +36 -1
- package/dist/db/migrate.d.ts.map +1 -1
- package/dist/db/migrate.js +199 -32
- package/dist/db/migrate.js.map +1 -1
- package/dist/db/provision-e2e-identity.d.ts +2 -0
- package/dist/db/provision-e2e-identity.d.ts.map +1 -0
- package/dist/db/provision-e2e-identity.js +114 -0
- package/dist/db/provision-e2e-identity.js.map +1 -0
- package/dist/fiscal/applicability.d.ts +73 -0
- package/dist/fiscal/applicability.d.ts.map +1 -0
- package/dist/fiscal/applicability.js +160 -0
- package/dist/fiscal/applicability.js.map +1 -0
- package/dist/fiscal/collection/authorization.d.ts +152 -0
- package/dist/fiscal/collection/authorization.d.ts.map +1 -0
- package/dist/fiscal/collection/authorization.js +178 -0
- package/dist/fiscal/collection/authorization.js.map +1 -0
- package/dist/fiscal/collection/competence.d.ts +66 -0
- package/dist/fiscal/collection/competence.d.ts.map +1 -0
- package/dist/fiscal/collection/competence.js +90 -0
- package/dist/fiscal/collection/competence.js.map +1 -0
- package/dist/fiscal/collection/first-contact.d.ts +103 -0
- package/dist/fiscal/collection/first-contact.d.ts.map +1 -0
- package/dist/fiscal/collection/first-contact.js +201 -0
- package/dist/fiscal/collection/first-contact.js.map +1 -0
- package/dist/fiscal/collection/plan.d.ts +74 -0
- package/dist/fiscal/collection/plan.d.ts.map +1 -0
- package/dist/fiscal/collection/plan.js +119 -0
- package/dist/fiscal/collection/plan.js.map +1 -0
- package/dist/fiscal/conditions.d.ts +99 -0
- package/dist/fiscal/conditions.d.ts.map +1 -0
- package/dist/fiscal/conditions.js +190 -0
- package/dist/fiscal/conditions.js.map +1 -0
- package/dist/fiscal/contracts/nfse-adn-contract.d.ts +315 -0
- package/dist/fiscal/contracts/nfse-adn-contract.d.ts.map +1 -0
- package/dist/fiscal/contracts/nfse-adn-contract.js +386 -0
- package/dist/fiscal/contracts/nfse-adn-contract.js.map +1 -0
- package/dist/fiscal/contracts/nfse-adn-endpoint.d.ts +13 -0
- package/dist/fiscal/contracts/nfse-adn-endpoint.d.ts.map +1 -0
- package/dist/fiscal/contracts/nfse-adn-endpoint.js +103 -0
- package/dist/fiscal/contracts/nfse-adn-endpoint.js.map +1 -0
- package/dist/fiscal/contracts/nfse-adn-envelope.d.ts +77 -0
- package/dist/fiscal/contracts/nfse-adn-envelope.d.ts.map +1 -0
- package/dist/fiscal/contracts/nfse-adn-envelope.js +215 -0
- package/dist/fiscal/contracts/nfse-adn-envelope.js.map +1 -0
- package/dist/fiscal/coverage/model.d.ts +114 -0
- package/dist/fiscal/coverage/model.d.ts.map +1 -0
- package/dist/fiscal/coverage/model.js +130 -0
- package/dist/fiscal/coverage/model.js.map +1 -0
- package/dist/fiscal/coverage/requests.d.ts +70 -0
- package/dist/fiscal/coverage/requests.d.ts.map +1 -0
- package/dist/fiscal/coverage/requests.js +95 -0
- package/dist/fiscal/coverage/requests.js.map +1 -0
- package/dist/fiscal/credentials/inspect.d.ts +114 -0
- package/dist/fiscal/credentials/inspect.d.ts.map +1 -0
- package/dist/fiscal/credentials/inspect.js +178 -0
- package/dist/fiscal/credentials/inspect.js.map +1 -0
- package/dist/fiscal/credentials/material.d.ts +81 -0
- package/dist/fiscal/credentials/material.d.ts.map +1 -0
- package/dist/fiscal/credentials/material.js +164 -0
- package/dist/fiscal/credentials/material.js.map +1 -0
- package/dist/fiscal/credentials/onboarding.d.ts +119 -0
- package/dist/fiscal/credentials/onboarding.d.ts.map +1 -0
- package/dist/fiscal/credentials/onboarding.js +259 -0
- package/dist/fiscal/credentials/onboarding.js.map +1 -0
- package/dist/fiscal/credentials/readiness.d.ts +119 -0
- package/dist/fiscal/credentials/readiness.d.ts.map +1 -0
- package/dist/fiscal/credentials/readiness.js +186 -0
- package/dist/fiscal/credentials/readiness.js.map +1 -0
- package/dist/fiscal/eligibility.d.ts +106 -0
- package/dist/fiscal/eligibility.d.ts.map +1 -0
- package/dist/fiscal/eligibility.js +194 -0
- package/dist/fiscal/eligibility.js.map +1 -0
- package/dist/fiscal/enrollment.d.ts +91 -0
- package/dist/fiscal/enrollment.d.ts.map +1 -0
- package/dist/fiscal/enrollment.js +126 -0
- package/dist/fiscal/enrollment.js.map +1 -0
- package/dist/fiscal/ingestion/__fixtures__/nfse.d.ts +57 -0
- package/dist/fiscal/ingestion/__fixtures__/nfse.d.ts.map +1 -0
- package/dist/fiscal/ingestion/__fixtures__/nfse.js +121 -0
- package/dist/fiscal/ingestion/__fixtures__/nfse.js.map +1 -0
- package/dist/fiscal/ingestion/adn-transport.d.ts +123 -0
- package/dist/fiscal/ingestion/adn-transport.d.ts.map +1 -0
- package/dist/fiscal/ingestion/adn-transport.js +220 -0
- package/dist/fiscal/ingestion/adn-transport.js.map +1 -0
- package/dist/fiscal/ingestion/direction.d.ts +60 -0
- package/dist/fiscal/ingestion/direction.d.ts.map +1 -0
- package/dist/fiscal/ingestion/direction.js +32 -0
- package/dist/fiscal/ingestion/direction.js.map +1 -0
- package/dist/fiscal/ingestion/nfse-adn.d.ts +91 -0
- package/dist/fiscal/ingestion/nfse-adn.d.ts.map +1 -0
- package/dist/fiscal/ingestion/nfse-adn.js +222 -0
- package/dist/fiscal/ingestion/nfse-adn.js.map +1 -0
- package/dist/fiscal/ingestion/pipeline.d.ts +168 -0
- package/dist/fiscal/ingestion/pipeline.d.ts.map +1 -0
- package/dist/fiscal/ingestion/pipeline.js +699 -0
- package/dist/fiscal/ingestion/pipeline.js.map +1 -0
- package/dist/fiscal/ingestion/provider.d.ts +206 -0
- package/dist/fiscal/ingestion/provider.d.ts.map +1 -0
- package/dist/fiscal/ingestion/provider.js +47 -0
- package/dist/fiscal/ingestion/provider.js.map +1 -0
- package/dist/fiscal/ingestion/repository.d.ts +82 -0
- package/dist/fiscal/ingestion/repository.d.ts.map +1 -0
- package/dist/fiscal/ingestion/repository.js +127 -0
- package/dist/fiscal/ingestion/repository.js.map +1 -0
- package/dist/fiscal/ingestion/synthetic-provider.d.ts +92 -0
- package/dist/fiscal/ingestion/synthetic-provider.d.ts.map +1 -0
- package/dist/fiscal/ingestion/synthetic-provider.js +99 -0
- package/dist/fiscal/ingestion/synthetic-provider.js.map +1 -0
- package/dist/fiscal/ingestion/synthetic-transport-types.d.ts +19 -0
- package/dist/fiscal/ingestion/synthetic-transport-types.d.ts.map +1 -0
- package/dist/fiscal/ingestion/synthetic-transport-types.js +9 -0
- package/dist/fiscal/ingestion/synthetic-transport-types.js.map +1 -0
- package/dist/fiscal/ingestion/synthetic-transport.d.ts +55 -0
- package/dist/fiscal/ingestion/synthetic-transport.d.ts.map +1 -0
- package/dist/fiscal/ingestion/synthetic-transport.js +57 -0
- package/dist/fiscal/ingestion/synthetic-transport.js.map +1 -0
- package/dist/fiscal/ingestion/xml-reader.d.ts +55 -0
- package/dist/fiscal/ingestion/xml-reader.d.ts.map +1 -0
- package/dist/fiscal/ingestion/xml-reader.js +112 -0
- package/dist/fiscal/ingestion/xml-reader.js.map +1 -0
- package/dist/fiscal/repository.d.ts +220 -0
- package/dist/fiscal/repository.d.ts.map +1 -0
- package/dist/fiscal/repository.js +449 -0
- package/dist/fiscal/repository.js.map +1 -0
- package/dist/fiscal/sync/circuit.d.ts +86 -0
- package/dist/fiscal/sync/circuit.d.ts.map +1 -0
- package/dist/fiscal/sync/circuit.js +118 -0
- package/dist/fiscal/sync/circuit.js.map +1 -0
- package/dist/fiscal/sync/intervention.d.ts +81 -0
- package/dist/fiscal/sync/intervention.d.ts.map +1 -0
- package/dist/fiscal/sync/intervention.js +135 -0
- package/dist/fiscal/sync/intervention.js.map +1 -0
- package/dist/fiscal/sync/lease.d.ts +118 -0
- package/dist/fiscal/sync/lease.d.ts.map +1 -0
- package/dist/fiscal/sync/lease.js +139 -0
- package/dist/fiscal/sync/lease.js.map +1 -0
- package/dist/fiscal/sync/observability.d.ts +148 -0
- package/dist/fiscal/sync/observability.d.ts.map +1 -0
- package/dist/fiscal/sync/observability.js +239 -0
- package/dist/fiscal/sync/observability.js.map +1 -0
- package/dist/fiscal/sync/orchestrator.d.ts +132 -0
- package/dist/fiscal/sync/orchestrator.d.ts.map +1 -0
- package/dist/fiscal/sync/orchestrator.js +487 -0
- package/dist/fiscal/sync/orchestrator.js.map +1 -0
- package/dist/fiscal/sync/policy.d.ts +87 -0
- package/dist/fiscal/sync/policy.d.ts.map +1 -0
- package/dist/fiscal/sync/policy.js +136 -0
- package/dist/fiscal/sync/policy.js.map +1 -0
- package/dist/fiscal/sync/reprocess.d.ts +76 -0
- package/dist/fiscal/sync/reprocess.d.ts.map +1 -0
- package/dist/fiscal/sync/reprocess.js +237 -0
- package/dist/fiscal/sync/reprocess.js.map +1 -0
- package/dist/fiscal/sync/retry.d.ts +82 -0
- package/dist/fiscal/sync/retry.d.ts.map +1 -0
- package/dist/fiscal/sync/retry.js +176 -0
- package/dist/fiscal/sync/retry.js.map +1 -0
- package/dist/fiscal/sync/secret-boundary.d.ts +169 -0
- package/dist/fiscal/sync/secret-boundary.d.ts.map +1 -0
- package/dist/fiscal/sync/secret-boundary.js +116 -0
- package/dist/fiscal/sync/secret-boundary.js.map +1 -0
- package/dist/fiscal/transport/https.d.ts +86 -0
- package/dist/fiscal/transport/https.d.ts.map +1 -0
- package/dist/fiscal/transport/https.js +303 -0
- package/dist/fiscal/transport/https.js.map +1 -0
- package/dist/fiscal/transport/synthetic-tls.d.ts +99 -0
- package/dist/fiscal/transport/synthetic-tls.d.ts.map +1 -0
- package/dist/fiscal/transport/synthetic-tls.js +374 -0
- package/dist/fiscal/transport/synthetic-tls.js.map +1 -0
- package/dist/fiscal/transport/types.d.ts +134 -0
- package/dist/fiscal/transport/types.d.ts.map +1 -0
- package/dist/fiscal/transport/types.js +88 -0
- package/dist/fiscal/transport/types.js.map +1 -0
- package/dist/import/br-documents.d.ts +26 -0
- package/dist/import/br-documents.d.ts.map +1 -0
- package/dist/import/br-documents.js +78 -0
- package/dist/import/br-documents.js.map +1 -0
- package/dist/import/clients-import.d.ts +122 -4
- package/dist/import/clients-import.d.ts.map +1 -1
- package/dist/import/clients-import.js +341 -41
- package/dist/import/clients-import.js.map +1 -1
- package/dist/index.d.ts +145 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +120 -7
- package/dist/index.js.map +1 -1
- package/dist/legal/documents.d.ts +12 -1
- package/dist/legal/documents.d.ts.map +1 -1
- package/dist/legal/documents.js +162 -18
- package/dist/legal/documents.js.map +1 -1
- package/dist/legal/index.d.ts +2 -2
- package/dist/legal/index.d.ts.map +1 -1
- package/dist/legal/index.js +1 -1
- package/dist/legal/index.js.map +1 -1
- package/dist/legal/types.d.ts +114 -2
- package/dist/legal/types.d.ts.map +1 -1
- package/dist/legal/types.js.map +1 -1
- package/dist/onboarding/persistence.d.ts +10 -1
- package/dist/onboarding/persistence.d.ts.map +1 -1
- package/dist/onboarding/persistence.js +4 -4
- package/dist/onboarding/persistence.js.map +1 -1
- package/dist/pilot/go-live-checklist.d.ts +41 -0
- package/dist/pilot/go-live-checklist.d.ts.map +1 -0
- package/dist/pilot/go-live-checklist.js +209 -0
- package/dist/pilot/go-live-checklist.js.map +1 -0
- package/dist/pilot/milestone.d.ts +56 -0
- package/dist/pilot/milestone.d.ts.map +1 -0
- package/dist/pilot/milestone.js +74 -0
- package/dist/pilot/milestone.js.map +1 -0
- package/dist/platform/capabilities.d.ts +88 -0
- package/dist/platform/capabilities.d.ts.map +1 -0
- package/dist/platform/capabilities.js +169 -0
- package/dist/platform/capabilities.js.map +1 -0
- package/dist/platform/job-contract.d.ts +232 -0
- package/dist/platform/job-contract.d.ts.map +1 -0
- package/dist/platform/job-contract.js +403 -0
- package/dist/platform/job-contract.js.map +1 -0
- package/dist/rbac/catalog.d.ts.map +1 -1
- package/dist/rbac/catalog.js +110 -0
- package/dist/rbac/catalog.js.map +1 -1
- package/dist/subscription-billing/index.d.ts +8 -5
- package/dist/subscription-billing/index.d.ts.map +1 -1
- package/dist/subscription-billing/index.js +4 -3
- package/dist/subscription-billing/index.js.map +1 -1
- package/dist/subscription-billing/platform-exemption.d.ts +89 -0
- package/dist/subscription-billing/platform-exemption.d.ts.map +1 -0
- package/dist/subscription-billing/platform-exemption.js +113 -0
- package/dist/subscription-billing/platform-exemption.js.map +1 -0
- package/dist/subscription-billing/service.d.ts +74 -0
- package/dist/subscription-billing/service.d.ts.map +1 -1
- package/dist/subscription-billing/service.js +182 -16
- package/dist/subscription-billing/service.js.map +1 -1
- package/dist/tenancy/features.d.ts +69 -0
- package/dist/tenancy/features.d.ts.map +1 -0
- package/dist/tenancy/features.js +123 -0
- package/dist/tenancy/features.js.map +1 -0
- package/dist/tenancy/settings.d.ts +63 -0
- package/dist/tenancy/settings.d.ts.map +1 -0
- package/dist/tenancy/settings.js +218 -0
- package/dist/tenancy/settings.js.map +1 -0
- package/dist/users/repository.d.ts +16 -1
- package/dist/users/repository.d.ts.map +1 -1
- package/dist/users/repository.js +24 -1
- package/dist/users/repository.js.map +1 -1
- package/dist/vault/repository.d.ts +69 -1
- package/dist/vault/repository.d.ts.map +1 -1
- package/dist/vault/repository.js +88 -5
- package/dist/vault/repository.js.map +1 -1
- package/package.json +10 -2
- package/src/db/migrations/0045_role_write_scope.sql +122 -0
- package/src/db/migrations/0046_pilot_activation_model.sql +184 -0
- package/src/db/migrations/0047_recipient_clearance.sql +89 -0
- package/src/db/migrations/0048_item_type_note.sql +16 -0
- package/src/db/migrations/0049_national_fiscal_engine.sql +279 -0
- package/src/db/migrations/0050_fiscal_vocabulary_readonly.sql +29 -0
- package/src/db/migrations/0051_seed_rules_from_catalog.sql +72 -0
- package/src/db/migrations/0052_fiscal_rule_delete_scope.sql +57 -0
- package/src/db/migrations/0053_rule_validity_lower_bound.sql +44 -0
- package/src/db/migrations/0054_tenant_profile_and_rule_source.sql +89 -0
- package/src/db/migrations/0055_job_capability_contract.sql +300 -0
- package/src/db/migrations/0056_fiscal_document_ingestion.sql +337 -0
- package/src/db/migrations/0057_fiscal_pending_event_inbox.sql +228 -0
- package/src/db/migrations/0058_fiscal_operational_engine.sql +516 -0
- package/src/db/migrations/0059_fiscal_contract_version.sql +59 -0
- package/src/db/migrations/0060_fiscal_credential_vault_and_run_authorization.sql +321 -0
- package/src/db/migrations/0061_client_official_registry_provenance.sql +193 -0
- package/src/db/migrations/0062_first_contact_and_capability_truth.sql +119 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect.js","sourceRoot":"","sources":["../../../../src/fiscal/credentials/inspect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildTlsMaterial = buildTlsMaterial;
|
|
4
|
+
exports.loadFiscalTlsMaterial = loadFiscalTlsMaterial;
|
|
5
|
+
const node_crypto_1 = require("node:crypto");
|
|
6
|
+
const repository_js_1 = require("../../vault/repository.js");
|
|
7
|
+
const secret_boundary_js_1 = require("../sync/secret-boundary.js");
|
|
8
|
+
/**
|
|
9
|
+
* Constrói o material a partir do envelope decifrado.
|
|
10
|
+
*
|
|
11
|
+
* Separado da leitura do banco de propósito: é esta função que o teste
|
|
12
|
+
* exercita com um PKCS#12 sintético, sem precisar de cofre nem de tenant.
|
|
13
|
+
*/
|
|
14
|
+
function buildTlsMaterial(raw) {
|
|
15
|
+
let envelope;
|
|
16
|
+
try {
|
|
17
|
+
envelope = JSON.parse(raw);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// Sem `err.message`: um JSON malformado costuma vir citado inteiro na
|
|
21
|
+
// exceção, e o "JSON malformado" aqui é um certificado.
|
|
22
|
+
return { status: 'unavailable', reason: 'envelope_unreadable' };
|
|
23
|
+
}
|
|
24
|
+
if (!envelope || typeof envelope !== 'object' || !('format' in envelope)) {
|
|
25
|
+
return { status: 'unavailable', reason: 'envelope_unreadable' };
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
if (envelope.format === 'pkcs12') {
|
|
29
|
+
if (typeof envelope.material !== 'string' || envelope.material === '') {
|
|
30
|
+
return { status: 'unavailable', reason: 'envelope_unreadable' };
|
|
31
|
+
}
|
|
32
|
+
const pfx = Buffer.from(envelope.material, 'base64');
|
|
33
|
+
if (pfx.byteLength === 0)
|
|
34
|
+
return { status: 'unavailable', reason: 'envelope_unreadable' };
|
|
35
|
+
return { status: 'ok', material: sealed({ pfx, passphrase: envelope.passphrase }) };
|
|
36
|
+
}
|
|
37
|
+
if (envelope.format === 'pem') {
|
|
38
|
+
if (typeof envelope.cert !== 'string' || typeof envelope.key !== 'string') {
|
|
39
|
+
return { status: 'unavailable', reason: 'envelope_unreadable' };
|
|
40
|
+
}
|
|
41
|
+
const cert = Buffer.from(envelope.cert, 'base64');
|
|
42
|
+
const key = Buffer.from(envelope.key, 'base64');
|
|
43
|
+
const ca = (envelope.ca ?? []).map((c) => Buffer.from(c, 'base64'));
|
|
44
|
+
if (cert.byteLength === 0 || key.byteLength === 0) {
|
|
45
|
+
return { status: 'unavailable', reason: 'envelope_unreadable' };
|
|
46
|
+
}
|
|
47
|
+
return { status: 'ok', material: sealed({ cert, key, ca }) };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return { status: 'unavailable', reason: 'envelope_unreadable' };
|
|
52
|
+
}
|
|
53
|
+
return { status: 'unavailable', reason: 'unsupported_format' };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Embrulha os buffers com a impressão digital e com o descarte.
|
|
57
|
+
*
|
|
58
|
+
* A impressão é do material APRESENTADO (o `.pfx` ou o `cert`), nunca da chave
|
|
59
|
+
* privada: identificar qual certificado foi usado não deve exigir tocar no
|
|
60
|
+
* segredo, nem sequer para calcular um hash.
|
|
61
|
+
*/
|
|
62
|
+
function sealed(parts) {
|
|
63
|
+
const identity = parts.pfx ?? parts.cert ?? Buffer.alloc(0);
|
|
64
|
+
const fingerprintSha256 = (0, node_crypto_1.createHash)('sha256').update(identity).digest('hex');
|
|
65
|
+
let disposed = false;
|
|
66
|
+
return {
|
|
67
|
+
...(parts.pfx ? { pfx: parts.pfx } : {}),
|
|
68
|
+
...(parts.passphrase ? { passphrase: parts.passphrase } : {}),
|
|
69
|
+
...(parts.cert ? { cert: parts.cert } : {}),
|
|
70
|
+
...(parts.key ? { key: parts.key } : {}),
|
|
71
|
+
...(parts.ca && parts.ca.length > 0 ? { ca: parts.ca } : {}),
|
|
72
|
+
fingerprintSha256,
|
|
73
|
+
dispose() {
|
|
74
|
+
if (disposed)
|
|
75
|
+
return;
|
|
76
|
+
disposed = true;
|
|
77
|
+
// Zerar não é cerimônia: o Buffer sobrevive no heap até o GC passar, e um
|
|
78
|
+
// heap dump de produção é um arquivo que alguém abre e guarda.
|
|
79
|
+
parts.pfx?.fill(0);
|
|
80
|
+
parts.cert?.fill(0);
|
|
81
|
+
parts.key?.fill(0);
|
|
82
|
+
for (const c of parts.ca ?? [])
|
|
83
|
+
c.fill(0);
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Busca o material do certificado de um cliente.
|
|
89
|
+
*
|
|
90
|
+
* O ponteiro vem de `digital_certificate.vault_credential_id` — o MESMO domínio
|
|
91
|
+
* que a prontidão lê, e não uma segunda tabela de credencial fiscal. Duas
|
|
92
|
+
* origens para o mesmo fato divergiriam na primeira atualização de uma só.
|
|
93
|
+
*
|
|
94
|
+
* NUNCA lança por ausência: um cliente sem certificado é estado normal, e uma
|
|
95
|
+
* exceção aqui derrubaria o worker no meio da carteira por causa do primeiro
|
|
96
|
+
* cliente não configurado.
|
|
97
|
+
*
|
|
98
|
+
* ## O `authorization` não é decoração
|
|
99
|
+
*
|
|
100
|
+
* Esta é a única porta do produto para material de certificado, e ela agora
|
|
101
|
+
* EXIGE o passe que o orquestrador emite depois do último portão. Um chamador
|
|
102
|
+
* que tente abrir o cofre antes disso — para "só conferir se o certificado
|
|
103
|
+
* abre", que é sempre como começa — recebe `FiscalSecretBoundaryError` em vez de
|
|
104
|
+
* uma chave privada. Ver `sync/secret-boundary.ts`.
|
|
105
|
+
*
|
|
106
|
+
* A checagem lança ANTES do primeiro `SELECT`: nem a existência do ponteiro é
|
|
107
|
+
* revelada a quem não passou pelos portões.
|
|
108
|
+
*/
|
|
109
|
+
async function loadFiscalTlsMaterial(tx, keyring, tenantId, input) {
|
|
110
|
+
(0, secret_boundary_js_1.assertFiscalSecretAccess)(input.authorization, 'loadFiscalTlsMaterial');
|
|
111
|
+
/*
|
|
112
|
+
* O passe é AUTÊNTICO — mas para quem?
|
|
113
|
+
*
|
|
114
|
+
* `assertFiscalSecretAccess` responde "esta autorização saiu dos portões", e
|
|
115
|
+
* não "esta autorização é DESTE cliente". A diferença abre um caso que a RLS
|
|
116
|
+
* não fecha: dentro do MESMO escritório, um passe emitido para o cliente X
|
|
117
|
+
* abriria o certificado do cliente Y, porque a política de tenant considera as
|
|
118
|
+
* duas linhas visíveis. É o `WHERE client_id = ...` abaixo que escolhe a
|
|
119
|
+
* linha, e ele obedece ao parâmetro, não ao passe.
|
|
120
|
+
*
|
|
121
|
+
* Hoje o orquestrador emite e usa o passe no mesmo par (tenant, cliente), de
|
|
122
|
+
* modo que o caso não ocorre. Mas é exatamente esse tipo de invariante — "quem
|
|
123
|
+
* chama sempre passa os mesmos valores" — que um refactor quebra em silêncio,
|
|
124
|
+
* e o módulo inteiro da fronteira existe porque convenção não é portão.
|
|
125
|
+
*
|
|
126
|
+
* A checagem é de ESCOPO, e vem antes de qualquer consulta: um passe fora do
|
|
127
|
+
* seu escopo não chega nem a saber se existe certificado do outro lado.
|
|
128
|
+
*/
|
|
129
|
+
if (input.authorization.tenantId !== tenantId ||
|
|
130
|
+
input.authorization.clientId !== input.clientId) {
|
|
131
|
+
throw new secret_boundary_js_1.FiscalSecretBoundaryError('loadFiscalTlsMaterial:scope');
|
|
132
|
+
}
|
|
133
|
+
const certType = input.kind === 'certificate_a3' ? 'A3' : 'A1';
|
|
134
|
+
let rows;
|
|
135
|
+
try {
|
|
136
|
+
rows = await tx `
|
|
137
|
+
SELECT vault_credential_id
|
|
138
|
+
FROM digital_certificate
|
|
139
|
+
WHERE client_id = ${input.clientId}
|
|
140
|
+
AND cert_type = ${certType}
|
|
141
|
+
AND deleted_at IS NULL
|
|
142
|
+
ORDER BY expires_at DESC
|
|
143
|
+
LIMIT 1
|
|
144
|
+
`;
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
const code = err?.code;
|
|
148
|
+
if (code === '42P01' || code === '42703') {
|
|
149
|
+
return { status: 'unavailable', reason: 'no_credential' };
|
|
150
|
+
}
|
|
151
|
+
throw err;
|
|
152
|
+
}
|
|
153
|
+
const pointer = rows[0]?.vault_credential_id;
|
|
154
|
+
if (!pointer)
|
|
155
|
+
return { status: 'unavailable', reason: 'no_credential' };
|
|
156
|
+
let secret;
|
|
157
|
+
try {
|
|
158
|
+
({ secret } = await (0, repository_js_1.revealWriteOnlySecretForProcess)(tx, keyring, tenantId, pointer));
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
// Ponteiro pendurado, chave de cifra ausente, linha invisível sob RLS: os
|
|
162
|
+
// três colapsam em "não deu para abrir", e diferenciá-los aqui vazaria a
|
|
163
|
+
// existência de um registro que a RLS já respondeu como ausente.
|
|
164
|
+
return { status: 'unavailable', reason: 'vault_unavailable' };
|
|
165
|
+
}
|
|
166
|
+
return buildTlsMaterial(secret);
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=material.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"material.js","sourceRoot":"","sources":["../../../../src/fiscal/credentials/material.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fiscalCertificateCredentialName = fiscalCertificateCredentialName;
|
|
4
|
+
exports.onboardFiscalCertificate = onboardFiscalCertificate;
|
|
5
|
+
exports.listFiscalCertificates = listFiscalCertificates;
|
|
6
|
+
exports.revokeFiscalCertificate = revokeFiscalCertificate;
|
|
7
|
+
exports.materialFingerprint = materialFingerprint;
|
|
8
|
+
const node_crypto_1 = require("node:crypto");
|
|
9
|
+
const shared_1 = require("@baruk/shared");
|
|
10
|
+
const crypto_js_1 = require("../../vault/crypto.js");
|
|
11
|
+
const inspect_js_1 = require("./inspect.js");
|
|
12
|
+
/** Impressão digital truncada. 16 hex identificam sem virar um segundo identificador. */
|
|
13
|
+
function shortFingerprint(full) {
|
|
14
|
+
return full.slice(0, 16);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Nome determinístico da credencial no cofre.
|
|
18
|
+
*
|
|
19
|
+
* Determinístico porque a substituição precisa ENCONTRAR o que já existe: o
|
|
20
|
+
* índice único do cofre é `(tenant, cliente, lower(nome))`, e um nome novo a
|
|
21
|
+
* cada upload deixaria uma trilha de chaves privadas órfãs, todas ainda
|
|
22
|
+
* decifráveis, nenhuma referenciada.
|
|
23
|
+
*/
|
|
24
|
+
function fiscalCertificateCredentialName(clientId, certType) {
|
|
25
|
+
return `fiscal:certificate:${certType}:${clientId}`;
|
|
26
|
+
}
|
|
27
|
+
async function onboardFiscalCertificate(tx, keyring, tenantId, input) {
|
|
28
|
+
const certType = input.certType ?? 'A1';
|
|
29
|
+
const clients = await tx `
|
|
30
|
+
SELECT id, document_number FROM client
|
|
31
|
+
WHERE id = ${input.clientId} AND deleted_at IS NULL
|
|
32
|
+
`;
|
|
33
|
+
const client = clients[0];
|
|
34
|
+
if (!client)
|
|
35
|
+
return { status: 'rejected', reason: 'client_not_found' };
|
|
36
|
+
const inspection = await (0, inspect_js_1.inspectPkcs12)(input.material, input.passphrase);
|
|
37
|
+
if (inspection.status === 'failed') {
|
|
38
|
+
return { status: 'rejected', reason: inspection.reason };
|
|
39
|
+
}
|
|
40
|
+
const facts = inspection.facts;
|
|
41
|
+
if (facts.expired)
|
|
42
|
+
return { status: 'rejected', reason: 'expired' };
|
|
43
|
+
const identity = (0, inspect_js_1.matchIdentity)(facts.document, client.document_number);
|
|
44
|
+
if (identity === 'mismatch' && !input.identityOverrideReason) {
|
|
45
|
+
return { status: 'rejected', reason: 'identity_mismatch', identityMatch: identity };
|
|
46
|
+
}
|
|
47
|
+
// O envelope é o MESMO que `material.ts` sabe abrir. Um segundo formato aqui
|
|
48
|
+
// significaria que o certificado que entra não é o que o transporte usa.
|
|
49
|
+
const envelope = JSON.stringify({
|
|
50
|
+
format: 'pkcs12',
|
|
51
|
+
material: input.material.toString('base64'),
|
|
52
|
+
...(input.passphrase ? { passphrase: input.passphrase } : {}),
|
|
53
|
+
});
|
|
54
|
+
const credentialName = fiscalCertificateCredentialName(input.clientId, certType);
|
|
55
|
+
const credentialId = await upsertWriteOnlyCredential(tx, keyring, tenantId, {
|
|
56
|
+
name: credentialName,
|
|
57
|
+
clientId: input.clientId,
|
|
58
|
+
secret: envelope,
|
|
59
|
+
expiresAt: facts.validTo,
|
|
60
|
+
actorId: input.actorId,
|
|
61
|
+
metadata: {
|
|
62
|
+
// Metadata do cofre é lida por telas e por trilha: só o que é público no
|
|
63
|
+
// certificado entra aqui.
|
|
64
|
+
fingerprint: shortFingerprint(facts.fingerprintSha256),
|
|
65
|
+
certType,
|
|
66
|
+
subject: facts.subjectCommonName,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
const expiresOn = facts.validTo.slice(0, 10);
|
|
70
|
+
const issuedAt = facts.validFrom.slice(0, 10);
|
|
71
|
+
const holderName = facts.subjectCommonName ?? 'Titular não identificado no certificado';
|
|
72
|
+
const existing = await tx `
|
|
73
|
+
SELECT id FROM digital_certificate
|
|
74
|
+
WHERE client_id = ${input.clientId} AND cert_type = ${certType} AND deleted_at IS NULL
|
|
75
|
+
ORDER BY created_at DESC LIMIT 1
|
|
76
|
+
`;
|
|
77
|
+
const override = identity === 'mismatch' ? (input.identityOverrideReason ?? null) : null;
|
|
78
|
+
const overrideBy = override ? input.actorId : null;
|
|
79
|
+
let rows;
|
|
80
|
+
if (existing[0]) {
|
|
81
|
+
rows = await tx `
|
|
82
|
+
UPDATE digital_certificate SET
|
|
83
|
+
holder_name = ${holderName},
|
|
84
|
+
holder_document = ${facts.document ?? client.document_number},
|
|
85
|
+
issued_at = ${issuedAt},
|
|
86
|
+
expires_at = ${expiresOn},
|
|
87
|
+
vault_credential_id = ${credentialId},
|
|
88
|
+
status = 'active',
|
|
89
|
+
fingerprint_sha256 = ${facts.fingerprintSha256},
|
|
90
|
+
subject_common_name = ${facts.subjectCommonName},
|
|
91
|
+
issuer_common_name = ${facts.issuerCommonName},
|
|
92
|
+
serial_tail = ${facts.serialTail},
|
|
93
|
+
certificate_document = ${facts.document},
|
|
94
|
+
identity_match = ${identity},
|
|
95
|
+
identity_override_by = ${overrideBy},
|
|
96
|
+
identity_override_reason = ${override},
|
|
97
|
+
uploaded_by = ${input.actorId},
|
|
98
|
+
uploaded_at = now(),
|
|
99
|
+
-- O material acabou de ser aberto pela inspeção — o mesmo OpenSSL do
|
|
100
|
+
-- handshake real. Isso é a validação LOCAL, e ela é fato deste instante:
|
|
101
|
+
-- senha correta, chave casando com o certificado, titular e datas
|
|
102
|
+
-- conferidos. Ver 1006.
|
|
103
|
+
local_validated_at = now(),
|
|
104
|
+
-- Material novo é uma afirmação nova: o que o ambiente oficial aceitou
|
|
105
|
+
-- foi o certificado ANTERIOR, e herdar a verificação diria que o novo
|
|
106
|
+
-- já funcionou. Ver 1004.
|
|
107
|
+
verified_at = NULL,
|
|
108
|
+
verified_by = NULL,
|
|
109
|
+
remote_verification_provider = NULL,
|
|
110
|
+
remote_verification_last_attempt_at = NULL,
|
|
111
|
+
last_verification_error = NULL,
|
|
112
|
+
updated_at = now()
|
|
113
|
+
WHERE id = ${existing[0].id}
|
|
114
|
+
RETURNING ${tx.unsafe(CERTIFICATE_COLUMNS)}
|
|
115
|
+
`;
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
rows = await tx `
|
|
119
|
+
INSERT INTO digital_certificate (
|
|
120
|
+
id, tenant_id, client_id, cert_type, holder_name, holder_document,
|
|
121
|
+
issued_at, expires_at, vault_credential_id, status,
|
|
122
|
+
fingerprint_sha256, subject_common_name, issuer_common_name, serial_tail,
|
|
123
|
+
certificate_document, identity_match, identity_override_by, identity_override_reason,
|
|
124
|
+
uploaded_by, uploaded_at, local_validated_at
|
|
125
|
+
) VALUES (
|
|
126
|
+
${(0, shared_1.uuidv7)()}, current_setting('app.current_tenant')::uuid, ${input.clientId},
|
|
127
|
+
${certType}, ${holderName}, ${facts.document ?? client.document_number},
|
|
128
|
+
${issuedAt}, ${expiresOn}, ${credentialId}, 'active',
|
|
129
|
+
${facts.fingerprintSha256}, ${facts.subjectCommonName}, ${facts.issuerCommonName},
|
|
130
|
+
${facts.serialTail}, ${facts.document}, ${identity}, ${overrideBy}, ${override},
|
|
131
|
+
-- As duas datas coincidem aqui, e é correto: o material só chega a
|
|
132
|
+
-- esta linha porque a inspeção passou.
|
|
133
|
+
${input.actorId}, now(), now()
|
|
134
|
+
)
|
|
135
|
+
RETURNING ${tx.unsafe(CERTIFICATE_COLUMNS)}
|
|
136
|
+
`;
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
status: 'stored',
|
|
140
|
+
certificate: mapCertificate(rows[0], { replaced: Boolean(existing[0]) }),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Grava (ou rotaciona) o segredo no cofre com `exposure = 'write_only'`.
|
|
145
|
+
*
|
|
146
|
+
* Não reutiliza `createCredential`/`rotateSecret` de `vault/repository.ts` por
|
|
147
|
+
* um motivo específico: aqueles não conhecem `exposure`, e um certificado
|
|
148
|
+
* gravado por eles nasceria `revealable` — a 0060 recusaria o INSERT, o que
|
|
149
|
+
* está correto, mas a mensagem de erro seria uma violação de CHECK em vez de
|
|
150
|
+
* uma decisão explícita. Aqui a classe do segredo é dita na escrita.
|
|
151
|
+
*/
|
|
152
|
+
async function upsertWriteOnlyCredential(tx, keyring, tenantId, input) {
|
|
153
|
+
const enc = (0, crypto_js_1.encryptSecret)(keyring, tenantId, input.secret);
|
|
154
|
+
const existing = await tx `
|
|
155
|
+
SELECT id FROM vault_credential
|
|
156
|
+
WHERE client_id = ${input.clientId}
|
|
157
|
+
AND lower(name) = lower(${input.name})
|
|
158
|
+
AND deleted_at IS NULL
|
|
159
|
+
LIMIT 1
|
|
160
|
+
`;
|
|
161
|
+
if (existing[0]) {
|
|
162
|
+
await tx `
|
|
163
|
+
UPDATE vault_credential SET
|
|
164
|
+
ciphertext = ${enc.ciphertext}, iv = ${enc.iv}, auth_tag = ${enc.authTag},
|
|
165
|
+
key_version = ${enc.keyVersion}, rotated_at = now(), updated_at = now(),
|
|
166
|
+
updated_by = ${input.actorId}, version = version + 1,
|
|
167
|
+
expires_at = ${input.expiresAt},
|
|
168
|
+
metadata = ${tx.json(input.metadata)},
|
|
169
|
+
exposure = 'write_only'
|
|
170
|
+
WHERE id = ${existing[0].id}
|
|
171
|
+
`;
|
|
172
|
+
return existing[0].id;
|
|
173
|
+
}
|
|
174
|
+
const rows = await tx `
|
|
175
|
+
INSERT INTO vault_credential (
|
|
176
|
+
id, tenant_id, client_id, name, category, provider,
|
|
177
|
+
ciphertext, iv, auth_tag, key_version, metadata, expires_at, created_by, exposure
|
|
178
|
+
) VALUES (
|
|
179
|
+
${(0, shared_1.uuidv7)()}, current_setting('app.current_tenant')::uuid, ${input.clientId},
|
|
180
|
+
${input.name}, 'certificate', 'icp_brasil',
|
|
181
|
+
${enc.ciphertext}, ${enc.iv}, ${enc.authTag}, ${enc.keyVersion},
|
|
182
|
+
${tx.json(input.metadata)}, ${input.expiresAt}, ${input.actorId}, 'write_only'
|
|
183
|
+
)
|
|
184
|
+
RETURNING id
|
|
185
|
+
`;
|
|
186
|
+
return rows[0].id;
|
|
187
|
+
}
|
|
188
|
+
const CERTIFICATE_COLUMNS = `
|
|
189
|
+
id, client_id, cert_type, status, subject_common_name, issuer_common_name,
|
|
190
|
+
serial_tail, fingerprint_sha256, certificate_document, identity_match,
|
|
191
|
+
identity_override_reason, issued_at, expires_at, uploaded_at, verified_at,
|
|
192
|
+
local_validated_at, remote_verification_provider
|
|
193
|
+
`;
|
|
194
|
+
function mapCertificate(r, extra) {
|
|
195
|
+
return {
|
|
196
|
+
id: r.id,
|
|
197
|
+
clientId: r.client_id,
|
|
198
|
+
certType: r.cert_type === 'A3' ? 'A3' : 'A1',
|
|
199
|
+
status: r.status,
|
|
200
|
+
subjectCommonName: r.subject_common_name,
|
|
201
|
+
issuerCommonName: r.issuer_common_name,
|
|
202
|
+
serialTail: r.serial_tail,
|
|
203
|
+
fingerprint: shortFingerprint(r.fingerprint_sha256 ?? ''),
|
|
204
|
+
certificateDocument: r.certificate_document,
|
|
205
|
+
identityMatch: r.identity_match ?? 'indeterminate',
|
|
206
|
+
identityOverrideReason: r.identity_override_reason,
|
|
207
|
+
issuedAt: r.issued_at ? isoDate(r.issued_at) : null,
|
|
208
|
+
expiresOn: isoDate(r.expires_at),
|
|
209
|
+
uploadedAt: r.uploaded_at?.toISOString() ?? null,
|
|
210
|
+
verifiedAt: r.verified_at?.toISOString() ?? null,
|
|
211
|
+
replaced: extra.replaced,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function isoDate(d) {
|
|
215
|
+
return d.toISOString().slice(0, 10);
|
|
216
|
+
}
|
|
217
|
+
/** Os certificados de um cliente, só metadata. É o que a tela lê. */
|
|
218
|
+
async function listFiscalCertificates(tx, clientId) {
|
|
219
|
+
const rows = await tx `
|
|
220
|
+
SELECT ${tx.unsafe(CERTIFICATE_COLUMNS)}
|
|
221
|
+
FROM digital_certificate
|
|
222
|
+
WHERE client_id = ${clientId} AND deleted_at IS NULL
|
|
223
|
+
ORDER BY expires_at DESC
|
|
224
|
+
`;
|
|
225
|
+
return rows.map((r) => mapCertificate(r, { replaced: false }));
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Revoga o uso do certificado DENTRO deste produto.
|
|
229
|
+
*
|
|
230
|
+
* Não toca a ICP-Brasil, e é por isso que a função se chama assim. Revogar de
|
|
231
|
+
* verdade um certificado é um ato junto à Autoridade Certificadora que o emitiu;
|
|
232
|
+
* apagar a linha daqui apenas garante que este produto pare de apresentá-lo. A
|
|
233
|
+
* tela repete a distinção, porque um operador que acredite ter revogado o
|
|
234
|
+
* certificado do cliente não vai à AC — e o certificado segue válido no mundo.
|
|
235
|
+
*
|
|
236
|
+
* O material sai do cofre no mesmo movimento (`deleted_at`), de modo que a
|
|
237
|
+
* revogação não deixa chave privada decifrável para trás.
|
|
238
|
+
*/
|
|
239
|
+
async function revokeFiscalCertificate(tx, clientId, certificateId) {
|
|
240
|
+
const rows = await tx `
|
|
241
|
+
UPDATE digital_certificate SET status = 'revoked', deleted_at = now(), updated_at = now()
|
|
242
|
+
WHERE id = ${certificateId} AND client_id = ${clientId} AND deleted_at IS NULL
|
|
243
|
+
RETURNING vault_credential_id
|
|
244
|
+
`;
|
|
245
|
+
if (rows.length === 0)
|
|
246
|
+
return { revoked: false };
|
|
247
|
+
const pointer = rows[0]?.vault_credential_id;
|
|
248
|
+
if (pointer) {
|
|
249
|
+
await tx `
|
|
250
|
+
UPDATE vault_credential SET deleted_at = now()
|
|
251
|
+
WHERE id = ${pointer} AND deleted_at IS NULL
|
|
252
|
+
`;
|
|
253
|
+
}
|
|
254
|
+
return { revoked: true };
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Impressão digital do material recebido, antes de qualquer decisão.
|
|
258
|
+
*
|
|
259
|
+
* Serve à trilha do upload recusado: registrar "tentaram subir algo" sem
|
|
260
|
+
* registrar o quê. É o mesmo cálculo de `material.ts`, e é seguro por
|
|
261
|
+
* construção — um hash não volta a ser um certificado.
|
|
262
|
+
*/
|
|
263
|
+
function materialFingerprint(material) {
|
|
264
|
+
return shortFingerprint((0, node_crypto_1.createHash)('sha256').update(material).digest('hex'));
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=onboarding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboarding.js","sourceRoot":"","sources":["../../../../src/fiscal/credentials/onboarding.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readFiscalCredentialReadiness = readFiscalCredentialReadiness;
|
|
4
|
+
exports.interventionKindFor = interventionKindFor;
|
|
5
|
+
/**
|
|
6
|
+
* Classes de erro de verificação que significam "o titular foi recusado".
|
|
7
|
+
*
|
|
8
|
+
* Guardadas em `digital_certificate.last_verification_error` como CLASSE — a
|
|
9
|
+
* coluna existe desde a 1004 justamente para não guardar a mensagem.
|
|
10
|
+
*/
|
|
11
|
+
const DENIED_CLASSES = new Set(['auth', 'not_allowed', 'access_denied', 'permission_denied']);
|
|
12
|
+
/**
|
|
13
|
+
* Lê a prontidão operacional.
|
|
14
|
+
*
|
|
15
|
+
* Roda dentro de `withContext` com o tenant: `digital_certificate` tem RLS FORCE
|
|
16
|
+
* e é a GUC que decide de quem são as linhas lidas.
|
|
17
|
+
*
|
|
18
|
+
* Tolera a ausência da tabela (`42P01`) porque `digital_certificate` pertence à
|
|
19
|
+
* VERTICAL contábil: um tenant sem ela instalada não tem credencial nenhuma, e
|
|
20
|
+
* a leitura correta disso é `NOT_CONFIGURED` — não uma exceção que derruba o
|
|
21
|
+
* worker no meio da carteira.
|
|
22
|
+
*/
|
|
23
|
+
async function readFiscalCredentialReadiness(tx, input) {
|
|
24
|
+
const kind = input.kind ?? 'certificate_a1';
|
|
25
|
+
const base = {
|
|
26
|
+
kind,
|
|
27
|
+
usableByWorker: false,
|
|
28
|
+
localValid: false,
|
|
29
|
+
eligibleForFirstContact: false,
|
|
30
|
+
selfHealing: false,
|
|
31
|
+
expiresOn: null,
|
|
32
|
+
verifiedAt: null,
|
|
33
|
+
localValidatedAt: null,
|
|
34
|
+
fingerprint: null,
|
|
35
|
+
providerAuthorization: 'unknown',
|
|
36
|
+
};
|
|
37
|
+
if (kind === 'municipal_portal') {
|
|
38
|
+
// Login de portal municipal não é certificado ICP-Brasil e ainda não tem
|
|
39
|
+
// onde morar. Um cron também não digita captcha. Negado até existir.
|
|
40
|
+
return {
|
|
41
|
+
...base,
|
|
42
|
+
state: 'NOT_CONFIGURED',
|
|
43
|
+
detail: 'portal municipal não tem credencial automatizável neste produto',
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
let rows;
|
|
47
|
+
try {
|
|
48
|
+
rows = await tx `
|
|
49
|
+
SELECT id, cert_type, status, expires_at, verified_at,
|
|
50
|
+
local_validated_at, fingerprint_sha256,
|
|
51
|
+
last_verification_error, vault_credential_id
|
|
52
|
+
FROM digital_certificate
|
|
53
|
+
WHERE client_id = ${input.clientId}
|
|
54
|
+
AND cert_type = ${kind === 'certificate_a3' ? 'A3' : 'A1'}
|
|
55
|
+
AND deleted_at IS NULL
|
|
56
|
+
ORDER BY expires_at DESC
|
|
57
|
+
LIMIT 1
|
|
58
|
+
`;
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
const code = err?.code;
|
|
62
|
+
if (code === '42P01' || code === '42703') {
|
|
63
|
+
return { ...base, state: 'NOT_CONFIGURED', detail: 'vertical contábil não aplicada' };
|
|
64
|
+
}
|
|
65
|
+
throw err;
|
|
66
|
+
}
|
|
67
|
+
const cert = rows[0];
|
|
68
|
+
if (!cert) {
|
|
69
|
+
return { ...base, state: 'NOT_CONFIGURED', detail: 'nenhum certificado cadastrado' };
|
|
70
|
+
}
|
|
71
|
+
const expiresOn = cert.expires_at ? isoDate(cert.expires_at) : null;
|
|
72
|
+
const verifiedAt = cert.verified_at?.toISOString() ?? null;
|
|
73
|
+
const localValidatedAt = cert.local_validated_at?.toISOString() ?? null;
|
|
74
|
+
const withDates = {
|
|
75
|
+
...base,
|
|
76
|
+
expiresOn,
|
|
77
|
+
verifiedAt,
|
|
78
|
+
localValidatedAt,
|
|
79
|
+
fingerprint: cert.fingerprint_sha256 ?? null,
|
|
80
|
+
};
|
|
81
|
+
if (cert.status === 'revoked') {
|
|
82
|
+
return { ...withDates, state: 'INVALID', detail: 'certificado revogado' };
|
|
83
|
+
}
|
|
84
|
+
// Vencimento é fato do calendário, não do registro: um certificado marcado
|
|
85
|
+
// `active` cuja data passou está vencido mesmo que ninguém tenha corrido para
|
|
86
|
+
// atualizar a linha.
|
|
87
|
+
if (cert.expires_at && cert.expires_at < todayUtc()) {
|
|
88
|
+
return { ...withDates, state: 'EXPIRED', detail: `vencido em ${expiresOn}` };
|
|
89
|
+
}
|
|
90
|
+
if (cert.status === 'expired') {
|
|
91
|
+
return { ...withDates, state: 'EXPIRED', detail: 'marcado como vencido' };
|
|
92
|
+
}
|
|
93
|
+
if (cert.last_verification_error && DENIED_CLASSES.has(cert.last_verification_error)) {
|
|
94
|
+
return {
|
|
95
|
+
...withDates,
|
|
96
|
+
state: 'ACCESS_DENIED',
|
|
97
|
+
detail: `último acesso recusado (${cert.last_verification_error})`,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
if (kind === 'certificate_a3') {
|
|
101
|
+
// A3 vive em token ou cartão com PIN digitado por uma pessoa. Ele EXISTE, e
|
|
102
|
+
// dizer "não tem certificado" seria falso; o que ele não é, é automatizável.
|
|
103
|
+
return {
|
|
104
|
+
...withDates,
|
|
105
|
+
state: 'REQUIRES_REVIEW',
|
|
106
|
+
detail: 'A3 exige PIN presencial e não é automatizável por cron',
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
if (!cert.vault_credential_id) {
|
|
110
|
+
// Cadastro sem material é uma promessa sem lastro: a tela diria "tem
|
|
111
|
+
// certificado" e o worker não teria o que apresentar no handshake.
|
|
112
|
+
return {
|
|
113
|
+
...withDates,
|
|
114
|
+
state: 'INVALID',
|
|
115
|
+
detail: 'certificado cadastrado sem material no cofre',
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
if (!cert.verified_at) {
|
|
119
|
+
// Aqui estava o impasse. Antes, tudo que não fora aceito remotamente caía
|
|
120
|
+
// num balde só, e o balde reprovava a execução — inclusive a execução que
|
|
121
|
+
// produziria o aceite. Agora o material conferido localmente tem estado
|
|
122
|
+
// próprio, e é ele que o primeiro contato aceita.
|
|
123
|
+
if (cert.local_validated_at) {
|
|
124
|
+
return {
|
|
125
|
+
...withDates,
|
|
126
|
+
state: 'LOCAL_VALID',
|
|
127
|
+
localValid: true,
|
|
128
|
+
eligibleForFirstContact: true,
|
|
129
|
+
detail: 'válida localmente; nenhum ambiente oficial a aceitou ainda',
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
...withDates,
|
|
134
|
+
state: 'REQUIRES_REVIEW',
|
|
135
|
+
detail: 'cadastrada sem validação local registrada',
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
// A autorização do provedor sai de execução OBSERVADA. Um `SELECT` sobre a
|
|
139
|
+
// trilha, e não uma dedução a partir do cadastro.
|
|
140
|
+
const [ok] = await tx `
|
|
141
|
+
SELECT count(*)::int AS n
|
|
142
|
+
FROM fiscal_sync_run
|
|
143
|
+
WHERE client_id = ${input.clientId}
|
|
144
|
+
AND source = ${input.source}
|
|
145
|
+
AND environment = ${input.environment}
|
|
146
|
+
AND outcome IN ('completed', 'no_documents')
|
|
147
|
+
`;
|
|
148
|
+
const established = (ok?.n ?? 0) > 0;
|
|
149
|
+
return {
|
|
150
|
+
...withDates,
|
|
151
|
+
state: 'READY',
|
|
152
|
+
usableByWorker: true,
|
|
153
|
+
localValid: true,
|
|
154
|
+
// Já aceita remotamente: não há primeiro contato a fazer.
|
|
155
|
+
eligibleForFirstContact: false,
|
|
156
|
+
selfHealing: true,
|
|
157
|
+
providerAuthorization: established ? 'established' : 'unknown',
|
|
158
|
+
detail: established
|
|
159
|
+
? 'pronta; o ambiente já aceitou esta credencial'
|
|
160
|
+
: 'pronta; o ambiente ainda não aceitou esta credencial nenhuma vez',
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function todayUtc() {
|
|
164
|
+
const now = new Date();
|
|
165
|
+
return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
|
|
166
|
+
}
|
|
167
|
+
function isoDate(d) {
|
|
168
|
+
return d.toISOString().slice(0, 10);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* O motivo de intervenção que este estado pede — ou `null` quando não pede.
|
|
172
|
+
*
|
|
173
|
+
* Aqui mora a regra de B2.36 que evita a fila ilegível: `REQUIRES_REVIEW` e
|
|
174
|
+
* `NOT_CONFIGURED` NÃO abrem tarefa. Não configurar automação é uma escolha
|
|
175
|
+
* legítima do escritório, e transformá-la em pendência encheria a fila de
|
|
176
|
+
* clientes que ninguém pediu para automatizar.
|
|
177
|
+
*/
|
|
178
|
+
function interventionKindFor(state) {
|
|
179
|
+
switch (state) {
|
|
180
|
+
case 'EXPIRED':
|
|
181
|
+
return 'certificate_expired';
|
|
182
|
+
case 'INVALID':
|
|
183
|
+
return 'certificate_invalid';
|
|
184
|
+
case 'ACCESS_DENIED':
|
|
185
|
+
return 'auth_required';
|
|
186
|
+
default:
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=readiness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readiness.js","sourceRoot":"","sources":["../../../../src/fiscal/credentials/readiness.ts"],"names":[],"mappings":";;AAsIA,sEA0JC;AAmBD,kDAaC;AA7MD;;;;;GAKG;AACH,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAE9F;;;;;;;;;;GAUG;AACI,KAAK,UAAU,6BAA6B,CACjD,EAAM,EACN,KAKC;IAED,MAAM,IAAI,GAAyB,KAAK,CAAC,IAAI,IAAI,gBAAgB,CAAC;IAElE,MAAM,IAAI,GAAG;QACX,IAAI;QACJ,cAAc,EAAE,KAAK;QACrB,UAAU,EAAE,KAAK;QACjB,uBAAuB,EAAE,KAAK;QAC9B,WAAW,EAAE,KAAK;QAClB,SAAS,EAAE,IAAI;QACf,UAAU,EAAE,IAAI;QAChB,gBAAgB,EAAE,IAAI;QACtB,WAAW,EAAE,IAAI;QACjB,qBAAqB,EAAE,SAAkB;KAC1C,CAAC;IAEF,IAAI,IAAI,KAAK,kBAAkB,EAAE,CAAC;QAChC,yEAAyE;QACzE,qEAAqE;QACrE,OAAO;YACL,GAAG,IAAI;YACP,KAAK,EAAE,gBAAgB;YACvB,MAAM,EAAE,iEAAiE;SAC1E,CAAC;IACJ,CAAC;IAED,IAAI,IAAe,CAAC;IACpB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,EAAE,CAAW;;;;;2BAKH,KAAK,CAAC,QAAQ;2BACd,IAAI,KAAK,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;;;;KAI7D,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,GAAI,GAAgC,EAAE,IAAI,CAAC;QACrD,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACzC,OAAO,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,gCAAgC,EAAE,CAAC;QACxF,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACrB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAC;IACvF,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACpE,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC;IAC3D,MAAM,gBAAgB,GAAG,IAAI,CAAC,kBAAkB,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC;IACxE,MAAM,SAAS,GAAG;QAChB,GAAG,IAAI;QACP,SAAS;QACT,UAAU;QACV,gBAAgB;QAChB,WAAW,EAAE,IAAI,CAAC,kBAAkB,IAAI,IAAI;KAC7C,CAAC;IAEF,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,EAAE,GAAG,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC;IAC5E,CAAC;IACD,2EAA2E;IAC3E,8EAA8E;IAC9E,qBAAqB;IACrB,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,GAAG,QAAQ,EAAE,EAAE,CAAC;QACpD,OAAO,EAAE,GAAG,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,SAAS,EAAE,EAAE,CAAC;IAC/E,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,EAAE,GAAG,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC;IAC5E,CAAC;IACD,IAAI,IAAI,CAAC,uBAAuB,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,uBAAuB,CAAC,EAAE,CAAC;QACrF,OAAO;YACL,GAAG,SAAS;YACZ,KAAK,EAAE,eAAe;YACtB,MAAM,EAAE,2BAA2B,IAAI,CAAC,uBAAuB,GAAG;SACnE,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QAC9B,4EAA4E;QAC5E,6EAA6E;QAC7E,OAAO;YACL,GAAG,SAAS;YACZ,KAAK,EAAE,iBAAiB;YACxB,MAAM,EAAE,wDAAwD;SACjE,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC9B,qEAAqE;QACrE,mEAAmE;QACnE,OAAO;YACL,GAAG,SAAS;YACZ,KAAK,EAAE,SAAS;YAChB,MAAM,EAAE,8CAA8C;SACvD,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACtB,0EAA0E;QAC1E,0EAA0E;QAC1E,wEAAwE;QACxE,kDAAkD;QAClD,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5B,OAAO;gBACL,GAAG,SAAS;gBACZ,KAAK,EAAE,aAAa;gBACpB,UAAU,EAAE,IAAI;gBAChB,uBAAuB,EAAE,IAAI;gBAC7B,MAAM,EAAE,4DAA4D;aACrE,CAAC;QACJ,CAAC;QACD,OAAO;YACL,GAAG,SAAS;YACZ,KAAK,EAAE,iBAAiB;YACxB,MAAM,EAAE,2CAA2C;SACpD,CAAC;IACJ,CAAC;IAED,2EAA2E;IAC3E,kDAAkD;IAClD,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAiB;;;yBAGf,KAAK,CAAC,QAAQ;sBACjB,KAAK,CAAC,MAAM;2BACP,KAAK,CAAC,WAAW;;GAEzC,CAAC;IACF,MAAM,WAAW,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAErC,OAAO;QACL,GAAG,SAAS;QACZ,KAAK,EAAE,OAAO;QACd,cAAc,EAAE,IAAI;QACpB,UAAU,EAAE,IAAI;QAChB,0DAA0D;QAC1D,uBAAuB,EAAE,KAAK;QAC9B,WAAW,EAAE,IAAI;QACjB,qBAAqB,EAAE,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS;QAC9D,MAAM,EAAE,WAAW;YACjB,CAAC,CAAC,+CAA+C;YACjD,CAAC,CAAC,kEAAkE;KACvE,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ;IACf,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,GAAG,CAAC,WAAW,EAAE,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AACvF,CAAC;AAED,SAAS,OAAO,CAAC,CAAO;IACtB,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,mBAAmB,CACjC,KAA4B;IAE5B,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,SAAS;YACZ,OAAO,qBAAqB,CAAC;QAC/B,KAAK,SAAS;YACZ,OAAO,qBAAqB,CAAC;QAC/B,KAAK,eAAe;YAClB,OAAO,eAAe,CAAC;QACzB;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC"}
|