@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
package/.env.example
CHANGED
|
@@ -1,94 +1,59 @@
|
|
|
1
|
-
# Brain service
|
|
2
|
-
#
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
# Brain service: copy to .env. These values are disposable local examples, not deploy secrets.
|
|
2
|
+
# Public settings live in config/config.json and config/config.<stage>.json.
|
|
3
|
+
# Precedence: schema defaults < base < stage < Lambda runtime bundle < non-empty real env.
|
|
4
|
+
# CONFIG_STAGE=dev or production opts local/Docker/offline into a checked-in stage.
|
|
5
|
+
# Without CONFIG_STAGE, keep using local env and schema defaults as before.
|
|
6
|
+
# Lambda selects LAMBDA_STAGE; its bundle is brain-service/<stage>/runtime-secrets.
|
|
7
|
+
# RUNTIME_SECRETS_ID is ignored outside Lambda. Keep GitHub fallbacks for rollback.
|
|
8
|
+
CONFIG_STAGE=
|
|
9
|
+
RUNTIME_SECRETS_ID=
|
|
10
|
+
|
|
11
|
+
# Required credentials. Replace every local example before connecting to shared services.
|
|
6
12
|
SEED=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
7
13
|
NEO4J_URI=bolt://localhost:7687
|
|
8
14
|
NEO4J_USERNAME=neo4j
|
|
9
|
-
NEO4J_PASSWORD=password
|
|
10
|
-
DOMAIN_NAME=
|
|
11
|
-
CLIENT_APP_DOMAIN_NAME=
|
|
12
|
-
CLIENT_APP_PORT=3000
|
|
13
|
-
LOGIN_PROVIDER_DID=
|
|
14
|
-
|
|
15
|
-
APP_STORE_ADMIN_PROFILE_IDS=
|
|
16
|
-
SKILL_FRAMEWORK_ADMIN_PROFILE_IDS=
|
|
17
|
-
SKILL_FRAMEWORK_SEED_OWNER_PROFILE_ID=
|
|
18
|
-
TRUSTED_BRAIN_SERVICES=
|
|
19
|
-
TRUSTED_ISSUERS_WHITELIST=
|
|
20
|
-
OIDC_TRUSTED_ISSUERS=
|
|
21
|
-
OIDC_EXPECTED_AUDIENCE=
|
|
22
|
-
|
|
23
|
-
AWS_REGION=
|
|
24
|
-
NOTIFICATIONS_QUEUE_URL=
|
|
25
|
-
INBOX_QUEUE_URL=
|
|
26
|
-
INBOX_DEAD_LETTER_QUEUE_URL=
|
|
27
|
-
# Set only for a local SQS emulator; production uses the AWS endpoint and IAM role.
|
|
28
|
-
INBOX_QUEUE_ENDPOINT=
|
|
29
|
-
NOTIFICATIONS_QUEUE_POLL_URL=
|
|
30
|
-
NOTIFICATIONS_SERVICE_WEBHOOK_URL=
|
|
31
|
-
NOTIFICATIONS_SERVICE_PORT=5100
|
|
32
|
-
BRAIN_SERVICE_REGISTRY_URL=
|
|
33
|
-
DCC_KNOWN_REGISTRIES_URL=
|
|
34
|
-
OPENSALT_BASE_URL=
|
|
35
|
-
OPENSALT_STAGING_BASE_URL=
|
|
36
|
-
|
|
37
|
-
SKILLS_PROVIDER=
|
|
38
|
-
SKILLS_PROVIDER_API_KEY=
|
|
39
|
-
SKILLS_PROVIDER_BASE_URL=
|
|
40
|
-
SKILL_EMBEDDING_GOOGLE_API_KEY=
|
|
41
|
-
SKILL_EMBEDDING_GOOGLE_MODEL=
|
|
42
|
-
SKILL_EMBEDDING_CACHE_TTL_SECONDS=
|
|
43
|
-
SKILL_EMBEDDING_BATCH_SIZE=
|
|
44
|
-
SKILL_EMBEDDING_BACKFILL_BATCH_SIZE=
|
|
45
|
-
SKILL_EMBEDDING_BACKFILL_LOCK_TTL_SECONDS=
|
|
46
|
-
SKILL_EMBEDDING_BACKFILL_PAGE_SIZE=
|
|
47
|
-
SKILL_SEMANTIC_SEARCH_RATE_LIMIT_PER_MIN=
|
|
15
|
+
NEO4J_PASSWORD=this-is-the-password
|
|
48
16
|
|
|
17
|
+
# Optional integration credentials; all are bundle/fallback-only in Lambda.
|
|
49
18
|
POSTMARK_API_KEY=
|
|
50
|
-
|
|
51
|
-
|
|
19
|
+
MESSAGEBIRD_AUTH_TOKEN=
|
|
20
|
+
SENTRY_DSN=
|
|
21
|
+
POSTHOG_API_KEY=
|
|
22
|
+
SKILL_EMBEDDING_GOOGLE_API_KEY=
|
|
23
|
+
SKILLS_PROVIDER_API_KEY=
|
|
52
24
|
TWILIO_ACCOUNT_SID=
|
|
53
25
|
TWILIO_AUTH_TOKEN=
|
|
54
|
-
TWILIO_FROM_NUMBER=
|
|
55
|
-
MESSAGEBIRD_AUTH_TOKEN=
|
|
56
|
-
MESSAGEBIRD_ORIGINATOR=
|
|
57
|
-
SMART_RESUME_ACCESS_KEY=
|
|
58
26
|
SMART_RESUME_CLIENT_ID=
|
|
27
|
+
SMART_RESUME_ACCESS_KEY=
|
|
59
28
|
SMART_RESUME_CONTRACT_URI=
|
|
29
|
+
APP_STORE_ADMIN_PROFILE_IDS=
|
|
30
|
+
LOGIN_PROVIDER_DID=
|
|
31
|
+
NOTIFICATIONS_SERVICE_WEBHOOK_URL=
|
|
32
|
+
# Both checked-in stages enable credential refresh. Use independent, stable private secrets.
|
|
33
|
+
CREDENTIAL_REFRESH_DIGEST_SECRET=local-only-replace-before-deploy-refresh-digest-secret
|
|
34
|
+
SHARE_LINK_REQUEST_HASH_SECRET=local-only-replace-before-deploy-share-link-request-secret
|
|
60
35
|
|
|
61
|
-
|
|
62
|
-
|
|
36
|
+
# Local infrastructure. Explicit env overrides the selected stage; unset overrides you don't want.
|
|
37
|
+
NODE_ENV=development
|
|
38
|
+
IS_OFFLINE=true
|
|
39
|
+
PORT=3000
|
|
63
40
|
REDIS_HOST=
|
|
64
41
|
REDIS_PORT=
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
BITSTRING_STATUS_LIST_ALLOW_SMALL=false
|
|
84
|
-
|
|
85
|
-
# Enable only after reviewing expired Universal Inbox audit history.
|
|
86
|
-
INBOX_DELETE_EXPIRED_RECORDS=false
|
|
87
|
-
|
|
88
|
-
# Managed credential refresh (LC-2117/LC-2135/LC-2136).
|
|
89
|
-
# Set to 'true' to mount the authenticated GET /refresh/{refreshId} endpoints.
|
|
90
|
-
# When enabled, CREDENTIAL_REFRESH_DIGEST_SECRET is required (validated at startup).
|
|
91
|
-
CREDENTIAL_REFRESH_ENABLED=false
|
|
92
|
-
CREDENTIAL_REFRESH_DIGEST_SECRET=
|
|
93
|
-
# Hours during which repeat refresh notifications collapse into one unread record.
|
|
94
|
-
CREDENTIAL_REFRESH_NOTIFICATION_WINDOW_HOURS=24
|
|
42
|
+
AWS_REGION=
|
|
43
|
+
NOTIFICATIONS_QUEUE_URL=
|
|
44
|
+
INBOX_QUEUE_URL=
|
|
45
|
+
INBOX_DEAD_LETTER_QUEUE_URL=
|
|
46
|
+
INBOX_QUEUE_ENDPOINT=
|
|
47
|
+
NOTIFICATIONS_QUEUE_POLL_URL=
|
|
48
|
+
# Non-offline self-hosters must supply DOMAIN_NAME or select a registered CONFIG_STAGE.
|
|
49
|
+
# For local DID resolution, an explicit override can be DOMAIN_NAME=localhost%3A4000.
|
|
50
|
+
|
|
51
|
+
# App-store inline templates: LCA API signing authority that apps' credentials are signed through.
|
|
52
|
+
SIGNING_AUTHORITY_ENDPOINT=http://localhost:5100/api
|
|
53
|
+
|
|
54
|
+
# Optional sample-persona seeder (not Lambda runtime configuration).
|
|
55
|
+
MONGO_URI=mongodb://localhost:27017/?replicaSet=rs0
|
|
56
|
+
MONGO_DB_NAME=lca-api
|
|
57
|
+
DEMO_PERSONA_SIGNING_AUTHORITY_ENDPOINT=http://localhost:5100/api
|
|
58
|
+
DEMO_PERSONA_SA_SEED=
|
|
59
|
+
# SENTRY_AUTH_TOKEN / SENTRY_ORG / SENTRY_PROJECT belong only in the build environment.
|
package/AGENTS.md
CHANGED
|
@@ -112,6 +112,44 @@ ConsentFlow is a consent management system where:
|
|
|
112
112
|
3. The signing authority signs the credential and returns it
|
|
113
113
|
4. The `issueCredentialWithSigningAuthority()` helper handles this flow
|
|
114
114
|
- A common pattern is to get a signing authority with `getSigningAuthorityForUserByName(profile, endpoint, name)`
|
|
115
|
+
- Known-recipient sends use the helper's `encrypt = true` default. Preserve its
|
|
116
|
+
`IssuedCredential` wrapper through storage so public status-list coordinates remain
|
|
117
|
+
available without decrypting the credential. Inbox finalization returns encrypted
|
|
118
|
+
deliveries; the network SDK decrypts them locally before returning VCs to the app.
|
|
119
|
+
- Ordinary accepted inbox finalization signs and allocates status-list indices before
|
|
120
|
+
opening its bounded Neo4j transaction (30 seconds). Retries or a lost claim race may
|
|
121
|
+
leave indices unused; this is intentional to avoid signing while holding graph locks.
|
|
122
|
+
The transaction atomically commits escrow removal, encrypted recovery, credential/
|
|
123
|
+
boost/sent/received indexes, shared claim hooks, default claimed roles, and claim audit.
|
|
124
|
+
Notifications remain outside it; invalidate permission-related caches only after commit.
|
|
125
|
+
Failed graph writes leave the pending record retryable and concurrent claims cannot
|
|
126
|
+
duplicate acceptance.
|
|
127
|
+
- CI runs `bunx nx run network-brain-service:test:inbox:e2e`, which includes
|
|
128
|
+
`test/credential-storage.neo4j.spec.ts` and `test/inbox.spec.ts`. Keep the storage
|
|
129
|
+
trust-boundary guard and finalization rollback/concurrency coverage in this CI-run
|
|
130
|
+
configuration, not only the locally invoked integration suite.
|
|
131
|
+
- Unsigned inbox subjects are bound to the verified recipient before signing; supplied
|
|
132
|
+
subject IDs are replaced. Pre-signed subjects are not rewritten.
|
|
133
|
+
- Ordinary unsigned finalization intentionally adds the issuer's profile DID as a reader
|
|
134
|
+
alongside the managed/app owner DID. This preserves the issuer's `did:key` access when
|
|
135
|
+
the signing authority uses an app `did:web` owner; it does not add the brain signer.
|
|
136
|
+
- Three interoperable delivery paths intentionally request plaintext (`LC-2201`):
|
|
137
|
+
- `routes/workflows.ts`: boost claim-link exchanges return a VC inside a presentation
|
|
138
|
+
to wallets that may not support LearnCard JWE decryption.
|
|
139
|
+
- `routes/workflows.ts`: inbox claim-link exchanges have the same interoperability requirement.
|
|
140
|
+
- `routes/boosts.ts`: federated `/send` forwards to another network's inbox endpoint,
|
|
141
|
+
whose accepted encryption format is outside this server's control.
|
|
142
|
+
- Managed refresh issuance is a separate existing boundary: refresh sends, inbox refresh
|
|
143
|
+
finalization, and refresh publication inspect the signed VC before encrypting it for
|
|
144
|
+
storage. LC-2201 does not change those refresh flows.
|
|
145
|
+
Its separate inbox finalization path does not use the ordinary-claim index transaction;
|
|
146
|
+
do not assume every refresh inbox finalization creates these network relationships.
|
|
147
|
+
Refresh inbox creation always persists `refreshId` alongside its `pending_holder`
|
|
148
|
+
aggregate; finalization dispatches those records to `finalizeInboxRefresh`, whose
|
|
149
|
+
accepted binding transitions the aggregate directly to `active`. Ordinary records
|
|
150
|
+
without `refreshId` do not own an `awaiting_claim` aggregate through this flow.
|
|
151
|
+
Normal `acceptCredential` also attempts activation after its already-received guard,
|
|
152
|
+
and the holder refresh endpoint can lazily reconcile acceptance.
|
|
115
153
|
|
|
116
154
|
### AutoBoosts
|
|
117
155
|
|
|
@@ -888,3 +926,17 @@ Tenant is resolved once per request in `createContext` via `resolveTenantFromReq
|
|
|
888
926
|
4. Call `deliveryService.send()` from the route, passing `branding: ctx.tenant?.emailBranding`.
|
|
889
927
|
|
|
890
928
|
See [Tenant-Branded Emails (architecture)](../../../docs/core-concepts/tenant-branded-emails.md) for the end-to-end flow and [Configure Tenant-Branded Emails](../../../docs/how-to-guides/configure-tenant-branded-emails.md) for operator-facing setup.
|
|
929
|
+
|
|
930
|
+
### Attributed contract requests and event delivery
|
|
931
|
+
|
|
932
|
+
- Integrator documentation lives in `docs/how-to-guides/consent-flow/brokered-referrals.md`, with the complete lifecycle sequence in `docs/core-concepts/consent-and-permissions/brokered-referral-lifecycle.md` and webhook fields in `docs/sdks/learncard-network/contract-requests-and-events.md`. Keep embedded `docs/snippets/contract-requests/` modules synchronized with `node scripts/check-docs-snippets.mjs --fix`; `tests/e2e/tests/docs-contract-requests.spec.ts` executes them against synthetic local services. The brain route `getConsentedDataForDid` is the SDK's `getConsentFlowDataForDid`; polling reconciles current state but cannot trigger learner claim/live sync. Scope grants never replace role or consent authorization.
|
|
933
|
+
- Generic `REQUESTED_FOR` edges have `requestId`, `requestedBy`, optional `externalReferenceId`/`message`, and `requestedAt`. Exact pending retries are idempotent; conflicting or terminal requests do not reopen. Legacy edges have no request ID and retain legacy AI behavior.
|
|
934
|
+
- Snapshot referral identity onto Terms and every related transaction, including issuance and maintenance. Do not infer historical correlation from the latest mutable request edge.
|
|
935
|
+
- Append `ConsentFlowEvent` + per-recipient `ConsentFlowEventDelivery` in the same locked query as consent/request state changes. The contract audience lock serializes request decisions, consent and recipient changes.
|
|
936
|
+
- `contract-events.helpers.ts` dispatches a bounded batch with leases; scheduler Lambda and Docker use the same worker. Contract notification callers opt in to typed permanent rejection errors (missing/disabled webhook or definitive HTTP 4xx, excluding 408/425/429); legacy boolean notification callers keep their behavior. Temporary failures and negative storage acknowledgements retry with exponential backoff (1 minute up to 1 hour), at most 12 claims or 24 hours from event creation. Count claims before external work so abandoned leases consume the budget. Terminal deliveries are delivered/skipped/rejected/failed; cleanup discards payload/message once all deliveries are terminal, retaining stable IDs and coarse failure reasons. Serialize fan-out completion on the event lock and recheck the lease before updating delivery state. Cleanup requires a running worker. Successful SQS enqueue completes the outbox delivery; its consumer acknowledges permanent contract rejection and leaves temporary failures to the queue policy. Consumers deduplicate `data.metadata.deliveryKey`.
|
|
937
|
+
- Recheck current audience membership and consent/category permissions before outbox delivery and again in the SQS consumer. Nonaudience requesters receive only a decision, no transaction payload or Terms URI.
|
|
938
|
+
- Referral management is separate from data access: owner/writers can inspect all requests; recipient-only callers can inspect only their own `requestedBy` requests, and targets their own incoming status. Enforce the role predicate in the Neo4j read query too, not just an earlier route check. Hidden status returns null like a missing request. Denial/cancellation fan-out is owner plus original requester, excluding the actor; suppress former broad queued deliveries. Consent data still reaches the current audience, but redact another referrer's `externalReferenceId` from metadata AND transaction.referral (and private message) unless the recipient is owner/writer or the original requester. Keep the full stored snapshot for learner-only history/exports.
|
|
939
|
+
- Referral clients pass `expectedRequestId` through SDK/consent options. Check exact ID + pending status and contract expiry under the same contract lock as consent/re-consent writes, including after a route loaded a snapshot. Direct/legacy calls omit the ID and remain independent of invitation cancellation, but expired contracts cannot accept new consent. Only actual already-consented errors count as idempotent success in the app; other conflicts return to review.
|
|
940
|
+
- Contract integration tests use `bun run test:integration -- test/contract-requests.spec.ts`; the default unit config excludes them.
|
|
941
|
+
- From the repository root, `bun run test:referrals` wraps the referral and notification integration suites with Docker preflight, a synthetic seed, container reuse disabled, readable suite results, and temporary logs. `--full` includes consent/credential regressions. It uses the existing integration global setup and mock-instance database, never a configured live database; it does not start HTTP services or test the app.
|
|
942
|
+
- Inline dispatch matches one event by its unique ID. Global cleanup uses indexed `cleanupPending=true`, removed on final cleanup; pending deliveries carry immutable `eventCreatedAt` and use separate indexed UNION branches for next attempt, age and attempts, deduplicated before claiming. The global worker runs a serialized one-time `indexed-outbox-v1` backfill for older retained bodies/pending deliveries. Drain old service writers before that backfill during rollout. Never replace this with a nullable event-ID OR or an every-tick history scan. Preserve the event lock and recheck pending deliveries after locking. The 12-attempt schedule normally exhausts after about six hours of uninterrupted failures; 24 hours is an additional age ceiling.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,152 @@
|
|
|
1
1
|
# @learncard/network-brain-service
|
|
2
2
|
|
|
3
|
+
## 4.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [#1647](https://github.com/learningeconomy/LearnCard/pull/1647) [`544d50fddf3fd93a37e4f87fd741038168f94e17`](https://github.com/learningeconomy/LearnCard/commit/544d50fddf3fd93a37e4f87fd741038168f94e17) Thanks [@smurflo2](https://github.com/smurflo2)! - fix: [LC-2201] Encrypt known-recipient server-side credential issuance and decrypt finalized inbox deliveries in the SDK. Raw inbox finalization now returns JWEs instead of plaintext VCs; deploy the updated SDK with the backend.
|
|
8
|
+
|
|
9
|
+
### Minor Changes
|
|
10
|
+
|
|
11
|
+
- [#1632](https://github.com/learningeconomy/LearnCard/pull/1632) [`6209da80c52ac056a7644dab14669192740c9dad`](https://github.com/learningeconomy/LearnCard/commit/6209da80c52ac056a7644dab14669192740c9dad) Thanks [@goblincore](https://github.com/goblincore)! - Add explicit consent contract data recipients and audience version acknowledgements. Enforce current consent status, expiry, category sharing, and recipient membership on consented data reads. Recipient additions freeze after first consent; removals immediately revoke API access and invalidate stale consent/update/sync acknowledgements.
|
|
12
|
+
|
|
13
|
+
Update existing app consent paths to review the current data audience, encrypt for all recipients, and cache copies by the full audience. Background synchronization reloads recipients and acknowledges the current version.
|
|
14
|
+
|
|
15
|
+
- [#1634](https://github.com/learningeconomy/LearnCard/pull/1634) [`5890451789b18afee45dc5ecbab3fa30aa90f085`](https://github.com/learningeconomy/LearnCard/commit/5890451789b18afee45dc5ecbab3fa30aa90f085) Thanks [@goblincore](https://github.com/goblincore)! - Add attributed generic contract requests, target-only denial, retained cancellation history, and optional referral identity on consent history and exports. Preserve legacy AI request payloads and owner-only consent behavior.
|
|
16
|
+
|
|
17
|
+
Persist correlated notification intents with consent mutations and retry via a leased Lambda/Docker worker. Fan out to the owner and current data recipients; give a requester outside that audience only a minimal decision. Recheck audience membership and current consent permissions before delivery, including queued notifications, and expose stable event and delivery IDs for downstream deduplication.
|
|
18
|
+
|
|
19
|
+
Keep app request hooks and legacy AI component props aligned with the shared request status type, including retained generic cancellations.
|
|
20
|
+
|
|
21
|
+
- [#1429](https://github.com/learningeconomy/LearnCard/pull/1429) [`1387cd0a08fa6b0a706c86a5a0376b6c7d706856`](https://github.com/learningeconomy/LearnCard/commit/1387cd0a08fa6b0a706c86a5a0376b6c7d706856) Thanks [@Custard7](https://github.com/Custard7)! - Make Partner Connect apps zero-config. Apps can send credentials from inline templates (`sendCredential({ alias, template, templateData })`) and request scoped consent (`requestConsent({ read, write, reason })`) without creating boosts or contracts in LearnCard first; the network creates and versions them on first use. New `@learncard/partner-connect-core` package holds the shared template compiler, validator, and manifest helpers.
|
|
22
|
+
|
|
23
|
+
Mock mode now captures an app manifest and offers a one-click publish link (`getCapturedManifest()`, `getPublishUrl()`), and `mock: 'auto'` also activates inside AI app-builder editor previews (Lovable, Bolt, v0, Replit) while never mocking on published app addresses. Adds template validation and preview, template issuance status and recipient queries, and a typed `PartnerConnectError`.
|
|
24
|
+
|
|
25
|
+
LearnCard gains a publish-from-link page with live preview and a consent designer, a simple app dashboard with manifest version diffs and one-step "Apply & Ship", and network routes plus plugin methods to submit, compare, and apply manifest versions. The publish page asks for the real address when an app was captured on a local or app-builder preview address.
|
|
26
|
+
|
|
27
|
+
App captures are additive: submitting a manifest merges it into the latest version (`mergeCapturedManifests`), so features a run didn't exercise are kept rather than reported as removed.
|
|
28
|
+
|
|
29
|
+
Practice mode gets a redesigned look: frosted-glass notices with clear icons and plain-language copy (at most three on screen, one on phones), and a "Practice mode" panel that lists the LearnCard features your app uses in plain words with a one-tap Publish button. Both follow the system light/dark setting and respect reduced motion.
|
|
30
|
+
|
|
31
|
+
Practice mode now remembers a separate identity for each app, so apps sharing a local address publish separately. Start over from the panel or with `resetPracticeMode()` to clear just that app's practice history. App icons are picked more accurately and can travel with the publish link as a small image, with a size limit to keep links manageable.
|
|
32
|
+
|
|
33
|
+
Calling `requestConsent()` without saying what you need now shows an amber "Choose what to ask for" notice in practice mode, and the panel marks it "Not set up yet", instead of pretending it will work when published. The publish page opens the consent setup pre-filled from what your app uses, reloads the preview once it's enabled, and checks with you before submitting without it.
|
|
34
|
+
|
|
35
|
+
- [#1429](https://github.com/learningeconomy/LearnCard/pull/1429) [`1387cd0a08fa6b0a706c86a5a0376b6c7d706856`](https://github.com/learningeconomy/LearnCard/commit/1387cd0a08fa6b0a706c86a5a0376b6c7d706856) Thanks [@Custard7](https://github.com/Custard7)! - Changes to a live App Store app now go through review. Listing edits and newly applied capabilities on a `LISTED` app are held as a pending update (`pending_update` on owner and admin listing responses) and only take effect once an admin approves them. New routes and plugin methods: `submitAppStoreListingUpdate`, `withdrawAppStoreListingUpdate`, `discardAppStoreListingUpdate`, and `adminReviewListingUpdate`; `adminGetAllListings` accepts `pendingUpdatesOnly`. `applyManifestVersion` returns `applied: false, pendingReview: true` for live apps.
|
|
36
|
+
|
|
37
|
+
The publish page and listing editor now show apps that are in review or live with their saved details, let developers withdraw a submission to make changes, and submit updates to live apps. The admin dashboard has an Updates view for reviewing them.
|
|
38
|
+
|
|
39
|
+
- [#1651](https://github.com/learningeconomy/LearnCard/pull/1651) [`267cf40291b3a63caf178857be0e57feaf5e0948`](https://github.com/learningeconomy/LearnCard/commit/267cf40291b3a63caf178857be0e57feaf5e0948) Thanks [@goblincore](https://github.com/goblincore)! - Publish Resume Builder PDFs through version-bound encrypted managed attachments. Add owner chunk staging/cleanup and guarded recipient retrieval, preserve atomic share lifecycle and passcode protection, and keep original selected credential contexts and proofs intact inside LER-RS records.
|
|
40
|
+
|
|
41
|
+
LER-RS `verifications` now uses JSON-LD `@json` so embedded original credentials retain their contexts and proofs. This changes canonicalization for newly issued LER-RS credentials; it does not rewrite or re-sign embedded source credentials.
|
|
42
|
+
|
|
43
|
+
### Patch Changes
|
|
44
|
+
|
|
45
|
+
- [#1670](https://github.com/learningeconomy/LearnCard/pull/1670) [`7656a57d30c6d80b8a25a8bb14bcd3b08b3648c2`](https://github.com/learningeconomy/LearnCard/commit/7656a57d30c6d80b8a25a8bb14bcd3b08b3648c2) Thanks [@Custard7](https://github.com/Custard7)! - Adopt the shared @learncard/service-config layered configuration model: checked-in non-secret per-stage config files (config/config.<stage>.json), lazy Lambda bootstrap that applies stage config and loads the optional runtime secrets bundle before importing the application, a CONFIG_STAGE-keyed Docker/local entrypoint, and a serverless function-environment fallback helper scoped by an IAM runtime-secrets read grant. Real environment variables always win and the GitHub-environment fallbacks remain in effect until each stage has a complete bundle.
|
|
46
|
+
|
|
47
|
+
- [#979](https://github.com/learningeconomy/LearnCard/pull/979) [`a55332b1652567bc7f3d60064a446365c134cf24`](https://github.com/learningeconomy/LearnCard/commit/a55332b1652567bc7f3d60064a446365c134cf24) Thanks [@github-actions](https://github.com/apps/github-actions)! - Export complete mutually exclusive credential-refresh publication schemas for generated clients. Regenerate the Python SDK from pinned, offline local inputs with omission-preserving models and UTC Z-only activity date filters; verify prepared requests against the unchanged server contracts.
|
|
48
|
+
|
|
49
|
+
- [#1644](https://github.com/learningeconomy/LearnCard/pull/1644) [`37a3db8ff98a35c8e9e140569a693c9e0ed00165`](https://github.com/learningeconomy/LearnCard/commit/37a3db8ff98a35c8e9e140569a693c9e0ed00165) Thanks [@smurflo2](https://github.com/smurflo2)! - fix: [LC-2225] Separate managed organizations from child consent and sharing restrictions. Preserve guardian approval history and explicitly typed children's protections, including legacy records with a service flag. Keep organization creation supported while rejecting service flags on Family and explicitly typed child creation paths.
|
|
50
|
+
|
|
51
|
+
Keep guardian-gated consent writes aligned with read and share policy for legacy service-flagged children, and prevent those children from changing their own profile type to evade protection.
|
|
52
|
+
|
|
53
|
+
- [#1429](https://github.com/learningeconomy/LearnCard/pull/1429) [`1387cd0a08fa6b0a706c86a5a0376b6c7d706856`](https://github.com/learningeconomy/LearnCard/commit/1387cd0a08fa6b0a706c86a5a0376b6c7d706856) Thanks [@Custard7](https://github.com/Custard7)! - Add a trusted-service `ensureManagedSigningAuthority` route (`POST /signing-authority/managed`) that returns or creates a named signing authority for an owner DID through the standard encrypted-seed path. Brain service now provisions app signing authorities through this route instead of writing plaintext seeds to the LCA API database.
|
|
54
|
+
|
|
55
|
+
- [#1637](https://github.com/learningeconomy/LearnCard/pull/1637) [`ec321885908bab179acac7fec910bf61c42deb5f`](https://github.com/learningeconomy/LearnCard/commit/ec321885908bab179acac7fec910bf61c42deb5f) Thanks [@goblincore](https://github.com/goblincore)! - Add gated referral invitations with attributed cards, audience and permission review, confirmed decline, and pending invitation recovery after alert dismissal. Require both tenant configuration and the enableContractRequests rollout flag; preserve existing AI and owner-only consent flows. Localize the experience in English, Spanish, French, and Arabic.
|
|
56
|
+
|
|
57
|
+
Show receiving organizations in consent and connected-app details and recheck current referral state before consent submission. Include a signed HTTP outcome acceptance lab and integration walkthrough.
|
|
58
|
+
|
|
59
|
+
Keep the receiving organizations visible in detailed privacy settings and connected-app access editing, while preserving the existing owner-only layout.
|
|
60
|
+
|
|
61
|
+
Bind referral acceptance to the reviewed request ID under the contract lock, reject expired contracts on consent/re-consent, and keep invitation conflicts in the review screen. Stop polling terminal invitations, localize permission summaries, retry failed dismissals, and support host-reachable webhook capture from Docker.
|
|
62
|
+
|
|
63
|
+
Document the complete referral, auto-boost, outcome, claim, synchronization and webhook lifecycle. Add tested integrator snippets for recipient contracts, signing authority setup, scoped runtime tokens and polling recovery, including the client activity required for live sharing.
|
|
64
|
+
|
|
65
|
+
Refine referral cards and review panels with compact typography, grouped audience and permission details, accessible actions, and lighter privacy settings. Keep invitation and consent behavior unchanged.
|
|
66
|
+
|
|
67
|
+
- [#1670](https://github.com/learningeconomy/LearnCard/pull/1670) [`7656a57d30c6d80b8a25a8bb14bcd3b08b3648c2`](https://github.com/learningeconomy/LearnCard/commit/7656a57d30c6d80b8a25a8bb14bcd3b08b3648c2) Thanks [@Custard7](https://github.com/Custard7)! - Select backend stage files by tenant as well as stage. `CONFIG_TENANT=scouts` loads `config.scouts.<stage>.json` (generated from the live ScoutPass Lambdas), so ScoutPass deployments no longer inherit LearnCard domains, trust settings or seed-encryption flags; a named tenant without a stage file fails closed. `ESCROW_ENCLAVE_MODE` is now forwarded in runtime-secrets bundle mode too.
|
|
68
|
+
|
|
69
|
+
- [#1644](https://github.com/learningeconomy/LearnCard/pull/1644) [`37a3db8ff98a35c8e9e140569a693c9e0ed00165`](https://github.com/learningeconomy/LearnCard/commit/37a3db8ff98a35c8e9e140569a693c9e0ed00165) Thanks [@smurflo2](https://github.com/smurflo2)! - Enable share-link view tracking for persisted service profiles without requiring a date of birth, including managed organizations. Apply the exemption during creation and transactional view-receipt checks, and show eligible service-profile view statistics in Privacy & Data. Keep child and personal-account age protections, link expiry behavior, and other privacy gates unchanged.
|
|
70
|
+
|
|
71
|
+
Preserve the 30-day default expiry for managed service profiles with adult birthdates. Refresh older resolved service tracking restrictions on an explicit owner edit only after a locked service-classification check, preserving stored expiry and the eligibility limits of replayed or recovered reservations.
|
|
72
|
+
|
|
73
|
+
- Updated dependencies [[`6209da80c52ac056a7644dab14669192740c9dad`](https://github.com/learningeconomy/LearnCard/commit/6209da80c52ac056a7644dab14669192740c9dad), [`5890451789b18afee45dc5ecbab3fa30aa90f085`](https://github.com/learningeconomy/LearnCard/commit/5890451789b18afee45dc5ecbab3fa30aa90f085), [`23c30e68ca4fc5feb70ab3a5660aae71e486d63e`](https://github.com/learningeconomy/LearnCard/commit/23c30e68ca4fc5feb70ab3a5660aae71e486d63e), [`aaeca3dad4a899a4ce7e96009ba211b4c27af7a2`](https://github.com/learningeconomy/LearnCard/commit/aaeca3dad4a899a4ce7e96009ba211b4c27af7a2), [`1387cd0a08fa6b0a706c86a5a0376b6c7d706856`](https://github.com/learningeconomy/LearnCard/commit/1387cd0a08fa6b0a706c86a5a0376b6c7d706856), [`d7ca528898d988c65f0dc7084cfdcd41767648c5`](https://github.com/learningeconomy/LearnCard/commit/d7ca528898d988c65f0dc7084cfdcd41767648c5), [`d7ca528898d988c65f0dc7084cfdcd41767648c5`](https://github.com/learningeconomy/LearnCard/commit/d7ca528898d988c65f0dc7084cfdcd41767648c5), [`8f3bc66ab3d3e5e1edb3fbf5f362025875a914ba`](https://github.com/learningeconomy/LearnCard/commit/8f3bc66ab3d3e5e1edb3fbf5f362025875a914ba), [`1387cd0a08fa6b0a706c86a5a0376b6c7d706856`](https://github.com/learningeconomy/LearnCard/commit/1387cd0a08fa6b0a706c86a5a0376b6c7d706856), [`267cf40291b3a63caf178857be0e57feaf5e0948`](https://github.com/learningeconomy/LearnCard/commit/267cf40291b3a63caf178857be0e57feaf5e0948), [`7656a57d30c6d80b8a25a8bb14bcd3b08b3648c2`](https://github.com/learningeconomy/LearnCard/commit/7656a57d30c6d80b8a25a8bb14bcd3b08b3648c2), [`c78c982f9f4911f1ca2973380f19d80db775e012`](https://github.com/learningeconomy/LearnCard/commit/c78c982f9f4911f1ca2973380f19d80db775e012), [`590adf48867d6c6fd504e66a11c9827d5102122d`](https://github.com/learningeconomy/LearnCard/commit/590adf48867d6c6fd504e66a11c9827d5102122d)]:
|
|
74
|
+
- @learncard/types@5.23.0
|
|
75
|
+
- @learncard/credential-library@2.1.0
|
|
76
|
+
- @learncard/partner-connect-core@0.2.0
|
|
77
|
+
- @learncard/email-templates@1.2.1
|
|
78
|
+
- @learncard/service-config@0.1.1
|
|
79
|
+
- @learncard/didkit-plugin@1.10.3
|
|
80
|
+
- @learncard/core@9.4.38
|
|
81
|
+
- @learncard/helpers@1.6.2
|
|
82
|
+
- @learncard/did-web-plugin@1.1.38
|
|
83
|
+
- @learncard/didkey-plugin@1.1.38
|
|
84
|
+
- @learncard/didkit-plugin-node@0.3.3
|
|
85
|
+
- @learncard/encryption-plugin@1.1.38
|
|
86
|
+
- @learncard/learn-card-plugin@1.2.38
|
|
87
|
+
- @learncard/vc-plugin@1.6.4
|
|
88
|
+
- @learncard/vc-templates-plugin@1.1.38
|
|
89
|
+
- @learncard/crypto-plugin@1.1.38
|
|
90
|
+
- @learncard/dynamic-loader-plugin@1.1.38
|
|
91
|
+
- @learncard/expiration-plugin@1.2.38
|
|
92
|
+
|
|
93
|
+
## Unreleased
|
|
94
|
+
|
|
95
|
+
### Patch Changes
|
|
96
|
+
|
|
97
|
+
- LC-2201: Encrypt signing-authority credentials for direct local sends, verified-email
|
|
98
|
+
inbox delivery, and accepted inbox finalization. Preserve public status coordinates
|
|
99
|
+
for revocation without decrypting payloads. Ordinary finalized inbox credentials are
|
|
100
|
+
indexed for their recipient and returned as encrypted deliveries for client-side decryption.
|
|
101
|
+
Interoperable claim exchanges and federated sends intentionally remain plaintext.
|
|
102
|
+
- LC-2201: Finalize ordinary inbox claims and their network indexes, permission hooks,
|
|
103
|
+
default claimed role, and claim audit in one transaction. Failed graph writes keep
|
|
104
|
+
pending escrow intact so retry can complete the delivery without partial permissions
|
|
105
|
+
or orphaned indexes; concurrent claims produce one accepted delivery.
|
|
106
|
+
- LC-2201: Bound ordinary inbox finalization's Neo4j transaction to 30 seconds.
|
|
107
|
+
Signing stays outside the transaction; failed writes and lost claim races may leave
|
|
108
|
+
unused status-list indices rather than hold graph locks across external signing.
|
|
109
|
+
- LC-2201: Bind unsigned inbox subject IDs to the verified recipient before signing,
|
|
110
|
+
replacing template-supplied IDs. Pre-signed credentials retain their signed subjects.
|
|
111
|
+
|
|
112
|
+
## 3.19.1
|
|
113
|
+
|
|
114
|
+
### Patch Changes
|
|
115
|
+
|
|
116
|
+
- [#1607](https://github.com/learningeconomy/LearnCard/pull/1607) [`b184f5552abf37a11468d435e5cea07fc35e1993`](https://github.com/learningeconomy/LearnCard/commit/b184f5552abf37a11468d435e5cea07fc35e1993) Thanks [@goblincore](https://github.com/goblincore)! - Make `acceptPresentation` idempotent so retries of a saved collection do not create duplicate relationships. New or replacement share-link passcodes require at least eight characters; existing shorter passcodes remain valid for recipients. Public share resolution can now return `try_later` when passcode verification is unavailable or throttled.
|
|
117
|
+
|
|
118
|
+
- [#1624](https://github.com/learningeconomy/LearnCard/pull/1624) [`7e5c2b9ce9fabbd5635cf17a2c6eea5c3ce692fa`](https://github.com/learningeconomy/LearnCard/commit/7e5c2b9ce9fabbd5635cf17a2c6eea5c3ce692fa) Thanks [@Custard7](https://github.com/Custard7)! - fix: Stop treating service profiles as child accounts and fix managed-child claim email template
|
|
119
|
+
|
|
120
|
+
- [#1529](https://github.com/learningeconomy/LearnCard/pull/1529) [`0e262737aafb8248e88e05039c83a3f30be6750f`](https://github.com/learningeconomy/LearnCard/commit/0e262737aafb8248e88e05039c83a3f30be6750f) Thanks [@Custard7](https://github.com/Custard7)! - SSS prod hardening: confirmed recovery enrollment, lost-login identity rebind, and an isolated email relay.
|
|
121
|
+
|
|
122
|
+
- Recovery methods now carry `confirmedAt` and must be proven before they count (email confirmation code, phrase challenge words, backup re-decrypt, passkey round trip). New SSS accounts are `active` immediately; web3auth migrations stay `provisional` until a method is confirmed.
|
|
123
|
+
- New recovery-session flow lets a user whose sign-in identity is gone recover via a verified personal email and bind a new sign-in.
|
|
124
|
+
- Email recovery shares are encrypted on the client to an isolated relay's public key; `lca-api` never sees plaintext. Provider tokens move from query strings to the `X-Auth-Token` header.
|
|
125
|
+
- Sensitive key routes require a single-use DID challenge; key records are keyed by immutable provider ID.
|
|
126
|
+
- `recovery-key` email template now requires `confirmationCode`.
|
|
127
|
+
- Auth-share initialization requires the provider uniqueness index before inserting, preventing competing first writes from creating duplicate accounts. Existing records with missing or BSON-null auth material retain atomic update protection.
|
|
128
|
+
- Automatic stale-key cleanup preserves unresolved pending shares for delayed commits; explicit device forgetting still removes them. Custom SSS storage adapters now implement `deleteDeviceShare(id?)` to remove only the selected share and its version.
|
|
129
|
+
|
|
130
|
+
- [#1614](https://github.com/learningeconomy/LearnCard/pull/1614) [`ae10525fbd0ef284aabe1b03d12db147a1922f2c`](https://github.com/learningeconomy/LearnCard/commit/ae10525fbd0ef284aabe1b03d12db147a1922f2c) Thanks [@smurflo2](https://github.com/smurflo2)! - feat: [LC-2191] Replace Demo School with standards-pure sample personas, including plain OBv3 ConsentFlow issuance without proprietary `boostId` fields.
|
|
131
|
+
|
|
132
|
+
- Updated dependencies [[`4b83aa9ee802f0d7a54adc5f053a7376fa103cdd`](https://github.com/learningeconomy/LearnCard/commit/4b83aa9ee802f0d7a54adc5f053a7376fa103cdd), [`2ebda517e9468476f22d3ae3b4ebddf67e8aca78`](https://github.com/learningeconomy/LearnCard/commit/2ebda517e9468476f22d3ae3b4ebddf67e8aca78), [`0e9dd47f4451d776ad1787d0a35dbd54141b9fe3`](https://github.com/learningeconomy/LearnCard/commit/0e9dd47f4451d776ad1787d0a35dbd54141b9fe3), [`b184f5552abf37a11468d435e5cea07fc35e1993`](https://github.com/learningeconomy/LearnCard/commit/b184f5552abf37a11468d435e5cea07fc35e1993), [`0e262737aafb8248e88e05039c83a3f30be6750f`](https://github.com/learningeconomy/LearnCard/commit/0e262737aafb8248e88e05039c83a3f30be6750f), [`ae10525fbd0ef284aabe1b03d12db147a1922f2c`](https://github.com/learningeconomy/LearnCard/commit/ae10525fbd0ef284aabe1b03d12db147a1922f2c), [`d436c39e00994e6d8c77e7b94985a51fe1f42adb`](https://github.com/learningeconomy/LearnCard/commit/d436c39e00994e6d8c77e7b94985a51fe1f42adb)]:
|
|
133
|
+
- @learncard/types@5.22.0
|
|
134
|
+
- @learncard/credential-library@2.0.5
|
|
135
|
+
- @learncard/email-templates@1.2.0
|
|
136
|
+
- @learncard/helpers@1.6.1
|
|
137
|
+
- @learncard/core@9.4.37
|
|
138
|
+
- @learncard/did-web-plugin@1.1.37
|
|
139
|
+
- @learncard/didkey-plugin@1.1.37
|
|
140
|
+
- @learncard/didkit-plugin@1.10.2
|
|
141
|
+
- @learncard/didkit-plugin-node@0.3.2
|
|
142
|
+
- @learncard/encryption-plugin@1.1.37
|
|
143
|
+
- @learncard/learn-card-plugin@1.2.37
|
|
144
|
+
- @learncard/vc-plugin@1.6.3
|
|
145
|
+
- @learncard/vc-templates-plugin@1.1.37
|
|
146
|
+
- @learncard/crypto-plugin@1.1.37
|
|
147
|
+
- @learncard/dynamic-loader-plugin@1.1.37
|
|
148
|
+
- @learncard/expiration-plugin@1.2.37
|
|
149
|
+
|
|
3
150
|
## 3.19.0
|
|
4
151
|
|
|
5
152
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -9,10 +9,10 @@ This service exposes the LearnCard Network API and local Neo4j-backed skills flo
|
|
|
9
9
|
- `termsUri`, `contractUri`, `status` and `terms` identify the current grant and its permissions.
|
|
10
10
|
- `createdAt` is the original grant time when known. `date` is the latest consent update time. No historical timestamp is invented.
|
|
11
11
|
- `contractUpdatedAt` identifies the current contract revision; `contractExpiresAt` and `reasonForAccessing` report existing contract metadata. These fields do not imply acceptance of a new privacy notice.
|
|
12
|
-
- `guardian.required` uses LearnCard's existing manager-based guardian rules, including authorized role-based managers.
|
|
12
|
+
- `guardian.required` uses LearnCard's existing manager-based guardian rules for non-service profiles and explicitly typed children, including authorized role-based managers. An explicit `child` type takes precedence over a legacy service flag. A service profile's managers are otherwise administrators, not guardians. Explicit approval metadata and persisted guardian approval history still require approval, including after manager removal or a change to service-profile status.
|
|
13
13
|
- `guardian.approved` requires a recorded approval for the current contract revision and a guardian who is still an authorized manager. Approval is server-recorded alongside the exact consent terms and transaction; it is not accepted from client-supplied terms. Raw approval presentations are not retained.
|
|
14
14
|
|
|
15
|
-
Existing adult grants remain eligible without new guardian or privacy-notice attestations. Existing managed-profile grants without recorded approval return `required: true, approved: false` and need a guardian-confirmed consent update. Consumers must enforce that distinction before AI processing; receipt metadata alone is not an authorization check.
|
|
15
|
+
Existing adult and managed service-profile grants remain eligible without new guardian or privacy-notice attestations unless they have guardian approval history. Existing managed non-service-profile grants without recorded approval return `required: true, approved: false` and need a guardian-confirmed consent update. Consumers must enforce that distinction before AI processing; receipt metadata alone is not an authorization check.
|
|
16
16
|
|
|
17
17
|
Removing all managers is not an adulthood transition. Guardian approval history survives withdrawal, so withdrawing and consenting again does **not** remove the requirement. Recovery first requires current manager authority: the existing verified-contact / `inbox.claimPendingGuardianLinks` flow can relink a guardian only when their verified email matches an eligible guardian-approved inbox credential for that child. Without that evidence, account/guardian-link recovery is a prerequisite; there is no generic self-service existing-child manager restoration or adult-conversion endpoint here. After authority is restored, obtain fresh approval to update live terms or reconsent withdrawn terms.
|
|
18
18
|
|
|
@@ -20,6 +20,13 @@ Guardian presentations retain a maximum five-minute signed lifetime. The backend
|
|
|
20
20
|
|
|
21
21
|
Deploy this producer before an AI Passport consumer that requires the new guardian metadata.
|
|
22
22
|
|
|
23
|
+
## Managed service profiles and children
|
|
24
|
+
|
|
25
|
+
`createManagedProfile` supports service profiles for developer/org onboarding and admin tools. It rejects `isServiceProfile: true` when the authenticated manager has a persisted parent Boost with category `Family`, or the requested profile has type `child`. Family child creation cannot use that flag to bypass guardian checks; other managed org creation remains supported.
|
|
26
|
+
|
|
27
|
+
Share-link policy exempts persisted service owners from management and birthdate restrictions **for tracking only**, in both preflight and the transactional recheck. An explicit `child` type always keeps child protections, even if a legacy record also has the service flag; the service flag is age-exempt, not an assertion of adulthood. Personal profiles with missing or malformed birthdates and managed non-service owners remain restricted. Default expiry still uses persisted age and management: managed service profiles keep a 30-day default, including those with an adult birthdate. Explicit null or date expiry, AI gates and other privacy settings are unchanged. Existing links retain their stored policy until an explicit edit rechecks current eligibility; this also refreshes older resolved service snapshots, without changing stored expiry. Reserved and freshly checked eligibility must both permit tracking, so a stale replay or recovery cannot broaden a restricted reservation. Creating a fresh link also applies the exemption.
|
|
28
|
+
Guardian-gated writes and consent metadata likewise exempt only service profiles that are not explicitly typed as children. A persisted service-flagged child cannot change its type through profile updates.
|
|
29
|
+
|
|
23
30
|
## Skill framework seeding
|
|
24
31
|
|
|
25
32
|
- **Auto-bootstrap**: on local/dev startup, if no `SkillFramework` nodes exist, the service seeds a default public set owned by the `network-seed` profile.
|
|
@@ -29,6 +36,48 @@ Deploy this producer before an AI Passport consumer that requires the new guardi
|
|
|
29
36
|
- **Default environment**: if you omit the stage, the command defaults to `local` and prints a note.
|
|
30
37
|
- **Production safety**: the manual seed command still refuses to run in production unless `--force` is provided.
|
|
31
38
|
|
|
39
|
+
## Sample persona seeding
|
|
40
|
+
|
|
41
|
+
Sample personas are ordered credential-library bundles published as idempotent
|
|
42
|
+
consent-flow contracts. The seeder uses every target value from
|
|
43
|
+
`services/learn-card-network/brain-service/.env`; verify them before running it.
|
|
44
|
+
Do not overwrite an existing `.env` or assume it points to local services.
|
|
45
|
+
|
|
46
|
+
For the local LearnCard App Compose stack, use explicit host-side values:
|
|
47
|
+
|
|
48
|
+
```dotenv
|
|
49
|
+
NEO4J_URI=bolt://localhost:7687
|
|
50
|
+
NEO4J_USERNAME=neo4j
|
|
51
|
+
NEO4J_PASSWORD=this-is-the-password
|
|
52
|
+
MONGO_URI=mongodb://localhost:27017/?replicaSet=rs0
|
|
53
|
+
MONGO_DB_NAME=lca-api
|
|
54
|
+
REDIS_HOST=localhost
|
|
55
|
+
REDIS_PORT=6379
|
|
56
|
+
DOMAIN_NAME=localhost%3A4000
|
|
57
|
+
DEMO_PERSONA_SIGNING_AUTHORITY_ENDPOINT=http://localhost:5100/api
|
|
58
|
+
# Disposable local-only seed. Never reuse this value in a shared environment.
|
|
59
|
+
DEMO_PERSONA_SA_SEED=dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Start the stack, then publish the bundle from `apps/learn-card-app`:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
bun run seed:demo-persona student
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Staging and production require their own secret 64-character hexadecimal
|
|
69
|
+
`DEMO_PERSONA_SA_SEED`, the matching LCA API endpoint, and explicit Neo4j, MongoDB,
|
|
70
|
+
Redis, and domain settings. Deploy the brain service first, run the seeder against
|
|
71
|
+
the intended environment, verify the printed contract URI, and only then deploy app
|
|
72
|
+
configuration that references it.
|
|
73
|
+
|
|
74
|
+
The root seed deterministically derives a distinct signing identity for every
|
|
75
|
+
configured sample issuer. The command updates issuer profiles, unsigned credential
|
|
76
|
+
templates, and auto-boost relationships in place, then prints the stable contract URI
|
|
77
|
+
to record in that tenant's `features.samplePersonas`. Running it again publishes
|
|
78
|
+
credential-library content changes without duplicating profiles, Boosts, signing
|
|
79
|
+
authorities, or contracts.
|
|
80
|
+
|
|
32
81
|
## Notes
|
|
33
82
|
|
|
34
83
|
- The default fixture is idempotent by framework and skill ID, so running the seed command multiple times does not duplicate data.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { APIGatewayProxyEventV2, Context } from 'aws-lambda';
|
|
2
|
+
import { beforeEach, expect, it, vi } from 'vitest';
|
|
3
|
+
|
|
4
|
+
const mocks = vi.hoisted(() => ({ bootstrap: vi.fn(), getApp: vi.fn(), handler: vi.fn() }));
|
|
5
|
+
|
|
6
|
+
vi.mock('@learncard/service-config', () => ({ bootstrapLambda: mocks.bootstrap }));
|
|
7
|
+
vi.mock('./src/config/stageConfig', () => ({ base: {}, stages: { dev: {}, production: {} } }));
|
|
8
|
+
|
|
9
|
+
const LAMBDA_APP_HANDLERS = [
|
|
10
|
+
'trpcHandler',
|
|
11
|
+
'openApiHandler',
|
|
12
|
+
'swaggerUiHandler',
|
|
13
|
+
'skillsViewerHandler',
|
|
14
|
+
'statusListsHandler',
|
|
15
|
+
'credentialRefreshHandler',
|
|
16
|
+
'inboxQueueWorker',
|
|
17
|
+
'inboxQueueDispatcher',
|
|
18
|
+
'inboxDeadLetterWorker',
|
|
19
|
+
'notificationsWorker',
|
|
20
|
+
'inboxMaintenanceHandler',
|
|
21
|
+
] as const;
|
|
22
|
+
|
|
23
|
+
vi.mock('./lambdaApp', () =>
|
|
24
|
+
Object.fromEntries(LAMBDA_APP_HANDLERS.map(name => [name, mocks.handler]))
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
vi.resetModules();
|
|
29
|
+
vi.clearAllMocks();
|
|
30
|
+
mocks.bootstrap.mockReturnValue(mocks.getApp);
|
|
31
|
+
mocks.handler.mockResolvedValue({ statusCode: 200 });
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('bootstraps the API once with checked-in stage config', async () => {
|
|
35
|
+
vi.stubEnv('AWS_LAMBDA_FUNCTION_NAME', 'lcn-brain-service-dev-trpc');
|
|
36
|
+
vi.stubEnv('LAMBDA_STAGE', 'dev');
|
|
37
|
+
await import('./lambda');
|
|
38
|
+
expect(mocks.bootstrap).toHaveBeenCalledTimes(1);
|
|
39
|
+
expect(mocks.bootstrap).toHaveBeenCalledWith({
|
|
40
|
+
base: {},
|
|
41
|
+
stages: { dev: {}, production: {} },
|
|
42
|
+
stage: 'dev',
|
|
43
|
+
importApp: expect.any(Function),
|
|
44
|
+
});
|
|
45
|
+
vi.unstubAllEnvs();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('uses CONFIG_STAGE outside Lambda rather than LAMBDA_STAGE', async () => {
|
|
49
|
+
vi.stubEnv('AWS_LAMBDA_FUNCTION_NAME', '');
|
|
50
|
+
vi.stubEnv('LAMBDA_STAGE', 'production');
|
|
51
|
+
vi.stubEnv('CONFIG_STAGE', 'dev');
|
|
52
|
+
await import('./lambda');
|
|
53
|
+
expect(mocks.bootstrap).toHaveBeenCalledWith(expect.objectContaining({ stage: 'dev' }));
|
|
54
|
+
vi.unstubAllEnvs();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('forwards every handler through its bootstrap accessor', async () => {
|
|
58
|
+
mocks.getApp.mockResolvedValue(
|
|
59
|
+
Object.fromEntries(LAMBDA_APP_HANDLERS.map(name => [name, mocks.handler]))
|
|
60
|
+
);
|
|
61
|
+
const lambda = await import('./lambda');
|
|
62
|
+
const event = {} as APIGatewayProxyEventV2;
|
|
63
|
+
const context = {} as Context;
|
|
64
|
+
const callback = vi.fn();
|
|
65
|
+
for (const name of LAMBDA_APP_HANDLERS) {
|
|
66
|
+
await (lambda[name] as (...args: unknown[]) => Promise<unknown>)(event, context, callback);
|
|
67
|
+
}
|
|
68
|
+
expect(mocks.bootstrap).toHaveBeenCalledTimes(1);
|
|
69
|
+
expect(mocks.getApp).toHaveBeenCalledTimes(LAMBDA_APP_HANDLERS.length);
|
|
70
|
+
expect(mocks.handler).toHaveBeenCalledTimes(LAMBDA_APP_HANDLERS.length);
|
|
71
|
+
expect(mocks.handler).toHaveBeenCalledWith(event, context, callback);
|
|
72
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"CLIENT_APP_DOMAIN_NAME": "learncard.app",
|
|
3
|
+
"CREDENTIAL_REFRESH_ENABLED": "true",
|
|
4
|
+
"CREDENTIAL_REFRESH_NOTIFICATION_WINDOW_HOURS": "12",
|
|
5
|
+
"DOMAIN_NAME": "staging.network.learncard.com",
|
|
6
|
+
"INBOX_BATCH_ITEMS_PER_HOUR": "10000",
|
|
7
|
+
"INBOX_DELETE_EXPIRED_RECORDS": "false",
|
|
8
|
+
"MESSAGEBIRD_ORIGINATOR": "+12077447198",
|
|
9
|
+
"OIDC_EXPECTED_AUDIENCE": "learncard",
|
|
10
|
+
"OIDC_TRUSTED_ISSUERS": "https://securetoken.google.com/learncard",
|
|
11
|
+
"POSTMARK_FROM_EMAIL": "inbox@learncard.com",
|
|
12
|
+
"SENTRY_ENV": "lcn-staging",
|
|
13
|
+
"SHARE_LINK_MAINTENANCE_ALLOW_INSECURE_LOOPBACK": "false",
|
|
14
|
+
"SHARE_LINK_MAINTENANCE_AUDIENCE": "did:web:staging.cloud.learncard.com",
|
|
15
|
+
"SHARE_LINK_MAINTENANCE_BUDGET_MS": "60000",
|
|
16
|
+
"SHARE_LINK_MAINTENANCE_CLAIMANT": "brain-share-link-maintenance",
|
|
17
|
+
"SHARE_LINK_MAINTENANCE_CLAIM_MS": "300000",
|
|
18
|
+
"SHARE_LINK_MAINTENANCE_CLEANUP_LIMIT": "25",
|
|
19
|
+
"SHARE_LINK_MAINTENANCE_FINALIZE_RESERVE_MS": "5000",
|
|
20
|
+
"SHARE_LINK_MAINTENANCE_GRAPH_TIMEOUT_MS": "15000",
|
|
21
|
+
"SHARE_LINK_MAINTENANCE_INTERVAL_MS": "300000",
|
|
22
|
+
"SHARE_LINK_MAINTENANCE_LEASE_MS": "120000",
|
|
23
|
+
"SHARE_LINK_MAINTENANCE_NAMESPACE": "learncard",
|
|
24
|
+
"SHARE_LINK_MAINTENANCE_ORIGIN": "https://staging.cloud.learncard.com",
|
|
25
|
+
"SHARE_LINK_MAINTENANCE_RECOVERY_LIMIT": "25",
|
|
26
|
+
"SHARE_LINK_MAINTENANCE_REQUEST_TIMEOUT_MS": "10000",
|
|
27
|
+
"SIGNING_AUTHORITY_ENDPOINT": "https://staging.api.learncard.app/api",
|
|
28
|
+
"SKILL_EMBEDDING_GOOGLE_MODEL": "gemini-embedding-001"
|
|
29
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"CLIENT_APP_DOMAIN_NAME": "example.com",
|
|
3
|
+
"CREDENTIAL_REFRESH_ENABLED": "false",
|
|
4
|
+
"CREDENTIAL_REFRESH_NOTIFICATION_WINDOW_HOURS": "24",
|
|
5
|
+
"DOMAIN_NAME": "network.example.com",
|
|
6
|
+
"INBOX_BATCH_ITEMS_PER_HOUR": "10000",
|
|
7
|
+
"INBOX_DELETE_EXPIRED_RECORDS": "false",
|
|
8
|
+
"MESSAGEBIRD_ORIGINATOR": "+10000000000",
|
|
9
|
+
"OIDC_EXPECTED_AUDIENCE": "example",
|
|
10
|
+
"OIDC_TRUSTED_ISSUERS": "https://securetoken.google.com/example",
|
|
11
|
+
"POSTMARK_FROM_EMAIL": "inbox@example.com",
|
|
12
|
+
"SENTRY_ENV": "lcn-example",
|
|
13
|
+
"SHARE_LINK_MAINTENANCE_ALLOW_INSECURE_LOOPBACK": "false",
|
|
14
|
+
"SHARE_LINK_MAINTENANCE_AUDIENCE": "did:web:cloud.example.com",
|
|
15
|
+
"SHARE_LINK_MAINTENANCE_BUDGET_MS": "60000",
|
|
16
|
+
"SHARE_LINK_MAINTENANCE_CLAIM_MS": "300000",
|
|
17
|
+
"SHARE_LINK_MAINTENANCE_CLAIMANT": "brain-share-link-maintenance",
|
|
18
|
+
"SHARE_LINK_MAINTENANCE_CLEANUP_LIMIT": "25",
|
|
19
|
+
"SHARE_LINK_MAINTENANCE_FINALIZE_RESERVE_MS": "5000",
|
|
20
|
+
"SHARE_LINK_MAINTENANCE_GRAPH_TIMEOUT_MS": "15000",
|
|
21
|
+
"SHARE_LINK_MAINTENANCE_INTERVAL_MS": "300000",
|
|
22
|
+
"SHARE_LINK_MAINTENANCE_LEASE_MS": "120000",
|
|
23
|
+
"SHARE_LINK_MAINTENANCE_NAMESPACE": "example",
|
|
24
|
+
"SHARE_LINK_MAINTENANCE_ORIGIN": "https://cloud.example.com",
|
|
25
|
+
"SHARE_LINK_MAINTENANCE_RECOVERY_LIMIT": "25",
|
|
26
|
+
"SHARE_LINK_MAINTENANCE_REQUEST_TIMEOUT_MS": "10000",
|
|
27
|
+
"SIGNING_AUTHORITY_ENDPOINT": "https://api.example.com/api",
|
|
28
|
+
"SKILL_EMBEDDING_GOOGLE_MODEL": "gemini-embedding-001"
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"CLIENT_APP_DOMAIN_NAME": "learncard.app",
|
|
3
|
+
"CREDENTIAL_REFRESH_ENABLED": "true",
|
|
4
|
+
"CREDENTIAL_REFRESH_NOTIFICATION_WINDOW_HOURS": "12",
|
|
5
|
+
"DOMAIN_NAME": "network.learncard.com",
|
|
6
|
+
"INBOX_BATCH_ITEMS_PER_HOUR": "10000",
|
|
7
|
+
"INBOX_DELETE_EXPIRED_RECORDS": "false",
|
|
8
|
+
"MESSAGEBIRD_ORIGINATOR": "+12077447198",
|
|
9
|
+
"OIDC_EXPECTED_AUDIENCE": "learncard",
|
|
10
|
+
"OIDC_TRUSTED_ISSUERS": "https://securetoken.google.com/learncard",
|
|
11
|
+
"POSTMARK_FROM_EMAIL": "inbox@learncard.com",
|
|
12
|
+
"SENTRY_ENV": "lcn-production",
|
|
13
|
+
"SHARE_LINK_MAINTENANCE_ALLOW_INSECURE_LOOPBACK": "false",
|
|
14
|
+
"SHARE_LINK_MAINTENANCE_AUDIENCE": "did:web:cloud.learncard.com",
|
|
15
|
+
"SHARE_LINK_MAINTENANCE_BUDGET_MS": "60000",
|
|
16
|
+
"SHARE_LINK_MAINTENANCE_CLAIMANT": "brain-share-link-maintenance",
|
|
17
|
+
"SHARE_LINK_MAINTENANCE_CLAIM_MS": "300000",
|
|
18
|
+
"SHARE_LINK_MAINTENANCE_CLEANUP_LIMIT": "25",
|
|
19
|
+
"SHARE_LINK_MAINTENANCE_FINALIZE_RESERVE_MS": "5000",
|
|
20
|
+
"SHARE_LINK_MAINTENANCE_GRAPH_TIMEOUT_MS": "15000",
|
|
21
|
+
"SHARE_LINK_MAINTENANCE_INTERVAL_MS": "300000",
|
|
22
|
+
"SHARE_LINK_MAINTENANCE_LEASE_MS": "120000",
|
|
23
|
+
"SHARE_LINK_MAINTENANCE_NAMESPACE": "learncard",
|
|
24
|
+
"SHARE_LINK_MAINTENANCE_ORIGIN": "https://cloud.learncard.com",
|
|
25
|
+
"SHARE_LINK_MAINTENANCE_RECOVERY_LIMIT": "25",
|
|
26
|
+
"SHARE_LINK_MAINTENANCE_REQUEST_TIMEOUT_MS": "10000",
|
|
27
|
+
"SIGNING_AUTHORITY_ENDPOINT": "https://api.learncard.app/api",
|
|
28
|
+
"SKILL_EMBEDDING_GOOGLE_MODEL": "gemini-embedding-001"
|
|
29
|
+
}
|