@learncard/network-brain-service 3.19.0 → 4.0.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/.env.example +47 -82
- package/AGENTS.md +52 -0
- package/CHANGELOG.md +147 -0
- package/README.md +51 -2
- package/bootstrapLambda.test.ts +72 -0
- package/config/config.dev.json +29 -0
- package/config/config.example.json +29 -0
- package/config/config.json +1 -0
- package/config/config.production.json +29 -0
- package/config/config.scouts.dev.json +24 -0
- package/config/config.scouts.production.json +24 -0
- package/contractEventsLambda.ts +18 -0
- package/contractEventsLambdaApp.ts +19 -0
- package/didWebLambda.ts +13 -18
- package/didWebLambdaApp.ts +22 -0
- package/dist/accesslayer/app-manifest-version/create.d.ts +10 -0
- package/dist/accesslayer/app-manifest-version/create.d.ts.map +1 -0
- package/dist/accesslayer/app-manifest-version/read.d.ts +11 -0
- package/dist/accesslayer/app-manifest-version/read.d.ts.map +1 -0
- package/dist/accesslayer/app-manifest-version/update.d.ts +7 -0
- package/dist/accesslayer/app-manifest-version/update.d.ts.map +1 -0
- package/dist/accesslayer/app-store-listing/read.d.ts +2 -1
- package/dist/accesslayer/app-store-listing/read.d.ts.map +1 -1
- package/dist/accesslayer/app-store-listing/relationships/create.d.ts +1 -0
- package/dist/accesslayer/app-store-listing/relationships/create.d.ts.map +1 -1
- package/dist/accesslayer/app-store-listing/relationships/read.d.ts +2 -0
- package/dist/accesslayer/app-store-listing/relationships/read.d.ts.map +1 -1
- package/dist/accesslayer/app-store-listing/update.d.ts +1 -0
- package/dist/accesslayer/app-store-listing/update.d.ts.map +1 -1
- package/dist/accesslayer/boost/relationships/create.d.ts +2 -1
- package/dist/accesslayer/boost/relationships/create.d.ts.map +1 -1
- package/dist/accesslayer/consentflowcontract/create.d.ts +9 -1
- package/dist/accesslayer/consentflowcontract/create.d.ts.map +1 -1
- package/dist/accesslayer/consentflowcontract/read.d.ts +34 -3
- package/dist/accesslayer/consentflowcontract/read.d.ts.map +1 -1
- package/dist/accesslayer/consentflowcontract/relationships/create.d.ts +4 -1
- package/dist/accesslayer/consentflowcontract/relationships/create.d.ts.map +1 -1
- package/dist/accesslayer/consentflowcontract/relationships/delete.d.ts.map +1 -1
- package/dist/accesslayer/consentflowcontract/relationships/read.d.ts +3 -2
- package/dist/accesslayer/consentflowcontract/relationships/read.d.ts.map +1 -1
- package/dist/accesslayer/consentflowcontract/relationships/recipients.d.ts +12 -0
- package/dist/accesslayer/consentflowcontract/relationships/recipients.d.ts.map +1 -0
- package/dist/accesslayer/consentflowcontract/relationships/smartResume.d.ts +12 -0
- package/dist/accesslayer/consentflowcontract/relationships/smartResume.d.ts.map +1 -0
- package/dist/accesslayer/consentflowcontract/relationships/update.d.ts +8 -5
- package/dist/accesslayer/consentflowcontract/relationships/update.d.ts.map +1 -1
- package/dist/accesslayer/credential/create.d.ts +2 -1
- package/dist/accesslayer/credential/create.d.ts.map +1 -1
- package/dist/accesslayer/credential/relationships/create.d.ts +4 -3
- package/dist/accesslayer/credential/relationships/create.d.ts.map +1 -1
- package/dist/accesslayer/inbox-credential/relationships/create.d.ts +2 -1
- package/dist/accesslayer/inbox-credential/relationships/create.d.ts.map +1 -1
- package/dist/accesslayer/inbox-credential/update.d.ts +2 -1
- package/dist/accesslayer/inbox-credential/update.d.ts.map +1 -1
- package/dist/accesslayer/presentation/read.d.ts.map +1 -1
- package/dist/accesslayer/presentation/relationships/create.d.ts +2 -2
- package/dist/accesslayer/presentation/relationships/create.d.ts.map +1 -1
- package/dist/accesslayer/presentation/relationships/read.d.ts.map +1 -1
- package/dist/accesslayer/share-link/abandon.d.ts +3 -0
- package/dist/accesslayer/share-link/abandon.d.ts.map +1 -0
- package/dist/accesslayer/share-link/attachment.d.ts +37 -0
- package/dist/accesslayer/share-link/attachment.d.ts.map +1 -0
- package/dist/accesslayer/share-link/cleanup.d.ts +6 -0
- package/dist/accesslayer/share-link/cleanup.d.ts.map +1 -0
- package/dist/accesslayer/share-link/errors.d.ts +8 -0
- package/dist/accesslayer/share-link/errors.d.ts.map +1 -0
- package/dist/accesslayer/share-link/finalize.d.ts +3 -0
- package/dist/accesslayer/share-link/finalize.d.ts.map +1 -0
- package/dist/accesslayer/share-link/helpers.d.ts +59 -0
- package/dist/accesslayer/share-link/helpers.d.ts.map +1 -0
- package/dist/accesslayer/share-link/index.d.ts +12 -0
- package/dist/accesslayer/share-link/index.d.ts.map +1 -0
- package/dist/accesslayer/share-link/list.d.ts +5 -0
- package/dist/accesslayer/share-link/list.d.ts.map +1 -0
- package/dist/accesslayer/share-link/read.d.ts +5 -0
- package/dist/accesslayer/share-link/read.d.ts.map +1 -0
- package/dist/accesslayer/share-link/receipt.d.ts +11 -0
- package/dist/accesslayer/share-link/receipt.d.ts.map +1 -0
- package/dist/accesslayer/share-link/recovery.d.ts +6 -0
- package/dist/accesslayer/share-link/recovery.d.ts.map +1 -0
- package/dist/accesslayer/share-link/reserve.d.ts +4 -0
- package/dist/accesslayer/share-link/reserve.d.ts.map +1 -0
- package/dist/accesslayer/share-link/revoke.d.ts +3 -0
- package/dist/accesslayer/share-link/revoke.d.ts.map +1 -0
- package/dist/accesslayer/share-link/transaction-execution.d.ts +18 -0
- package/dist/accesslayer/share-link/transaction-execution.d.ts.map +1 -0
- package/dist/accesslayer/share-link/transaction.d.ts +15 -0
- package/dist/accesslayer/share-link/transaction.d.ts.map +1 -0
- package/dist/accesslayer/share-link/types.d.ts +375 -0
- package/dist/accesslayer/share-link/types.d.ts.map +1 -0
- package/dist/app.d.ts +4 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/cache/app-store.caches.d.ts +49 -0
- package/dist/cache/app-store.caches.d.ts.map +1 -1
- package/dist/config/applyDockerStageConfig.d.ts +2 -0
- package/dist/config/applyDockerStageConfig.d.ts.map +1 -0
- package/dist/config/environment.d.ts +14 -0
- package/dist/config/environment.d.ts.map +1 -1
- package/dist/config/serverlessFunctionEnv.test.d.ts +2 -0
- package/dist/config/serverlessFunctionEnv.test.d.ts.map +1 -0
- package/dist/config/stageConfig.d.ts +112 -0
- package/dist/config/stageConfig.d.ts.map +1 -0
- package/dist/config/stageConfig.test.d.ts +2 -0
- package/dist/config/stageConfig.test.d.ts.map +1 -0
- package/dist/constants/auth-grant.d.ts +2 -0
- package/dist/constants/auth-grant.d.ts.map +1 -1
- package/dist/didkit_wasm_bg.wasm +0 -0
- package/dist/docker-entry.d.ts +1 -1
- package/dist/docker-entry.d.ts.map +1 -1
- package/dist/helpers/app-manifest.helpers.d.ts +5 -0
- package/dist/helpers/app-manifest.helpers.d.ts.map +1 -0
- package/dist/helpers/boost.helpers.d.ts.map +1 -1
- package/dist/helpers/claim-hooks.helpers.d.ts +2 -1
- package/dist/helpers/claim-hooks.helpers.d.ts.map +1 -1
- package/dist/helpers/consent-referral.helpers.d.ts +2 -0
- package/dist/helpers/consent-referral.helpers.d.ts.map +1 -0
- package/dist/helpers/consent-scopes.helpers.d.ts +7 -0
- package/dist/helpers/consent-scopes.helpers.d.ts.map +1 -0
- package/dist/helpers/contract-event-maintenance.helpers.d.ts +3 -0
- package/dist/helpers/contract-event-maintenance.helpers.d.ts.map +1 -0
- package/dist/helpers/contract-events.helpers.d.ts +25 -0
- package/dist/helpers/contract-events.helpers.d.ts.map +1 -0
- package/dist/helpers/contract-requests.helpers.d.ts +19 -0
- package/dist/helpers/contract-requests.helpers.d.ts.map +1 -0
- package/dist/helpers/credentialSubject.helpers.d.ts +3 -0
- package/dist/helpers/credentialSubject.helpers.d.ts.map +1 -0
- package/dist/helpers/credentialSubject.helpers.test.d.ts +2 -0
- package/dist/helpers/credentialSubject.helpers.test.d.ts.map +1 -0
- package/dist/helpers/finalize-inbox.helpers.d.ts +3 -3
- package/dist/helpers/finalize-inbox.helpers.d.ts.map +1 -1
- package/dist/helpers/inbox.helpers.d.ts.map +1 -1
- package/dist/helpers/inline-template.helpers.d.ts +45 -0
- package/dist/helpers/inline-template.helpers.d.ts.map +1 -0
- package/dist/helpers/notificationMessages.d.ts +1 -1
- package/dist/helpers/notificationMessages.d.ts.map +1 -1
- package/dist/helpers/notificationQueue.helpers.d.ts.map +1 -1
- package/dist/helpers/notifications.helpers.d.ts +6 -0
- package/dist/helpers/notifications.helpers.d.ts.map +1 -1
- package/dist/helpers/presentation-metadata.d.ts +4 -0
- package/dist/helpers/presentation-metadata.d.ts.map +1 -0
- package/dist/helpers/presentation.helpers.d.ts +1 -1
- package/dist/helpers/presentation.helpers.d.ts.map +1 -1
- package/dist/helpers/profile.helpers.d.ts +2 -0
- package/dist/helpers/profile.helpers.d.ts.map +1 -1
- package/dist/helpers/share-content-client/adapters.d.ts +10 -0
- package/dist/helpers/share-content-client/adapters.d.ts.map +1 -0
- package/dist/helpers/share-content-client/canonical.d.ts +7 -0
- package/dist/helpers/share-content-client/canonical.d.ts.map +1 -0
- package/dist/helpers/share-content-client/client.d.ts +5 -0
- package/dist/helpers/share-content-client/client.d.ts.map +1 -0
- package/dist/helpers/share-content-client/config.d.ts +11 -0
- package/dist/helpers/share-content-client/config.d.ts.map +1 -0
- package/dist/helpers/share-content-client/index.d.ts +6 -0
- package/dist/helpers/share-content-client/index.d.ts.map +1 -0
- package/dist/helpers/share-content-client/responses.d.ts +16 -0
- package/dist/helpers/share-content-client/responses.d.ts.map +1 -0
- package/dist/helpers/share-content-client/types.d.ts +145 -0
- package/dist/helpers/share-content-client/types.d.ts.map +1 -0
- package/dist/helpers/share-link-attachment-access.d.ts +4 -0
- package/dist/helpers/share-link-attachment-access.d.ts.map +1 -0
- package/dist/helpers/share-link-attachment.d.ts +18 -0
- package/dist/helpers/share-link-attachment.d.ts.map +1 -0
- package/dist/helpers/share-link-coordinator/attachment-stat.d.ts +5 -0
- package/dist/helpers/share-link-coordinator/attachment-stat.d.ts.map +1 -0
- package/dist/helpers/share-link-coordinator/budget-helpers.d.ts +5 -0
- package/dist/helpers/share-link-coordinator/budget-helpers.d.ts.map +1 -0
- package/dist/helpers/share-link-coordinator/cleanup-runner.d.ts +3 -0
- package/dist/helpers/share-link-coordinator/cleanup-runner.d.ts.map +1 -0
- package/dist/helpers/share-link-coordinator/coordinator.d.ts +4 -0
- package/dist/helpers/share-link-coordinator/coordinator.d.ts.map +1 -0
- package/dist/helpers/share-link-coordinator/index.d.ts +5 -0
- package/dist/helpers/share-link-coordinator/index.d.ts.map +1 -0
- package/dist/helpers/share-link-coordinator/recovery-runner.d.ts +9 -0
- package/dist/helpers/share-link-coordinator/recovery-runner.d.ts.map +1 -0
- package/dist/helpers/share-link-coordinator/runtime.d.ts +11 -0
- package/dist/helpers/share-link-coordinator/runtime.d.ts.map +1 -0
- package/dist/helpers/share-link-coordinator/stat.d.ts +4 -0
- package/dist/helpers/share-link-coordinator/stat.d.ts.map +1 -0
- package/dist/helpers/share-link-coordinator/types.d.ts +160 -0
- package/dist/helpers/share-link-coordinator/types.d.ts.map +1 -0
- package/dist/helpers/share-link-lifecycle/index.d.ts +5 -0
- package/dist/helpers/share-link-lifecycle/index.d.ts.map +1 -0
- package/dist/helpers/share-link-lifecycle/lease.helpers.d.ts +4 -0
- package/dist/helpers/share-link-lifecycle/lease.helpers.d.ts.map +1 -0
- package/dist/helpers/share-link-lifecycle/recovery.helpers.d.ts +21 -0
- package/dist/helpers/share-link-lifecycle/recovery.helpers.d.ts.map +1 -0
- package/dist/helpers/share-link-lifecycle/request-hash.helpers.d.ts +9 -0
- package/dist/helpers/share-link-lifecycle/request-hash.helpers.d.ts.map +1 -0
- package/dist/helpers/share-link-lifecycle/types.d.ts +14 -0
- package/dist/helpers/share-link-lifecycle/types.d.ts.map +1 -0
- package/dist/helpers/share-link-maintenance/budget.d.ts +12 -0
- package/dist/helpers/share-link-maintenance/budget.d.ts.map +1 -0
- package/dist/helpers/share-link-maintenance/config.d.ts +48 -0
- package/dist/helpers/share-link-maintenance/config.d.ts.map +1 -0
- package/dist/helpers/share-link-maintenance/index.d.ts +8 -0
- package/dist/helpers/share-link-maintenance/index.d.ts.map +1 -0
- package/dist/helpers/share-link-maintenance/runner.d.ts +20 -0
- package/dist/helpers/share-link-maintenance/runner.d.ts.map +1 -0
- package/dist/helpers/share-link-maintenance/runtime.d.ts +38 -0
- package/dist/helpers/share-link-maintenance/runtime.d.ts.map +1 -0
- package/dist/helpers/share-link-maintenance/scheduler.d.ts +18 -0
- package/dist/helpers/share-link-maintenance/scheduler.d.ts.map +1 -0
- package/dist/helpers/share-link-maintenance/telemetry.d.ts +5 -0
- package/dist/helpers/share-link-maintenance/telemetry.d.ts.map +1 -0
- package/dist/helpers/share-link-maintenance/types.d.ts +56 -0
- package/dist/helpers/share-link-maintenance/types.d.ts.map +1 -0
- package/dist/helpers/share-link-owner/config.d.ts +16 -0
- package/dist/helpers/share-link-owner/config.d.ts.map +1 -0
- package/dist/helpers/share-link-owner/diagnostics.d.ts +26 -0
- package/dist/helpers/share-link-owner/diagnostics.d.ts.map +1 -0
- package/dist/helpers/share-link-owner/lazy-initializer.d.ts +2 -0
- package/dist/helpers/share-link-owner/lazy-initializer.d.ts.map +1 -0
- package/dist/helpers/share-link-owner-projection.d.ts +4 -0
- package/dist/helpers/share-link-owner-projection.d.ts.map +1 -0
- package/dist/helpers/share-link-passcode-abuse.d.ts +2 -0
- package/dist/helpers/share-link-passcode-abuse.d.ts.map +1 -0
- package/dist/helpers/share-link-passcode.d.ts +6 -0
- package/dist/helpers/share-link-passcode.d.ts.map +1 -0
- package/dist/helpers/share-link-policy/index.d.ts +4 -0
- package/dist/helpers/share-link-policy/index.d.ts.map +1 -0
- package/dist/helpers/share-link-policy/production.d.ts +11 -0
- package/dist/helpers/share-link-policy/production.d.ts.map +1 -0
- package/dist/helpers/share-link-policy/resolver.d.ts +6 -0
- package/dist/helpers/share-link-policy/resolver.d.ts.map +1 -0
- package/dist/helpers/share-link-policy/types.d.ts +22 -0
- package/dist/helpers/share-link-policy/types.d.ts.map +1 -0
- package/dist/helpers/share-link-public/config.d.ts +13 -0
- package/dist/helpers/share-link-public/config.d.ts.map +1 -0
- package/dist/helpers/share-link-view-notification.d.ts +2 -0
- package/dist/helpers/share-link-view-notification.d.ts.map +1 -0
- package/dist/helpers/signingAuthority.helpers.d.ts.map +1 -1
- package/dist/helpers/smartResume.helpers.d.ts +3 -0
- package/dist/helpers/smartResume.helpers.d.ts.map +1 -0
- package/dist/index.js +2 -2
- package/dist/models/AppManifestVersion.d.ts +20 -0
- package/dist/models/AppManifestVersion.d.ts.map +1 -0
- package/dist/models/AppStoreListing.d.ts +13 -0
- package/dist/models/AppStoreListing.d.ts.map +1 -1
- package/dist/models/ConsentFlowContract.d.ts +13 -2
- package/dist/models/ConsentFlowContract.d.ts.map +1 -1
- package/dist/models/ConsentFlowTerms.d.ts.map +1 -1
- package/dist/models/ConsentFlowTransaction.d.ts.map +1 -1
- package/dist/models/Integration.d.ts +2 -0
- package/dist/models/Integration.d.ts.map +1 -1
- package/dist/models/Presentation.d.ts +2 -0
- package/dist/models/Presentation.d.ts.map +1 -1
- package/dist/models/Profile.d.ts +2 -0
- package/dist/models/Profile.d.ts.map +1 -1
- package/dist/models/ShareLink.d.ts +46 -0
- package/dist/models/ShareLink.d.ts.map +1 -0
- package/dist/models/ShareViewReceipt.d.ts +22 -0
- package/dist/models/ShareViewReceipt.d.ts.map +1 -0
- package/dist/models/index.d.ts +2 -0
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/share-link-constraints.d.ts +3 -0
- package/dist/models/share-link-constraints.d.ts.map +1 -0
- package/dist/openapi.d.ts +1 -1
- package/dist/openapi.d.ts.map +1 -1
- package/dist/public-share-link-http.d.ts +4 -0
- package/dist/public-share-link-http.d.ts.map +1 -0
- package/dist/routes/app-store.d.ts +619 -0
- package/dist/routes/app-store.d.ts.map +1 -1
- package/dist/routes/boosts.d.ts +2 -2
- package/dist/routes/boosts.d.ts.map +1 -1
- package/dist/routes/contracts.d.ts +148 -5
- package/dist/routes/contracts.d.ts.map +1 -1
- package/dist/routes/credentials.d.ts +35 -1
- package/dist/routes/credentials.d.ts.map +1 -1
- package/dist/routes/inbox.d.ts +52 -2
- package/dist/routes/inbox.d.ts.map +1 -1
- package/dist/routes/index.d.ts +153 -0
- package/dist/routes/index.d.ts.map +1 -1
- package/dist/routes/presentations.d.ts +1 -0
- package/dist/routes/presentations.d.ts.map +1 -1
- package/dist/routes/profile-manager.d.ts.map +1 -1
- package/dist/routes/profiles.d.ts.map +1 -1
- package/dist/routes/public-share-links.d.ts +285 -0
- package/dist/routes/public-share-links.d.ts.map +1 -0
- package/dist/routes/share-links.d.ts +1005 -0
- package/dist/routes/share-links.d.ts.map +1 -0
- package/dist/routes/test.d.ts +5 -0
- package/dist/routes/test.d.ts.map +1 -1
- package/dist/routes/workflows.d.ts.map +1 -1
- package/dist/services/delivery/adapters/postmark.adapter.d.ts.map +1 -1
- package/dist/types/app-manifest.d.ts +339 -0
- package/dist/types/app-manifest.d.ts.map +1 -0
- package/dist/types/app-store-listing.d.ts +34 -0
- package/dist/types/app-store-listing.d.ts.map +1 -1
- package/dist/types/consentflowcontract.d.ts +31 -4
- package/dist/types/consentflowcontract.d.ts.map +1 -1
- package/dist/types/credential-refresh.d.ts +1 -1
- package/esbuildPlugins.cjs +1 -0
- package/lambda.ts +49 -192
- package/lambdaApp.ts +203 -0
- package/package.json +25 -17
- package/scripts/export-openapi.ts +20 -0
- package/scripts/offline-schema-environment.ts +18 -0
- package/scripts/seed-demo-persona.ts +425 -0
- package/scripts/verify-python-contracts.ts +72 -0
- package/serverless-local.yml +3 -6
- package/serverless.function-env.cjs +50 -0
- package/serverless.local.yml +0 -1
- package/serverless.yml +44 -55
- package/shareLinkMaintenanceLambda.ts +18 -0
- package/shareLinkMaintenanceLambdaApp.ts +50 -0
- package/src/accesslayer/app-manifest-version/create.ts +57 -0
- package/src/accesslayer/app-manifest-version/read.ts +129 -0
- package/src/accesslayer/app-manifest-version/update.ts +61 -0
- package/src/accesslayer/app-store-listing/read.ts +6 -0
- package/src/accesslayer/app-store-listing/relationships/create.ts +20 -0
- package/src/accesslayer/app-store-listing/relationships/read.ts +24 -1
- package/src/accesslayer/app-store-listing/update.ts +15 -0
- package/src/accesslayer/boost/relationships/create.ts +8 -2
- package/src/accesslayer/consentflowcontract/create.ts +81 -8
- package/src/accesslayer/consentflowcontract/read.ts +84 -10
- package/src/accesslayer/consentflowcontract/relationships/create.ts +125 -109
- package/src/accesslayer/consentflowcontract/relationships/delete.ts +1 -0
- package/src/accesslayer/consentflowcontract/relationships/read.ts +184 -108
- package/src/accesslayer/consentflowcontract/relationships/recipients.ts +125 -0
- package/src/accesslayer/consentflowcontract/relationships/smartResume.ts +125 -0
- package/src/accesslayer/consentflowcontract/relationships/update.ts +255 -217
- package/src/accesslayer/credential/create.test.ts +2 -115
- package/src/accesslayer/credential/create.ts +11 -6
- package/src/accesslayer/credential/relationships/create.ts +17 -10
- package/src/accesslayer/inbox-credential/relationships/create.ts +70 -48
- package/src/accesslayer/inbox-credential/update.ts +4 -2
- package/src/accesslayer/presentation/read.ts +57 -25
- package/src/accesslayer/presentation/relationships/create.ts +54 -11
- package/src/accesslayer/presentation/relationships/read.ts +21 -6
- package/src/accesslayer/share-link/abandon.ts +120 -0
- package/src/accesslayer/share-link/attachment.ts +360 -0
- package/src/accesslayer/share-link/cleanup.ts +271 -0
- package/src/accesslayer/share-link/errors.ts +32 -0
- package/src/accesslayer/share-link/finalize.ts +313 -0
- package/src/accesslayer/share-link/helpers.ts +450 -0
- package/src/accesslayer/share-link/index.ts +11 -0
- package/src/accesslayer/share-link/list.ts +162 -0
- package/src/accesslayer/share-link/read.ts +107 -0
- package/src/accesslayer/share-link/receipt.ts +548 -0
- package/src/accesslayer/share-link/recovery.ts +565 -0
- package/src/accesslayer/share-link/reserve.ts +763 -0
- package/src/accesslayer/share-link/revoke.ts +232 -0
- package/src/accesslayer/share-link/transaction-execution.ts +72 -0
- package/src/accesslayer/share-link/transaction.ts +126 -0
- package/src/accesslayer/share-link/types.ts +606 -0
- package/src/app.ts +6 -0
- package/src/cache/app-store.caches.ts +35 -0
- package/src/config/applyDockerStageConfig.ts +6 -0
- package/src/config/environment.test.ts +17 -12
- package/src/config/environment.ts +15 -0
- package/src/config/serverlessFunctionEnv.test.ts +105 -0
- package/src/config/stageConfig.test.ts +25 -0
- package/src/config/stageConfig.ts +24 -0
- package/src/constants/auth-grant.ts +5 -0
- package/src/docker-entry.ts +81 -0
- package/src/helpers/app-manifest.helpers.ts +185 -0
- package/src/helpers/boost.helpers.ts +4 -31
- package/src/helpers/claim-hooks.helpers.ts +20 -7
- package/src/helpers/consent-referral.helpers.ts +6 -0
- package/src/helpers/consent-scopes.helpers.ts +58 -0
- package/src/helpers/contract-event-maintenance.helpers.ts +43 -0
- package/src/helpers/contract-events.helpers.ts +540 -0
- package/src/helpers/contract-requests.helpers.ts +211 -0
- package/src/helpers/credentialSubject.helpers.test.ts +114 -0
- package/src/helpers/credentialSubject.helpers.ts +40 -0
- package/src/helpers/finalize-inbox.helpers.ts +163 -44
- package/src/helpers/inbox.helpers.ts +58 -70
- package/src/helpers/inline-template.helpers.ts +560 -0
- package/src/helpers/notificationMessages.ts +77 -1
- package/src/helpers/notificationQueue.helpers.ts +23 -5
- package/src/helpers/notifications.helpers.ts +25 -1
- package/src/helpers/presentation-metadata.ts +41 -0
- package/src/helpers/presentation.helpers.ts +27 -20
- package/src/helpers/profile.helpers.ts +13 -0
- package/src/helpers/share-content-client/adapters.ts +55 -0
- package/src/helpers/share-content-client/canonical.ts +25 -0
- package/src/helpers/share-content-client/client.ts +440 -0
- package/src/helpers/share-content-client/config.ts +189 -0
- package/src/helpers/share-content-client/index.ts +27 -0
- package/src/helpers/share-content-client/responses.ts +273 -0
- package/src/helpers/share-content-client/types.ts +253 -0
- package/src/helpers/share-link-attachment-access.ts +87 -0
- package/src/helpers/share-link-attachment.ts +115 -0
- package/src/helpers/share-link-coordinator/attachment-stat.ts +41 -0
- package/src/helpers/share-link-coordinator/budget-helpers.ts +53 -0
- package/src/helpers/share-link-coordinator/cleanup-runner.ts +286 -0
- package/src/helpers/share-link-coordinator/coordinator.ts +727 -0
- package/src/helpers/share-link-coordinator/index.ts +8 -0
- package/src/helpers/share-link-coordinator/recovery-runner.ts +443 -0
- package/src/helpers/share-link-coordinator/runtime.ts +88 -0
- package/src/helpers/share-link-coordinator/stat.ts +30 -0
- package/src/helpers/share-link-coordinator/types.ts +353 -0
- package/src/helpers/share-link-lifecycle/index.ts +4 -0
- package/src/helpers/share-link-lifecycle/lease.helpers.ts +35 -0
- package/src/helpers/share-link-lifecycle/recovery.helpers.ts +173 -0
- package/src/helpers/share-link-lifecycle/request-hash.helpers.ts +130 -0
- package/src/helpers/share-link-lifecycle/types.ts +58 -0
- package/src/helpers/share-link-maintenance/budget.ts +63 -0
- package/src/helpers/share-link-maintenance/config.ts +312 -0
- package/src/helpers/share-link-maintenance/index.ts +24 -0
- package/src/helpers/share-link-maintenance/runner.ts +251 -0
- package/src/helpers/share-link-maintenance/runtime.ts +340 -0
- package/src/helpers/share-link-maintenance/scheduler.ts +126 -0
- package/src/helpers/share-link-maintenance/telemetry.ts +73 -0
- package/src/helpers/share-link-maintenance/types.ts +91 -0
- package/src/helpers/share-link-owner/config.ts +48 -0
- package/src/helpers/share-link-owner/diagnostics.ts +89 -0
- package/src/helpers/share-link-owner/lazy-initializer.ts +29 -0
- package/src/helpers/share-link-owner-projection.ts +54 -0
- package/src/helpers/share-link-passcode-abuse.ts +36 -0
- package/src/helpers/share-link-passcode.ts +47 -0
- package/src/helpers/share-link-policy/index.ts +7 -0
- package/src/helpers/share-link-policy/production.ts +108 -0
- package/src/helpers/share-link-policy/resolver.ts +113 -0
- package/src/helpers/share-link-policy/types.ts +56 -0
- package/src/helpers/share-link-public/config.ts +41 -0
- package/src/helpers/share-link-view-notification.ts +18 -0
- package/src/helpers/signingAuthority.helpers.ts +23 -14
- package/src/helpers/smartResume.helpers.ts +123 -0
- package/src/models/AppManifestVersion.ts +43 -0
- package/src/models/AppStoreListing.ts +32 -0
- package/src/models/ConsentFlowContract.ts +34 -3
- package/src/models/ConsentFlowTerms.ts +10 -0
- package/src/models/ConsentFlowTransaction.ts +3 -0
- package/src/models/Integration.ts +2 -0
- package/src/models/Presentation.ts +2 -2
- package/src/models/Profile.ts +3 -2
- package/src/models/ShareLink.ts +134 -0
- package/src/models/ShareViewReceipt.ts +69 -0
- package/src/models/index.ts +25 -0
- package/src/models/share-link-constraints.ts +98 -0
- package/src/openapi.ts +44 -8
- package/src/public-share-link-http.ts +49 -0
- package/src/routes/app-store.ts +1056 -38
- package/src/routes/boosts.ts +14 -25
- package/src/routes/contracts.ts +384 -273
- package/src/routes/inbox.ts +4 -2
- package/src/routes/index.ts +142 -44
- package/src/routes/presentations.ts +19 -3
- package/src/routes/profile-manager.ts +29 -2
- package/src/routes/profiles.ts +29 -6
- package/src/routes/public-share-links.ts +983 -0
- package/src/routes/share-links.ts +709 -0
- package/src/routes/workflows.ts +3 -2
- package/src/services/delivery/adapters/postmark.adapter.ts +4 -1
- package/src/types/app-manifest.ts +28 -0
- package/src/types/app-store-listing.ts +13 -0
- package/src/types/consentflowcontract.ts +25 -4
- package/test/app-manifest.helpers.spec.ts +170 -0
- package/test/app-manifest.routes.spec.ts +299 -0
- package/test/app-store-listing-updates.spec.ts +236 -0
- package/test/app-store-listing.spec.ts +65 -3
- package/test/consent-data-boundaries.spec.ts +352 -0
- package/test/consent-recipients.spec.ts +513 -0
- package/test/consent-scopes.helpers.spec.ts +67 -0
- package/test/consentflow.spec.ts +63 -2
- package/test/contract-requests.spec.ts +1588 -0
- package/test/credential-storage.neo4j.spec.ts +122 -0
- package/test/dids.spec.ts +10 -1
- package/test/guardian-gated-routes.spec.ts +49 -0
- package/test/helpers/share-link-fixtures.ts +94 -0
- package/test/inbox-security.e2e.ts +26 -10
- package/test/inbox.spec.ts +184 -8
- package/test/inline-template.helpers.spec.ts +49 -0
- package/test/managed-recipient-inbox.spec.ts +152 -0
- package/test/notificationMessages.spec.ts +13 -0
- package/test/openapi.spec.ts +14 -53
- package/test/presentations.spec.ts +54 -6
- package/test/profiles.spec.ts +97 -1
- package/test/share-content-client.contract.spec.ts +365 -0
- package/test/share-content-client.unit.spec.ts +462 -0
- package/test/share-link-abuse.unit.spec.ts +65 -0
- package/test/share-link-attachment.neo4j.spec.ts +262 -0
- package/test/share-link-attachment.unit.spec.ts +244 -0
- package/test/share-link-coordinator.neo4j.spec.ts +684 -0
- package/test/share-link-coordinator.unit.spec.ts +990 -0
- package/test/share-link-dependency-diagnostics.unit.spec.ts +127 -0
- package/test/share-link-lifecycle.neo4j.spec.ts +1411 -0
- package/test/share-link-lifecycle.unit.spec.ts +205 -0
- package/test/share-link-list-cursor.unit.spec.ts +86 -0
- package/test/share-link-list.neo4j.spec.ts +324 -0
- package/test/share-link-maintenance.neo4j.spec.ts +355 -0
- package/test/share-link-maintenance.unit.spec.ts +1140 -0
- package/test/share-link-owner-policy.unit.spec.ts +210 -0
- package/test/share-link-owner-route.unit.spec.ts +820 -0
- package/test/share-link-owner-runtime.unit.spec.ts +102 -0
- package/test/share-link-passcode.unit.spec.ts +29 -0
- package/test/share-link-policy.unit.spec.ts +149 -0
- package/test/share-link-presentation-metadata.unit.spec.ts +49 -0
- package/test/share-link-production-policy.unit.spec.ts +126 -0
- package/test/share-link-public-config.unit.spec.ts +64 -0
- package/test/share-link-public-http-adapter.unit.spec.ts +315 -0
- package/test/share-link-public-route.unit.spec.ts +1079 -0
- package/test/share-link-receipt.neo4j.spec.ts +943 -0
- package/test/share-link-recovery.neo4j.spec.ts +935 -0
- package/test/share-link-recovery.unit.spec.ts +726 -0
- package/test/share-link-service-policy.neo4j.spec.ts +403 -0
- package/test/signing-authority-encryption.spec.ts +75 -0
- package/test/smart-resume-consent.spec.ts +233 -0
- package/test/smart-resume-upload.spec.ts +65 -0
- package/tsconfig.build.json +1 -1
- package/tsconfig.json +1 -0
- package/vitest.config.ts +14 -0
- package/vitest.inbox-e2e.config.ts +2 -0
- package/vitest.share-links-neo4j.config.ts +19 -0
- package/vitest.share-links-unit.config.ts +28 -0
- package/workerLambda.test.ts +100 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LC-2187 share-link lifecycle constants and literals.
|
|
3
|
+
*
|
|
4
|
+
* This module is intentionally storage- and transport-agnostic: routes, the
|
|
5
|
+
* LearnCloud client and the reconciliation worker all derive their bounds from
|
|
6
|
+
* here so the Brain repository and the tests agree on one set of numbers.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** Operation kinds that are bound to an idempotency record. */
|
|
10
|
+
export type ShareLinkOperationKind = 'create' | 'update' | 'revoke';
|
|
11
|
+
|
|
12
|
+
export const SHARE_LINK_OPERATION_KINDS: readonly ShareLinkOperationKind[] = [
|
|
13
|
+
'create',
|
|
14
|
+
'update',
|
|
15
|
+
'revoke',
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Default bounded lease for one in-flight share content operation. A worker that
|
|
20
|
+
* cannot finish staging + finalize within the lease loses its fence and must not
|
|
21
|
+
* commit; a later reservation supersedes it with a higher generation.
|
|
22
|
+
*/
|
|
23
|
+
export const SHARE_LINK_DEFAULT_LEASE_MS = 2 * 60 * 1000;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Retain completed operation records for 30 days.
|
|
27
|
+
*
|
|
28
|
+
* Pruning is an explicit operator action, not an automatic replay path. After a
|
|
29
|
+
* record is pruned, object-reference uniqueness, the share version compare-and-set
|
|
30
|
+
* and the `stopped` terminal state still prevent a replay from overwriting newer
|
|
31
|
+
* content.
|
|
32
|
+
*/
|
|
33
|
+
export const SHARE_LINK_OPERATION_RETENTION_MS = 30 * 24 * 60 * 60 * 1000;
|
|
34
|
+
|
|
35
|
+
/** Cleanup retry backoff bounds (exponential, capped). */
|
|
36
|
+
export const SHARE_LINK_CLEANUP_BASE_BACKOFF_MS = 30 * 1000;
|
|
37
|
+
export const SHARE_LINK_CLEANUP_MAX_BACKOFF_MS = 24 * 60 * 60 * 1000;
|
|
38
|
+
|
|
39
|
+
/** Default cap on cleanup jobs claimed in one bounded batch. */
|
|
40
|
+
export const SHARE_LINK_CLEANUP_DEFAULT_BATCH = 25;
|
|
41
|
+
export const SHARE_LINK_CLEANUP_MAX_BATCH = 100;
|
|
42
|
+
|
|
43
|
+
/** Default lease for a claimed cleanup job. */
|
|
44
|
+
export const SHARE_LINK_CLEANUP_DEFAULT_CLAIM_MS = 5 * 60 * 1000;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Hard bounds for a caller-supplied cleanup claim lease. A configured
|
|
48
|
+
* maintenance lease is clamped into this window so a bad deployment cannot hold
|
|
49
|
+
* (or instantly drop) work; the repository default is unchanged.
|
|
50
|
+
*/
|
|
51
|
+
export const SHARE_LINK_CLEANUP_MIN_CLAIM_MS = 1_000;
|
|
52
|
+
export const SHARE_LINK_CLEANUP_MAX_CLAIM_MS = 30 * 60 * 1000;
|
|
53
|
+
|
|
54
|
+
/** Reasons a durable cleanup job can be created. */
|
|
55
|
+
export type ShareContentCleanupReason = 'superseded' | 'abandoned' | 'stopped';
|
|
56
|
+
|
|
57
|
+
/** Lifecycle status of a durable cleanup job. */
|
|
58
|
+
export type ShareContentCleanupStatus = 'queued' | 'claimed' | 'completed';
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { MaintenanceBudget } from '../share-link-coordinator';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Monotonic wall-clock budget for one maintenance pass.
|
|
5
|
+
*
|
|
6
|
+
* The runner checks `exhausted()` before each claim; once the remaining time is
|
|
7
|
+
* at or below `finalizeReserveMs` it must stop starting new graph/remote work so
|
|
8
|
+
* the pass can still log and return a summary. This is a cooperative deadline,
|
|
9
|
+
* not a hard kill: it never uses `Promise.race`, which would leave an untracked
|
|
10
|
+
* mutation running after the pass returned.
|
|
11
|
+
*/
|
|
12
|
+
export type MaintenancePassBudget = MaintenanceBudget & {
|
|
13
|
+
elapsedMs: () => number;
|
|
14
|
+
configuredMs: number;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const defaultMonotonicNow = (): number =>
|
|
18
|
+
typeof performance !== 'undefined' && typeof performance.now === 'function'
|
|
19
|
+
? performance.now()
|
|
20
|
+
: Date.now();
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Resolve the pass budget from a Lambda remaining-time value.
|
|
24
|
+
*
|
|
25
|
+
* `undefined` means "no Lambda signal" and keeps the configured budget. Any
|
|
26
|
+
* other value failing the finite/positive check — NaN, Infinity, negative or
|
|
27
|
+
* zero — fails closed to a zero budget so the pass does no work.
|
|
28
|
+
*/
|
|
29
|
+
export const resolveMaintenanceBudgetMs = (
|
|
30
|
+
configuredBudgetMs: number,
|
|
31
|
+
remainingTimeMs: number | undefined
|
|
32
|
+
): number => {
|
|
33
|
+
if (remainingTimeMs === undefined) return configuredBudgetMs;
|
|
34
|
+
if (!Number.isFinite(remainingTimeMs) || remainingTimeMs <= 0) return 0;
|
|
35
|
+
|
|
36
|
+
return Math.min(configuredBudgetMs, Math.trunc(remainingTimeMs));
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const createMaintenancePassBudget = (input: {
|
|
40
|
+
budgetMs: number;
|
|
41
|
+
finalizeReserveMs: number;
|
|
42
|
+
monotonicNow?: () => number;
|
|
43
|
+
}): MaintenancePassBudget => {
|
|
44
|
+
const monotonicNow = input.monotonicNow ?? defaultMonotonicNow;
|
|
45
|
+
const configuredMs = Number.isFinite(input.budgetMs)
|
|
46
|
+
? Math.max(0, Math.trunc(input.budgetMs))
|
|
47
|
+
: 0;
|
|
48
|
+
const reserveMs = Number.isFinite(input.finalizeReserveMs)
|
|
49
|
+
? Math.max(0, Math.trunc(input.finalizeReserveMs))
|
|
50
|
+
: 0;
|
|
51
|
+
const startedAt = monotonicNow();
|
|
52
|
+
const deadline = startedAt + configuredMs;
|
|
53
|
+
|
|
54
|
+
const remainingMs = (): number => deadline - monotonicNow();
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
configuredMs,
|
|
58
|
+
elapsedMs: () => monotonicNow() - startedAt,
|
|
59
|
+
remainingMs,
|
|
60
|
+
reserveMs: () => reserveMs,
|
|
61
|
+
exhausted: () => remainingMs() <= reserveMs,
|
|
62
|
+
};
|
|
63
|
+
};
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SHARE_LINK_CLEANUP_DEFAULT_BATCH,
|
|
3
|
+
SHARE_LINK_CLEANUP_DEFAULT_CLAIM_MS,
|
|
4
|
+
SHARE_LINK_CLEANUP_MAX_BATCH,
|
|
5
|
+
SHARE_LINK_CLEANUP_MAX_CLAIM_MS,
|
|
6
|
+
SHARE_LINK_CLEANUP_MIN_CLAIM_MS,
|
|
7
|
+
SHARE_LINK_DEFAULT_LEASE_MS,
|
|
8
|
+
} from '../share-link-lifecycle';
|
|
9
|
+
import {
|
|
10
|
+
SHARE_LINK_RECOVERY_DEFAULT_BATCH,
|
|
11
|
+
SHARE_LINK_RECOVERY_MAX_BATCH,
|
|
12
|
+
} from '../share-link-lifecycle/recovery.helpers';
|
|
13
|
+
import { validateShareContentOrigin } from '../share-content-client/config';
|
|
14
|
+
import type { ShareLinkMaintenanceConfig, ShareLinkMaintenanceConfigResolution } from './types';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Operator-facing configuration for the automatic share-link maintenance pass.
|
|
18
|
+
*
|
|
19
|
+
* Every value is read and validated here rather than in the global environment
|
|
20
|
+
* schema so malformed maintenance settings fail closed to a fixed category
|
|
21
|
+
* instead of preventing the whole Brain service from booting. Absent or
|
|
22
|
+
* invalid configuration must perform no graph or remote I/O and must not
|
|
23
|
+
* initialize a signer.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
export const SHARE_LINK_MAINTENANCE_ENV = {
|
|
27
|
+
NAMESPACE: 'SHARE_LINK_MAINTENANCE_NAMESPACE',
|
|
28
|
+
ORIGIN: 'SHARE_LINK_MAINTENANCE_ORIGIN',
|
|
29
|
+
AUDIENCE: 'SHARE_LINK_MAINTENANCE_AUDIENCE',
|
|
30
|
+
ALLOW_INSECURE_LOOPBACK: 'SHARE_LINK_MAINTENANCE_ALLOW_INSECURE_LOOPBACK',
|
|
31
|
+
CLAIMANT: 'SHARE_LINK_MAINTENANCE_CLAIMANT',
|
|
32
|
+
RECOVERY_LIMIT: 'SHARE_LINK_MAINTENANCE_RECOVERY_LIMIT',
|
|
33
|
+
CLEANUP_LIMIT: 'SHARE_LINK_MAINTENANCE_CLEANUP_LIMIT',
|
|
34
|
+
RECEIPT_PRUNE_LIMIT: 'SHARE_LINK_MAINTENANCE_RECEIPT_PRUNE_LIMIT',
|
|
35
|
+
LEASE_MS: 'SHARE_LINK_MAINTENANCE_LEASE_MS',
|
|
36
|
+
CLAIM_MS: 'SHARE_LINK_MAINTENANCE_CLAIM_MS',
|
|
37
|
+
BUDGET_MS: 'SHARE_LINK_MAINTENANCE_BUDGET_MS',
|
|
38
|
+
INTERVAL_MS: 'SHARE_LINK_MAINTENANCE_INTERVAL_MS',
|
|
39
|
+
REQUEST_TIMEOUT_MS: 'SHARE_LINK_MAINTENANCE_REQUEST_TIMEOUT_MS',
|
|
40
|
+
FINALIZE_RESERVE_MS: 'SHARE_LINK_MAINTENANCE_FINALIZE_RESERVE_MS',
|
|
41
|
+
GRAPH_TIMEOUT_MS: 'SHARE_LINK_MAINTENANCE_GRAPH_TIMEOUT_MS',
|
|
42
|
+
} as const;
|
|
43
|
+
|
|
44
|
+
export const SHARE_LINK_MAINTENANCE_DEFAULTS = Object.freeze({
|
|
45
|
+
claimant: 'brain-share-link-maintenance',
|
|
46
|
+
recoveryLimit: SHARE_LINK_RECOVERY_DEFAULT_BATCH,
|
|
47
|
+
cleanupLimit: SHARE_LINK_CLEANUP_DEFAULT_BATCH,
|
|
48
|
+
receiptPruneLimit: 200,
|
|
49
|
+
leaseMs: SHARE_LINK_DEFAULT_LEASE_MS,
|
|
50
|
+
claimMs: SHARE_LINK_CLEANUP_DEFAULT_CLAIM_MS,
|
|
51
|
+
budgetMs: 60_000,
|
|
52
|
+
intervalMs: 300_000,
|
|
53
|
+
requestTimeoutMs: 10_000,
|
|
54
|
+
finalizeReserveMs: 5_000,
|
|
55
|
+
graphTimeoutMs: 15_000,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export const SHARE_LINK_MAINTENANCE_INVALID_CATEGORY =
|
|
59
|
+
'share_link_maintenance_configuration_invalid' as const;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Transport/service-client portion of the share-content configuration.
|
|
63
|
+
*
|
|
64
|
+
* Owner/public APIs and maintenance use the same validated namespace, origin,
|
|
65
|
+
* and audience. No backend rollout flag is required.
|
|
66
|
+
*/
|
|
67
|
+
export type ShareLinkServiceTransportConfig = {
|
|
68
|
+
namespace: string;
|
|
69
|
+
origin: string;
|
|
70
|
+
audience: string;
|
|
71
|
+
allowInsecureLoopback: boolean;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export type ShareLinkServiceTransportConfigResolution =
|
|
75
|
+
{ status: 'enabled'; config: ShareLinkServiceTransportConfig } | { status: 'invalid' };
|
|
76
|
+
|
|
77
|
+
/** Whether any required service wiring has been supplied (empty deployment defaults are absent). */
|
|
78
|
+
export const hasShareLinkServiceTransportConfig = (source: Record<string, unknown>): boolean =>
|
|
79
|
+
[
|
|
80
|
+
SHARE_LINK_MAINTENANCE_ENV.NAMESPACE,
|
|
81
|
+
SHARE_LINK_MAINTENANCE_ENV.ORIGIN,
|
|
82
|
+
SHARE_LINK_MAINTENANCE_ENV.AUDIENCE,
|
|
83
|
+
].some(key => source[key] !== undefined && source[key] !== null && source[key] !== '');
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Validate service-client transport fields without echoing values or exceptions.
|
|
87
|
+
*/
|
|
88
|
+
export const resolveShareLinkServiceTransportConfig = (
|
|
89
|
+
raw: unknown
|
|
90
|
+
): ShareLinkServiceTransportConfigResolution => {
|
|
91
|
+
if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
|
|
92
|
+
return { status: 'invalid' };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const source = raw as Record<string, unknown>;
|
|
96
|
+
const allowInsecureLoopback = parseDeliberateBoolean(
|
|
97
|
+
source[SHARE_LINK_MAINTENANCE_ENV.ALLOW_INSECURE_LOOPBACK]
|
|
98
|
+
);
|
|
99
|
+
if (allowInsecureLoopback === null) return { status: 'invalid' };
|
|
100
|
+
const insecureLoopbackAllowed = allowInsecureLoopback === true;
|
|
101
|
+
|
|
102
|
+
const origin = validateShareContentOrigin(
|
|
103
|
+
source[SHARE_LINK_MAINTENANCE_ENV.ORIGIN],
|
|
104
|
+
insecureLoopbackAllowed
|
|
105
|
+
);
|
|
106
|
+
if (!origin.ok) return { status: 'invalid' };
|
|
107
|
+
|
|
108
|
+
const namespace = source[SHARE_LINK_MAINTENANCE_ENV.NAMESPACE];
|
|
109
|
+
if (!isOpaqueIdentifier(namespace)) return { status: 'invalid' };
|
|
110
|
+
|
|
111
|
+
const audience = source[SHARE_LINK_MAINTENANCE_ENV.AUDIENCE];
|
|
112
|
+
if (typeof audience !== 'string' || !audience.startsWith('did:')) {
|
|
113
|
+
return { status: 'invalid' };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
status: 'enabled',
|
|
118
|
+
config: {
|
|
119
|
+
namespace,
|
|
120
|
+
origin: origin.origin,
|
|
121
|
+
audience,
|
|
122
|
+
allowInsecureLoopback: insecureLoopbackAllowed,
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const OPAQUE_IDENTIFIER_RE = /^[A-Za-z0-9._~-]+$/;
|
|
128
|
+
|
|
129
|
+
const isOpaqueIdentifier = (value: unknown, maxLength = 128): value is string =>
|
|
130
|
+
typeof value === 'string' &&
|
|
131
|
+
value.length >= 1 &&
|
|
132
|
+
value.length <= maxLength &&
|
|
133
|
+
OPAQUE_IDENTIFIER_RE.test(value);
|
|
134
|
+
|
|
135
|
+
const MISSING = Symbol('missing');
|
|
136
|
+
|
|
137
|
+
/** Deliberate boolean parse: only booleans and the exact strings true/false. */
|
|
138
|
+
const parseDeliberateBoolean = (value: unknown): boolean | typeof MISSING | null => {
|
|
139
|
+
if (value === undefined || value === null || value === '') return MISSING;
|
|
140
|
+
if (typeof value === 'boolean') return value;
|
|
141
|
+
if (typeof value === 'string') {
|
|
142
|
+
const normalized = value.trim().toLowerCase();
|
|
143
|
+
if (normalized === 'true') return true;
|
|
144
|
+
if (normalized === 'false') return false;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return null;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
type BoundedIntegerOptions = { minimum: number; maximum: number; fallback: number };
|
|
151
|
+
|
|
152
|
+
const parseBoundedInteger = (
|
|
153
|
+
value: unknown,
|
|
154
|
+
options: BoundedIntegerOptions
|
|
155
|
+
): number | typeof MISSING | null => {
|
|
156
|
+
if (value === undefined || value === null || value === '') return MISSING;
|
|
157
|
+
|
|
158
|
+
let parsed: number;
|
|
159
|
+
if (typeof value === 'number') parsed = value;
|
|
160
|
+
else if (typeof value === 'string' && /^[0-9]+$/.test(value.trim()))
|
|
161
|
+
parsed = Number(value.trim());
|
|
162
|
+
else return null;
|
|
163
|
+
|
|
164
|
+
if (!Number.isSafeInteger(parsed) || parsed < options.minimum || parsed > options.maximum)
|
|
165
|
+
return null;
|
|
166
|
+
|
|
167
|
+
return parsed;
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const invalid = (): ShareLinkMaintenanceConfigResolution => ({
|
|
171
|
+
status: 'invalid',
|
|
172
|
+
category: SHARE_LINK_MAINTENANCE_INVALID_CATEGORY,
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Resolve maintenance configuration from a raw record (typically `process.env`).
|
|
177
|
+
* Never throws and never echoes a value.
|
|
178
|
+
*/
|
|
179
|
+
export const resolveShareLinkMaintenanceConfig = (
|
|
180
|
+
raw: unknown
|
|
181
|
+
): ShareLinkMaintenanceConfigResolution => {
|
|
182
|
+
if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) return invalid();
|
|
183
|
+
|
|
184
|
+
const source = raw as Record<string, unknown>;
|
|
185
|
+
if (!hasShareLinkServiceTransportConfig(source)) return { status: 'disabled' };
|
|
186
|
+
|
|
187
|
+
const transport = resolveShareLinkServiceTransportConfig(source);
|
|
188
|
+
if (transport.status !== 'enabled') return invalid();
|
|
189
|
+
|
|
190
|
+
const { namespace, origin, audience, allowInsecureLoopback } = transport.config;
|
|
191
|
+
|
|
192
|
+
const claimantValue = source[SHARE_LINK_MAINTENANCE_ENV.CLAIMANT];
|
|
193
|
+
const claimant =
|
|
194
|
+
claimantValue === undefined || claimantValue === ''
|
|
195
|
+
? SHARE_LINK_MAINTENANCE_DEFAULTS.claimant
|
|
196
|
+
: claimantValue;
|
|
197
|
+
if (!isOpaqueIdentifier(claimant)) return invalid();
|
|
198
|
+
|
|
199
|
+
const numericFields: Array<[string, BoundedIntegerOptions]> = [
|
|
200
|
+
[
|
|
201
|
+
SHARE_LINK_MAINTENANCE_ENV.RECOVERY_LIMIT,
|
|
202
|
+
{
|
|
203
|
+
minimum: 1,
|
|
204
|
+
maximum: SHARE_LINK_RECOVERY_MAX_BATCH,
|
|
205
|
+
fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.recoveryLimit,
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
[
|
|
209
|
+
SHARE_LINK_MAINTENANCE_ENV.CLEANUP_LIMIT,
|
|
210
|
+
{
|
|
211
|
+
minimum: 1,
|
|
212
|
+
maximum: SHARE_LINK_CLEANUP_MAX_BATCH,
|
|
213
|
+
fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.cleanupLimit,
|
|
214
|
+
},
|
|
215
|
+
],
|
|
216
|
+
[
|
|
217
|
+
SHARE_LINK_MAINTENANCE_ENV.RECEIPT_PRUNE_LIMIT,
|
|
218
|
+
{
|
|
219
|
+
minimum: 1,
|
|
220
|
+
maximum: 1_000,
|
|
221
|
+
fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.receiptPruneLimit,
|
|
222
|
+
},
|
|
223
|
+
],
|
|
224
|
+
[
|
|
225
|
+
SHARE_LINK_MAINTENANCE_ENV.LEASE_MS,
|
|
226
|
+
{
|
|
227
|
+
minimum: 1_000,
|
|
228
|
+
maximum: 30 * 60 * 1000,
|
|
229
|
+
fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.leaseMs,
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
[
|
|
233
|
+
SHARE_LINK_MAINTENANCE_ENV.CLAIM_MS,
|
|
234
|
+
{
|
|
235
|
+
minimum: SHARE_LINK_CLEANUP_MIN_CLAIM_MS,
|
|
236
|
+
maximum: SHARE_LINK_CLEANUP_MAX_CLAIM_MS,
|
|
237
|
+
fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.claimMs,
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
[
|
|
241
|
+
SHARE_LINK_MAINTENANCE_ENV.BUDGET_MS,
|
|
242
|
+
{
|
|
243
|
+
minimum: 1_000,
|
|
244
|
+
maximum: 240_000,
|
|
245
|
+
fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.budgetMs,
|
|
246
|
+
},
|
|
247
|
+
],
|
|
248
|
+
[
|
|
249
|
+
SHARE_LINK_MAINTENANCE_ENV.INTERVAL_MS,
|
|
250
|
+
{
|
|
251
|
+
minimum: 1_000,
|
|
252
|
+
maximum: 60 * 60 * 1000,
|
|
253
|
+
fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.intervalMs,
|
|
254
|
+
},
|
|
255
|
+
],
|
|
256
|
+
[
|
|
257
|
+
SHARE_LINK_MAINTENANCE_ENV.REQUEST_TIMEOUT_MS,
|
|
258
|
+
{
|
|
259
|
+
minimum: 100,
|
|
260
|
+
maximum: 30_000,
|
|
261
|
+
fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.requestTimeoutMs,
|
|
262
|
+
},
|
|
263
|
+
],
|
|
264
|
+
[
|
|
265
|
+
SHARE_LINK_MAINTENANCE_ENV.FINALIZE_RESERVE_MS,
|
|
266
|
+
{
|
|
267
|
+
minimum: 100,
|
|
268
|
+
maximum: 120_000,
|
|
269
|
+
fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.finalizeReserveMs,
|
|
270
|
+
},
|
|
271
|
+
],
|
|
272
|
+
[
|
|
273
|
+
SHARE_LINK_MAINTENANCE_ENV.GRAPH_TIMEOUT_MS,
|
|
274
|
+
{
|
|
275
|
+
minimum: 100,
|
|
276
|
+
maximum: 120_000,
|
|
277
|
+
fallback: SHARE_LINK_MAINTENANCE_DEFAULTS.graphTimeoutMs,
|
|
278
|
+
},
|
|
279
|
+
],
|
|
280
|
+
];
|
|
281
|
+
|
|
282
|
+
const resolved: Record<string, number> = {};
|
|
283
|
+
for (const [key, options] of numericFields) {
|
|
284
|
+
const parsed = parseBoundedInteger(source[key], options);
|
|
285
|
+
if (parsed === null) return invalid();
|
|
286
|
+
resolved[key] = parsed === MISSING ? options.fallback : parsed;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const budgetMs = resolved[SHARE_LINK_MAINTENANCE_ENV.BUDGET_MS] as number;
|
|
290
|
+
const finalizeReserveMs = resolved[SHARE_LINK_MAINTENANCE_ENV.FINALIZE_RESERVE_MS] as number;
|
|
291
|
+
if (finalizeReserveMs >= budgetMs) return invalid();
|
|
292
|
+
|
|
293
|
+
const config: ShareLinkMaintenanceConfig = {
|
|
294
|
+
namespace,
|
|
295
|
+
origin,
|
|
296
|
+
audience,
|
|
297
|
+
allowInsecureLoopback,
|
|
298
|
+
claimant,
|
|
299
|
+
recoveryLimit: resolved[SHARE_LINK_MAINTENANCE_ENV.RECOVERY_LIMIT] as number,
|
|
300
|
+
cleanupLimit: resolved[SHARE_LINK_MAINTENANCE_ENV.CLEANUP_LIMIT] as number,
|
|
301
|
+
receiptPruneLimit: resolved[SHARE_LINK_MAINTENANCE_ENV.RECEIPT_PRUNE_LIMIT] as number,
|
|
302
|
+
leaseMs: resolved[SHARE_LINK_MAINTENANCE_ENV.LEASE_MS] as number,
|
|
303
|
+
claimMs: resolved[SHARE_LINK_MAINTENANCE_ENV.CLAIM_MS] as number,
|
|
304
|
+
budgetMs,
|
|
305
|
+
intervalMs: resolved[SHARE_LINK_MAINTENANCE_ENV.INTERVAL_MS] as number,
|
|
306
|
+
requestTimeoutMs: resolved[SHARE_LINK_MAINTENANCE_ENV.REQUEST_TIMEOUT_MS] as number,
|
|
307
|
+
finalizeReserveMs,
|
|
308
|
+
graphTimeoutMs: resolved[SHARE_LINK_MAINTENANCE_ENV.GRAPH_TIMEOUT_MS] as number,
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
return { status: 'enabled', config };
|
|
312
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export * from './types';
|
|
2
|
+
export {
|
|
3
|
+
SHARE_LINK_MAINTENANCE_DEFAULTS,
|
|
4
|
+
SHARE_LINK_MAINTENANCE_ENV,
|
|
5
|
+
SHARE_LINK_MAINTENANCE_INVALID_CATEGORY,
|
|
6
|
+
resolveShareLinkMaintenanceConfig,
|
|
7
|
+
} from './config';
|
|
8
|
+
export { createMaintenancePassBudget, type MaintenancePassBudget } from './budget';
|
|
9
|
+
export {
|
|
10
|
+
createConsoleMaintenanceLogger,
|
|
11
|
+
safeLogMaintenance,
|
|
12
|
+
toMaintenanceLogEvent,
|
|
13
|
+
} from './telemetry';
|
|
14
|
+
export { runShareLinkMaintenancePass, type ShareLinkMaintenanceRunnerDependencies } from './runner';
|
|
15
|
+
export {
|
|
16
|
+
createShareLinkMaintenanceScheduler,
|
|
17
|
+
type ShareLinkMaintenanceScheduler,
|
|
18
|
+
type ShareLinkMaintenanceSchedulerDependencies,
|
|
19
|
+
} from './scheduler';
|
|
20
|
+
export {
|
|
21
|
+
createShareLinkMaintenanceRuntime,
|
|
22
|
+
type CreateShareLinkMaintenanceRuntimeOptions,
|
|
23
|
+
type ShareLinkMaintenanceRuntime,
|
|
24
|
+
} from './runtime';
|