@elevasis/core 0.1.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/dist/index.d.ts +435 -0
- package/dist/index.js +403 -0
- package/dist/organization-model/index.d.ts +435 -0
- package/dist/organization-model/index.js +403 -0
- package/package.json +62 -0
- package/src/README.md +34 -0
- package/src/__tests__/observability-exports.test.ts +36 -0
- package/src/__tests__/publish.test.ts +18 -0
- package/src/__tests__/template-foundations-compatibility.test.ts +34 -0
- package/src/auth/index.ts +8 -0
- package/src/auth/multi-tenancy/credentials/README.md +38 -0
- package/src/auth/multi-tenancy/credentials/__tests__/encryption.test.ts +216 -0
- package/src/auth/multi-tenancy/credentials/__tests__/service.test.ts +174 -0
- package/src/auth/multi-tenancy/credentials/index.ts +6 -0
- package/src/auth/multi-tenancy/credentials/server/encryption.ts +39 -0
- package/src/auth/multi-tenancy/credentials/server/service.ts +60 -0
- package/src/auth/multi-tenancy/index.ts +17 -0
- package/src/auth/multi-tenancy/invitations/__tests__/invitation.test.ts +237 -0
- package/src/auth/multi-tenancy/invitations/api-schemas.ts +107 -0
- package/src/auth/multi-tenancy/invitations/index.ts +38 -0
- package/src/auth/multi-tenancy/invitations/invitation.ts +86 -0
- package/src/auth/multi-tenancy/invitations/server/index.ts +25 -0
- package/src/auth/multi-tenancy/invitations/server/transforms.ts +24 -0
- package/src/auth/multi-tenancy/invitations/server/workos.ts +24 -0
- package/src/auth/multi-tenancy/invitations/supabase.ts +50 -0
- package/src/auth/multi-tenancy/memberships/__tests__/membership.test.ts +227 -0
- package/src/auth/multi-tenancy/memberships/__tests__/supabase-transforms.test.ts +88 -0
- package/src/auth/multi-tenancy/memberships/__tests__/workos-transforms.test.ts +139 -0
- package/src/auth/multi-tenancy/memberships/api-schemas.ts +126 -0
- package/src/auth/multi-tenancy/memberships/index.ts +22 -0
- package/src/auth/multi-tenancy/memberships/membership.ts +138 -0
- package/src/auth/multi-tenancy/memberships/server/index.ts +15 -0
- package/src/auth/multi-tenancy/memberships/server/transforms.ts +32 -0
- package/src/auth/multi-tenancy/memberships/server/workos.ts +21 -0
- package/src/auth/multi-tenancy/memberships/supabase.ts +46 -0
- package/src/auth/multi-tenancy/organizations/__tests__/organization.test.ts +249 -0
- package/src/auth/multi-tenancy/organizations/api-schemas.ts +128 -0
- package/src/auth/multi-tenancy/organizations/index.ts +23 -0
- package/src/auth/multi-tenancy/organizations/organization.ts +25 -0
- package/src/auth/multi-tenancy/organizations/server/index.ts +10 -0
- package/src/auth/multi-tenancy/organizations/server/transforms.ts +35 -0
- package/src/auth/multi-tenancy/organizations/server/workos.ts +20 -0
- package/src/auth/multi-tenancy/types.ts +89 -0
- package/src/auth/multi-tenancy/users/__tests__/user.test.ts +208 -0
- package/src/auth/multi-tenancy/users/api-schemas.ts +194 -0
- package/src/auth/multi-tenancy/users/index.ts +28 -0
- package/src/auth/multi-tenancy/users/server/index.ts +19 -0
- package/src/auth/multi-tenancy/users/server/transforms.ts +21 -0
- package/src/auth/multi-tenancy/users/server/workos.ts +16 -0
- package/src/auth/multi-tenancy/users/user.ts +65 -0
- package/src/business/acquisition/api-schemas.ts +759 -0
- package/src/business/acquisition/index.ts +109 -0
- package/src/business/acquisition/types.ts +400 -0
- package/src/business/crm/api-schemas.ts +75 -0
- package/src/business/delivery/index.ts +1 -0
- package/src/business/delivery/types.ts +89 -0
- package/src/business/index.ts +12 -0
- package/src/business/pdf/assets/ElevasisLogo.png +0 -0
- package/src/business/pdf/browser/image-utils.ts +74 -0
- package/src/business/pdf/browser/index.ts +16 -0
- package/src/business/pdf/browser/pdfmake-browser.ts +229 -0
- package/src/business/pdf/index.ts +10 -0
- package/src/business/pdf/sections/acceptance.ts +112 -0
- package/src/business/pdf/sections/automation.ts +56 -0
- package/src/business/pdf/sections/cover.ts +51 -0
- package/src/business/pdf/sections/index.ts +57 -0
- package/src/business/pdf/sections/investment.ts +69 -0
- package/src/business/pdf/sections/proposal-document.ts +200 -0
- package/src/business/pdf/sections/summary-investment.ts +124 -0
- package/src/business/pdf/sections/summary.ts +55 -0
- package/src/business/pdf/sections/table-summary.ts +59 -0
- package/src/business/pdf/sections/types.ts +124 -0
- package/src/business/pdf/server/__tests__/pdfmake-test.ts +219 -0
- package/src/business/pdf/server/index.ts +21 -0
- package/src/business/pdf/server/pdfmake-service.ts +237 -0
- package/src/business/pdf/server/themes/default.ts +8 -0
- package/src/business/pdf/server/themes/index.ts +9 -0
- package/src/business/pdf/server/themes/types.ts +8 -0
- package/src/business/pdf/shared/convert.ts +514 -0
- package/src/business/pdf/shared/index.ts +12 -0
- package/src/business/pdf/themes.ts +78 -0
- package/src/business/pdf/types.ts +272 -0
- package/src/business/seo/__tests__/linking.test.ts +549 -0
- package/src/business/seo/__tests__/types.test.ts +404 -0
- package/src/business/seo/index.ts +2 -0
- package/src/business/seo/linking.ts +281 -0
- package/src/business/seo/types.ts +199 -0
- package/src/commands/index.ts +8 -0
- package/src/commands/queue/index.ts +3 -0
- package/src/commands/queue/schemas.test.ts +593 -0
- package/src/commands/queue/schemas.ts +125 -0
- package/src/commands/queue/sse-events.ts +61 -0
- package/src/commands/queue/types/action.ts +52 -0
- package/src/commands/queue/types/checkpoint.ts +44 -0
- package/src/commands/queue/types/index.ts +7 -0
- package/src/commands/queue/types/task.ts +116 -0
- package/src/commands/queue/types.ts +14 -0
- package/src/content/distribution-metadata.ts +61 -0
- package/src/content/index.ts +10 -0
- package/src/deployments/index.ts +22 -0
- package/src/execution/calibration/__tests__/schemas.test.ts +320 -0
- package/src/execution/calibration/index.ts +3 -0
- package/src/execution/calibration/schemas.ts +121 -0
- package/src/execution/calibration/sse-events.ts +125 -0
- package/src/execution/calibration/types.ts +190 -0
- package/src/execution/core/__tests__/api-schemas.test.ts +667 -0
- package/src/execution/core/__tests__/archived-logs.test.ts +72 -0
- package/src/execution/core/api-schemas.ts +312 -0
- package/src/execution/core/index.ts +11 -0
- package/src/execution/core/resource-validator.test.ts +63 -0
- package/src/execution/core/runner-types.ts +80 -0
- package/src/execution/core/server/environment.ts +31 -0
- package/src/execution/core/sse-executions.ts +119 -0
- package/src/execution/core/types.ts +29 -0
- package/src/execution/engine/__tests__/fixtures/index.ts +2 -0
- package/src/execution/engine/__tests__/fixtures/mock-scenarios.ts +60 -0
- package/src/execution/engine/__tests__/fixtures/test-agents.ts +85 -0
- package/src/execution/engine/__tests__/integration/agent-framework.integration.test.ts +1031 -0
- package/src/execution/engine/__tests__/timeout.test.ts +565 -0
- package/src/execution/engine/agent/__tests__/errors.test.ts +508 -0
- package/src/execution/engine/agent/actions/__tests__/processor.test.ts +531 -0
- package/src/execution/engine/agent/actions/executor.ts +205 -0
- package/src/execution/engine/agent/actions/navigate-knowledge-executor.ts +230 -0
- package/src/execution/engine/agent/actions/processor.ts +116 -0
- package/src/execution/engine/agent/actions/types.ts +70 -0
- package/src/execution/engine/agent/core/__tests__/agent.test.ts +614 -0
- package/src/execution/engine/agent/core/__tests__/error-passthrough.test.ts +134 -0
- package/src/execution/engine/agent/core/agent.ts +810 -0
- package/src/execution/engine/agent/core/types.ts +155 -0
- package/src/execution/engine/agent/errors.ts +251 -0
- package/src/execution/engine/agent/index.ts +78 -0
- package/src/execution/engine/agent/knowledge-map/__tests__/navigate-knowledge-executor.test.ts +580 -0
- package/src/execution/engine/agent/knowledge-map/__tests__/utils.test.ts +622 -0
- package/src/execution/engine/agent/knowledge-map/types.ts +106 -0
- package/src/execution/engine/agent/knowledge-map/utils.ts +101 -0
- package/src/execution/engine/agent/memory/__tests__/domains.test.ts +72 -0
- package/src/execution/engine/agent/memory/__tests__/manager.test.ts +754 -0
- package/src/execution/engine/agent/memory/__tests__/utils.test.ts +285 -0
- package/src/execution/engine/agent/memory/domains.ts +99 -0
- package/src/execution/engine/agent/memory/manager.ts +365 -0
- package/src/execution/engine/agent/memory/processor.ts +66 -0
- package/src/execution/engine/agent/memory/types.ts +90 -0
- package/src/execution/engine/agent/memory/utils.ts +134 -0
- package/src/execution/engine/agent/observability/logging.ts +467 -0
- package/src/execution/engine/agent/observability/types.ts +64 -0
- package/src/execution/engine/agent/reasoning/__tests__/request-builder.test.ts +209 -0
- package/src/execution/engine/agent/reasoning/adapters/agent-adapter-helpers.ts +349 -0
- package/src/execution/engine/agent/reasoning/processor.ts +92 -0
- package/src/execution/engine/agent/reasoning/prompt-sections/base-actions.ts +134 -0
- package/src/execution/engine/agent/reasoning/prompt-sections/completion.ts +49 -0
- package/src/execution/engine/agent/reasoning/prompt-sections/knowledge-map.ts +93 -0
- package/src/execution/engine/agent/reasoning/prompt-sections/memory.ts +65 -0
- package/src/execution/engine/agent/reasoning/prompt-sections/security.ts +32 -0
- package/src/execution/engine/agent/reasoning/prompt-sections/tools.ts +44 -0
- package/src/execution/engine/agent/reasoning/request-builder.ts +169 -0
- package/src/execution/engine/agent/reasoning/types.ts +18 -0
- package/src/execution/engine/base/__tests__/errors.test.ts +246 -0
- package/src/execution/engine/base/__tests__/serialization.test.ts +670 -0
- package/src/execution/engine/base/__tests__/utils.test.ts +45 -0
- package/src/execution/engine/base/errors.ts +118 -0
- package/src/execution/engine/base/index.ts +2 -0
- package/src/execution/engine/base/logging.ts +31 -0
- package/src/execution/engine/base/serialization.ts +324 -0
- package/src/execution/engine/base/types.ts +126 -0
- package/src/execution/engine/base/utils.ts +41 -0
- package/src/execution/engine/index.ts +440 -0
- package/src/execution/engine/interface/index.ts +1 -0
- package/src/execution/engine/interface/types.ts +62 -0
- package/src/execution/engine/llm/__tests__/errors.test.ts +318 -0
- package/src/execution/engine/llm/__tests__/input-sanitizer.test.ts +286 -0
- package/src/execution/engine/llm/__tests__/model-info.test.ts +50 -0
- package/src/execution/engine/llm/__tests__/model-validation.test.ts +321 -0
- package/src/execution/engine/llm/__tests__/response-schema-validator.test.ts +115 -0
- package/src/execution/engine/llm/adapters/__tests__/adapter-factory.test.ts +375 -0
- package/src/execution/engine/llm/adapters/__tests__/anthropic-adapter.test.ts +463 -0
- package/src/execution/engine/llm/adapters/__tests__/anthropic.integration.test.ts +177 -0
- package/src/execution/engine/llm/adapters/__tests__/circuit-breaker-error.test.ts +94 -0
- package/src/execution/engine/llm/adapters/__tests__/google-adapter.test.ts +722 -0
- package/src/execution/engine/llm/adapters/__tests__/google.integration.test.ts +376 -0
- package/src/execution/engine/llm/adapters/__tests__/mock-adapter.test.ts +432 -0
- package/src/execution/engine/llm/adapters/__tests__/openai-adapter.test.ts +551 -0
- package/src/execution/engine/llm/adapters/__tests__/openrouter-adapter.test.ts +563 -0
- package/src/execution/engine/llm/adapters/__tests__/openrouter.integration.test.ts +105 -0
- package/src/execution/engine/llm/adapters/__tests__/universal-adapter.test.ts +537 -0
- package/src/execution/engine/llm/adapters/circuit-breaker.ts +147 -0
- package/src/execution/engine/llm/adapters/index.ts +17 -0
- package/src/execution/engine/llm/adapters/mock-adapter.ts +116 -0
- package/src/execution/engine/llm/adapters/server/adapter-factory.ts +130 -0
- package/src/execution/engine/llm/adapters/server/anthropic.ts +137 -0
- package/src/execution/engine/llm/adapters/server/compose-signal.ts +18 -0
- package/src/execution/engine/llm/adapters/server/google.ts +283 -0
- package/src/execution/engine/llm/adapters/server/index.ts +12 -0
- package/src/execution/engine/llm/adapters/server/openai.ts +206 -0
- package/src/execution/engine/llm/adapters/server/openrouter.ts +235 -0
- package/src/execution/engine/llm/adapters/universal-adapter.ts +230 -0
- package/src/execution/engine/llm/errors.ts +186 -0
- package/src/execution/engine/llm/input-sanitizer.ts +129 -0
- package/src/execution/engine/llm/model-info.ts +332 -0
- package/src/execution/engine/llm/response-schema-validator.ts +113 -0
- package/src/execution/engine/llm/types.ts +86 -0
- package/src/execution/engine/test-utils/index.ts +6 -0
- package/src/execution/engine/test-utils/mocks.ts +56 -0
- package/src/execution/engine/tools/__tests__/tooling-error.test.ts +265 -0
- package/src/execution/engine/tools/__tests__/types.test.ts +47 -0
- package/src/execution/engine/tools/integration/base-integration-adapter.ts +50 -0
- package/src/execution/engine/tools/integration/index.ts +53 -0
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/anymailfinder-adapter.ts +73 -0
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/anymailfinder-tools.ts +209 -0
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-company-email/index.ts +82 -0
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-decision-maker-email/index.ts +122 -0
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/find-person-email/index.ts +89 -0
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/fetch/verify-email/index.ts +84 -0
- package/src/execution/engine/tools/integration/server/adapters/anymailfinder/index.ts +16 -0
- package/src/execution/engine/tools/integration/server/adapters/apify/__tests__/apify-run-actor.integration.test.ts +293 -0
- package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.ts +100 -0
- package/src/execution/engine/tools/integration/server/adapters/apify/apify-tools.ts +217 -0
- package/src/execution/engine/tools/integration/server/adapters/apify/fetch/get-dataset-items/index.ts +92 -0
- package/src/execution/engine/tools/integration/server/adapters/apify/fetch/run-actor/index.ts +218 -0
- package/src/execution/engine/tools/integration/server/adapters/apify/fetch/start-actor/index.ts +87 -0
- package/src/execution/engine/tools/integration/server/adapters/apify/index.ts +11 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/__tests__/attio-crud.integration.test.ts +362 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/attio-adapter.ts +162 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/attio-tools.ts +594 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/README.md +632 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-attribute/index.ts +214 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-note/index.ts +152 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/create-record/index.ts +141 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/delete-note/index.ts +86 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/delete-record/index.ts +105 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.test.ts +186 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.ts +118 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-attributes/index.ts +165 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-notes/index.ts +96 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-objects/index.ts +104 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.test.ts +338 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.ts +156 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/update-attribute/index.ts +220 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/update-record/index.ts +140 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/utils/types.ts +147 -0
- package/src/execution/engine/tools/integration/server/adapters/attio/index.ts +31 -0
- package/src/execution/engine/tools/integration/server/adapters/dropbox/__tests__/dropbox-adapter.test.ts +409 -0
- package/src/execution/engine/tools/integration/server/adapters/dropbox/dropbox-adapter.ts +281 -0
- package/src/execution/engine/tools/integration/server/adapters/dropbox/dropbox-tools.ts +106 -0
- package/src/execution/engine/tools/integration/server/adapters/dropbox/fetch/create-folder/__tests__/index.test.ts +451 -0
- package/src/execution/engine/tools/integration/server/adapters/dropbox/fetch/create-folder/index.ts +114 -0
- package/src/execution/engine/tools/integration/server/adapters/dropbox/fetch/upload-file/__tests__/index.test.ts +415 -0
- package/src/execution/engine/tools/integration/server/adapters/dropbox/fetch/upload-file/index.ts +111 -0
- package/src/execution/engine/tools/integration/server/adapters/dropbox/index.ts +25 -0
- package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-adapter.ts +210 -0
- package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-tools.ts +104 -0
- package/src/execution/engine/tools/integration/server/adapters/google-sheets/__tests__/google-sheets.integration.test.ts +261 -0
- package/src/execution/engine/tools/integration/server/adapters/google-sheets/google-sheets-adapter.ts +1189 -0
- package/src/execution/engine/tools/integration/server/adapters/google-sheets/google-sheets-tools.ts +641 -0
- package/src/execution/engine/tools/integration/server/adapters/google-sheets/index.ts +18 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/activate-campaign/index.ts +86 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/add-to-campaign/__tests__/index.test.ts +289 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/add-to-campaign/index.ts +154 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-add-leads/__tests__/index.test.ts +325 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-add-leads/index.ts +153 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/bulk-delete-leads/index.ts +84 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/create-campaign/index.ts +125 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/create-inbox-test/index.ts +107 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/delete-campaign/index.ts +85 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-account-health/index.ts +91 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign/index.ts +92 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign-analytics/__tests__/index.test.ts +195 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-campaign-analytics/index.ts +113 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-daily-campaign-analytics/index.ts +104 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-emails/index.ts +155 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-step-analytics/__tests__/index.test.ts +196 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/get-step-analytics/index.ts +102 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-campaigns/__tests__/index.test.ts +189 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-campaigns/index.ts +87 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/list-leads/index.ts +112 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/patch-lead/index.ts +76 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/pause-campaign/index.ts +86 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/remove-from-subsequence/index.ts +98 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/send-reply/index.ts +126 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-campaign/__tests__/index.test.ts +193 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-campaign/index.ts +99 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-interest-status/__tests__/index.test.ts +621 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/fetch/update-interest-status/index.ts +125 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/index.ts +29 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-adapter.ts +178 -0
- package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-tools.ts +1473 -0
- package/src/execution/engine/tools/integration/server/adapters/millionverifier/fetch/check-credits/index.ts +59 -0
- package/src/execution/engine/tools/integration/server/adapters/millionverifier/fetch/verify-email/index.ts +102 -0
- package/src/execution/engine/tools/integration/server/adapters/millionverifier/index.ts +17 -0
- package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-adapter.ts +80 -0
- package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-tools.ts +102 -0
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/get-email/index.ts +102 -0
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.ts +134 -0
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/utils/types.ts +75 -0
- package/src/execution/engine/tools/integration/server/adapters/resend/index.ts +27 -0
- package/src/execution/engine/tools/integration/server/adapters/resend/resend-adapter.ts +108 -0
- package/src/execution/engine/tools/integration/server/adapters/resend/resend-tools.ts +132 -0
- package/src/execution/engine/tools/integration/server/adapters/resend/types.ts +44 -0
- package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/create-envelope/index.ts +274 -0
- package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/download-document/index.ts +230 -0
- package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/get-envelope/index.ts +133 -0
- package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/utils/types.ts +246 -0
- package/src/execution/engine/tools/integration/server/adapters/signature-api/fetch/void-envelope/index.ts +90 -0
- package/src/execution/engine/tools/integration/server/adapters/signature-api/index.ts +38 -0
- package/src/execution/engine/tools/integration/server/adapters/signature-api/signature-api-adapter.ts +87 -0
- package/src/execution/engine/tools/integration/server/adapters/signature-api/signature-api-tools.ts +179 -0
- package/src/execution/engine/tools/integration/server/adapters/stripe/fetch/utils/types.ts +210 -0
- package/src/execution/engine/tools/integration/server/adapters/stripe/index.ts +44 -0
- package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-adapter.ts +517 -0
- package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-tools.ts +309 -0
- package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/domain-search/index.ts +133 -0
- package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/email-finder/index.ts +122 -0
- package/src/execution/engine/tools/integration/server/adapters/tomba/fetch/email-verifier/index.ts +111 -0
- package/src/execution/engine/tools/integration/server/adapters/tomba/index.ts +11 -0
- package/src/execution/engine/tools/integration/server/adapters/tomba/tomba-adapter.ts +78 -0
- package/src/execution/engine/tools/integration/server/adapters/tomba/tomba-tools.ts +222 -0
- package/src/execution/engine/tools/integration/server/index.ts +61 -0
- package/src/execution/engine/tools/integration/service.ts +161 -0
- package/src/execution/engine/tools/integration/tool.ts +253 -0
- package/src/execution/engine/tools/integration/types/anymailfinder.ts +74 -0
- package/src/execution/engine/tools/integration/types/apify.ts +92 -0
- package/src/execution/engine/tools/integration/types/attio.ts +354 -0
- package/src/execution/engine/tools/integration/types/dropbox.ts +64 -0
- package/src/execution/engine/tools/integration/types/gmail.ts +35 -0
- package/src/execution/engine/tools/integration/types/google-sheets.ts +303 -0
- package/src/execution/engine/tools/integration/types/index.ts +19 -0
- package/src/execution/engine/tools/integration/types/instantly.ts +557 -0
- package/src/execution/engine/tools/integration/types/millionverifier.ts +56 -0
- package/src/execution/engine/tools/integration/types/resend.ts +63 -0
- package/src/execution/engine/tools/integration/types/signature-api.ts +164 -0
- package/src/execution/engine/tools/integration/types/stripe.ts +162 -0
- package/src/execution/engine/tools/integration/types/tomba.ts +94 -0
- package/src/execution/engine/tools/lead-service-types.ts +884 -0
- package/src/execution/engine/tools/llm/index.ts +11 -0
- package/src/execution/engine/tools/llm/server/index.ts +8 -0
- package/src/execution/engine/tools/llm/server/llm-call-tool.ts +118 -0
- package/src/execution/engine/tools/platform/__tests__/approval.test.ts +242 -0
- package/src/execution/engine/tools/platform/__tests__/email.test.ts +482 -0
- package/src/execution/engine/tools/platform/__tests__/hitl-cancel.test.ts +97 -0
- package/src/execution/engine/tools/platform/__tests__/notification.test.ts +208 -0
- package/src/execution/engine/tools/platform/__tests__/pdf.test.ts +441 -0
- package/src/execution/engine/tools/platform/__tests__/scheduler.test.ts +189 -0
- package/src/execution/engine/tools/platform/__tests__/schedules.test.ts +336 -0
- package/src/execution/engine/tools/platform/acquisition/company-tools.ts +248 -0
- package/src/execution/engine/tools/platform/acquisition/contact-tools.ts +319 -0
- package/src/execution/engine/tools/platform/acquisition/index.ts +43 -0
- package/src/execution/engine/tools/platform/acquisition/list-tools.ts +148 -0
- package/src/execution/engine/tools/platform/acquisition/types.ts +260 -0
- package/src/execution/engine/tools/platform/approval/cancel-by-metadata.ts +65 -0
- package/src/execution/engine/tools/platform/approval/index.ts +4 -0
- package/src/execution/engine/tools/platform/approval/tool.ts +99 -0
- package/src/execution/engine/tools/platform/email/index.ts +122 -0
- package/src/execution/engine/tools/platform/email/types.ts +96 -0
- package/src/execution/engine/tools/platform/index.ts +181 -0
- package/src/execution/engine/tools/platform/notification.ts +81 -0
- package/src/execution/engine/tools/platform/pdf/index.ts +110 -0
- package/src/execution/engine/tools/platform/pdf/types.ts +77 -0
- package/src/execution/engine/tools/platform/resource-invocation/__tests__/edge-cases.test.ts +507 -0
- package/src/execution/engine/tools/platform/resource-invocation/__tests__/resource-invocation-service.test.ts +500 -0
- package/src/execution/engine/tools/platform/resource-invocation/__tests__/tool.test.ts +555 -0
- package/src/execution/engine/tools/platform/resource-invocation/dynamic-tool.ts +94 -0
- package/src/execution/engine/tools/platform/resource-invocation/index.ts +14 -0
- package/src/execution/engine/tools/platform/resource-invocation/resource-invocation-service.ts +147 -0
- package/src/execution/engine/tools/platform/resource-invocation/tool.ts +115 -0
- package/src/execution/engine/tools/platform/resource-invocation/types.ts +31 -0
- package/src/execution/engine/tools/platform/scheduler.ts +87 -0
- package/src/execution/engine/tools/platform/schedules/cancel-by-key-tool.ts +48 -0
- package/src/execution/engine/tools/platform/schedules/cancel-by-metadata-tool.ts +42 -0
- package/src/execution/engine/tools/platform/schedules/delete-by-key-tool.ts +43 -0
- package/src/execution/engine/tools/platform/schedules/index.ts +13 -0
- package/src/execution/engine/tools/platform/schedules/list-tool.ts +56 -0
- package/src/execution/engine/tools/platform/schedules/types.ts +88 -0
- package/src/execution/engine/tools/platform/storage/__tests__/storage.test.ts +998 -0
- package/src/execution/engine/tools/platform/storage/index.ts +370 -0
- package/src/execution/engine/tools/platform/storage/types.ts +128 -0
- package/src/execution/engine/tools/platform/types.ts +148 -0
- package/src/execution/engine/tools/registry.ts +590 -0
- package/src/execution/engine/tools/tool-maps.ts +694 -0
- package/src/execution/engine/tools/types.ts +233 -0
- package/src/execution/engine/workflow/__tests__/errors.test.ts +139 -0
- package/src/execution/engine/workflow/__tests__/utils.test.ts +645 -0
- package/src/execution/engine/workflow/__tests__/workflow.test.ts +818 -0
- package/src/execution/engine/workflow/errors.ts +63 -0
- package/src/execution/engine/workflow/helpers/index.ts +11 -0
- package/src/execution/engine/workflow/helpers/server/index.ts +8 -0
- package/src/execution/engine/workflow/helpers/server/llm-call.ts +93 -0
- package/src/execution/engine/workflow/index.ts +19 -0
- package/src/execution/engine/workflow/log-truncate.ts +26 -0
- package/src/execution/engine/workflow/logging.ts +191 -0
- package/src/execution/engine/workflow/types.ts +183 -0
- package/src/execution/engine/workflow/utils.ts +280 -0
- package/src/execution/engine/workflow/workflow.ts +168 -0
- package/src/execution/index.ts +20 -0
- package/src/execution/scheduler/__tests__/api-schemas.test.ts +733 -0
- package/src/execution/scheduler/__tests__/retry.test.ts +37 -0
- package/src/execution/scheduler/__tests__/utils.test.ts +1009 -0
- package/src/execution/scheduler/api-schemas.ts +296 -0
- package/src/execution/scheduler/index.ts +50 -0
- package/src/execution/scheduler/schemas.ts +264 -0
- package/src/execution/scheduler/types.ts +111 -0
- package/src/execution/scheduler/utils.ts +364 -0
- package/src/forms/index.ts +7 -0
- package/src/forms/schemas.test.ts +113 -0
- package/src/forms/schemas.ts +69 -0
- package/src/forms/types.ts +70 -0
- package/src/index.ts +54 -0
- package/src/integrations/credentials/__tests__/api-schemas.test.ts +496 -0
- package/src/integrations/credentials/__tests__/schemas.test.ts +82 -0
- package/src/integrations/credentials/__tests__/utils.test.ts +144 -0
- package/src/integrations/credentials/api-schemas.ts +143 -0
- package/src/integrations/credentials/index.ts +32 -0
- package/src/integrations/credentials/schemas.ts +164 -0
- package/src/integrations/credentials/utils.ts +59 -0
- package/src/integrations/oauth/__tests__/provider-registry.test.ts +59 -0
- package/src/integrations/oauth/api-schemas.ts +92 -0
- package/src/integrations/oauth/index.ts +19 -0
- package/src/integrations/oauth/provider-registry.ts +61 -0
- package/src/integrations/oauth/server/__tests__/refresh-concurrent.test.ts +183 -0
- package/src/integrations/oauth/server/__tests__/refresh.integration.test.ts +257 -0
- package/src/integrations/oauth/server/__tests__/refresh.test.ts +577 -0
- package/src/integrations/oauth/server/credentials.ts +39 -0
- package/src/integrations/oauth/server/refresh.ts +214 -0
- package/src/integrations/oauth/types.ts +34 -0
- package/src/integrations/webhook-endpoints/__tests__/api-schemas.test.ts +318 -0
- package/src/integrations/webhook-endpoints/api-schemas.ts +102 -0
- package/src/integrations/webhook-endpoints/index.ts +28 -0
- package/src/integrations/webhook-endpoints/types.ts +51 -0
- package/src/operations/activities/api-schemas.ts +79 -0
- package/src/operations/activities/index.ts +9 -0
- package/src/operations/activities/sse-events.ts +30 -0
- package/src/operations/activities/types.ts +63 -0
- package/src/operations/debug-logs/client.ts +60 -0
- package/src/operations/debug-logs/debug-logger.ts +83 -0
- package/src/operations/debug-logs/index.ts +8 -0
- package/src/operations/debug-logs/server.ts +19 -0
- package/src/operations/debug-logs/types.ts +33 -0
- package/src/operations/index.ts +50 -0
- package/src/operations/notifications/__tests__/api-schemas.test.ts +216 -0
- package/src/operations/notifications/api-schemas.ts +91 -0
- package/src/operations/notifications/index.ts +3 -0
- package/src/operations/notifications/sse-events.ts +21 -0
- package/src/operations/notifications/types.ts +47 -0
- package/src/operations/observability/__tests__/openrouter-cost-flow.test.ts +297 -0
- package/src/operations/observability/__tests__/schemas.test.ts +151 -0
- package/src/operations/observability/__tests__/types.test.ts +109 -0
- package/src/operations/observability/__tests__/utils.test.ts +54 -0
- package/src/operations/observability/ai-usage-collector.ts +64 -0
- package/src/operations/observability/index.ts +13 -0
- package/src/operations/observability/metrics-collector.ts +49 -0
- package/src/operations/observability/schemas.ts +39 -0
- package/src/operations/observability/types.ts +463 -0
- package/src/operations/observability/utils.ts +77 -0
- package/src/operations/sessions/__tests__/api-schemas.test.ts +361 -0
- package/src/operations/sessions/__tests__/manager.test.ts +821 -0
- package/src/operations/sessions/api-schemas.ts +166 -0
- package/src/operations/sessions/index.ts +26 -0
- package/src/operations/sessions/server/manager.ts +90 -0
- package/src/operations/sessions/server/session.ts +180 -0
- package/src/operations/sessions/types.ts +98 -0
- package/src/operations/triggers/index.ts +12 -0
- package/src/operations/triggers/webhook/definitions/__tests__/instantly-reply-received.test.ts +72 -0
- package/src/operations/triggers/webhook/definitions/instantly-account-error.ts +44 -0
- package/src/operations/triggers/webhook/definitions/instantly-auto-reply-received.ts +51 -0
- package/src/operations/triggers/webhook/definitions/instantly-campaign-completed.ts +45 -0
- package/src/operations/triggers/webhook/definitions/instantly-email-bounced.ts +49 -0
- package/src/operations/triggers/webhook/definitions/instantly-lead-unsubscribed.ts +45 -0
- package/src/operations/triggers/webhook/definitions/instantly-reply-received.ts +54 -0
- package/src/operations/triggers/webhook/index.ts +35 -0
- package/src/operations/triggers/webhook/types.ts +74 -0
- package/src/organization-model/README.md +79 -0
- package/src/organization-model/__tests__/graph.test.ts +250 -0
- package/src/organization-model/__tests__/resolve.test.ts +47 -0
- package/src/organization-model/defaults.ts +60 -0
- package/src/organization-model/domains/branding.ts +22 -0
- package/src/organization-model/domains/crm.ts +46 -0
- package/src/organization-model/domains/delivery.ts +48 -0
- package/src/organization-model/domains/features.ts +57 -0
- package/src/organization-model/domains/lead-gen.ts +33 -0
- package/src/organization-model/domains/navigation.ts +103 -0
- package/src/organization-model/domains/shared.ts +42 -0
- package/src/organization-model/graph/build.ts +432 -0
- package/src/organization-model/graph/index.ts +4 -0
- package/src/organization-model/graph/schema.ts +50 -0
- package/src/organization-model/graph/types.ts +52 -0
- package/src/organization-model/index.ts +11 -0
- package/src/organization-model/published.ts +18 -0
- package/src/organization-model/resolve.ts +42 -0
- package/src/organization-model/schema.ts +21 -0
- package/src/organization-model/types.ts +27 -0
- package/src/platform/api/index.ts +1 -0
- package/src/platform/api/types.ts +35 -0
- package/src/platform/constants/http.ts +37 -0
- package/src/platform/constants/index.ts +5 -0
- package/src/platform/constants/limits.ts +32 -0
- package/src/platform/constants/resilience.ts +51 -0
- package/src/platform/constants/timeouts.ts +20 -0
- package/src/platform/constants/versions.ts +3 -0
- package/src/platform/index.ts +27 -0
- package/src/platform/registry/__tests__/command-view.test.ts +410 -0
- package/src/platform/registry/__tests__/resource-registry-static.test.ts +347 -0
- package/src/platform/registry/__tests__/resource-registry.integration.test.ts +1004 -0
- package/src/platform/registry/__tests__/resource-registry.list-executable.test.ts +393 -0
- package/src/platform/registry/__tests__/resource-registry.test.ts +1942 -0
- package/src/platform/registry/__tests__/serialization.test.ts +1127 -0
- package/src/platform/registry/__tests__/validation.test.ts +1086 -0
- package/src/platform/registry/command-view.ts +180 -0
- package/src/platform/registry/domains.ts +165 -0
- package/src/platform/registry/index.ts +93 -0
- package/src/platform/registry/reserved.ts +24 -0
- package/src/platform/registry/resource-metadata.ts +59 -0
- package/src/platform/registry/resource-registry.command-queue-groups.test.ts +129 -0
- package/src/platform/registry/resource-registry.ts +788 -0
- package/src/platform/registry/serialization.ts +273 -0
- package/src/platform/registry/serialized-types.ts +231 -0
- package/src/platform/registry/stats-types.ts +66 -0
- package/src/platform/registry/types.ts +404 -0
- package/src/platform/registry/validation.ts +513 -0
- package/src/platform/resilience/__tests__/circuit-breaker.test.ts +291 -0
- package/src/platform/resilience/__tests__/http-error-mapper.test.ts +173 -0
- package/src/platform/resilience/__tests__/rate-limiter.test.ts +471 -0
- package/src/platform/resilience/__tests__/retry.test.ts +380 -0
- package/src/platform/resilience/__tests__/timeout.test.ts +219 -0
- package/src/platform/resilience/circuit-breaker.ts +164 -0
- package/src/platform/resilience/errors.ts +68 -0
- package/src/platform/resilience/http-error-mapper.ts +129 -0
- package/src/platform/resilience/index.ts +93 -0
- package/src/platform/resilience/rate-limiter-types.ts +46 -0
- package/src/platform/resilience/rate-limiter.ts +140 -0
- package/src/platform/resilience/retry.ts +89 -0
- package/src/platform/resilience/timeout.ts +63 -0
- package/src/platform/sse/events.ts +67 -0
- package/src/platform/sse/index.ts +7 -0
- package/src/platform/utils/__tests__/currency.test.ts +77 -0
- package/src/platform/utils/__tests__/validation.test.ts +1083 -0
- package/src/platform/utils/currency.ts +96 -0
- package/src/platform/utils/debounce.ts +52 -0
- package/src/platform/utils/error.ts +42 -0
- package/src/platform/utils/hmac.test.ts +97 -0
- package/src/platform/utils/index.ts +32 -0
- package/src/platform/utils/server/betterstack-logger.ts +210 -0
- package/src/platform/utils/server/hmac.ts +44 -0
- package/src/platform/utils/server/unsubscribe.ts +111 -0
- package/src/platform/utils/token-counter.ts +96 -0
- package/src/platform/utils/validation.ts +425 -0
- package/src/projects/api-schemas.ts +265 -0
- package/src/published.ts +1 -0
- package/src/server.ts +273 -0
- package/src/supabase/__tests__/helpers.test.ts +51 -0
- package/src/supabase/database.types.ts +2674 -0
- package/src/supabase/helpers.ts +20 -0
- package/src/supabase/index.ts +52 -0
- package/src/supabase/server/client.ts +58 -0
- package/src/test-utils/README.md +150 -0
- package/src/test-utils/browser-mocks.ts +54 -0
- package/src/test-utils/fixtures/api-keys.ts +52 -0
- package/src/test-utils/fixtures/index.ts +4 -0
- package/src/test-utils/fixtures/memberships.ts +80 -0
- package/src/test-utils/fixtures/organizations.ts +69 -0
- package/src/test-utils/fixtures/users.ts +79 -0
- package/src/test-utils/index.ts +11 -0
- package/src/test-utils/mocks/index.ts +2 -0
- package/src/test-utils/mocks/supabase.ts +142 -0
- package/src/test-utils/mocks/workos.ts +108 -0
- package/src/test-utils/rls/RLSTestContext.ts +586 -0
- package/src/test-utils/rls/index.ts +1 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Domain - Zod Validation Schemas
|
|
3
|
+
*
|
|
4
|
+
* Validation schemas for OAuth flow endpoints.
|
|
5
|
+
* Includes path params and query params for authorize/callback flows.
|
|
6
|
+
*
|
|
7
|
+
* Security:
|
|
8
|
+
* - All schemas use .strict() to prevent mass assignment attacks
|
|
9
|
+
* - Provider enum validation prevents invalid providers
|
|
10
|
+
* - OAuth code and state length limits prevent DoS
|
|
11
|
+
* - organizationId validation prevents injection
|
|
12
|
+
* - CSRF protection via state parameter validation
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { z } from 'zod'
|
|
16
|
+
import { OAuthProviderSchema, OAuthCodeSchema, OAuthStateParamSchema, CredentialNameSchema } from '../../platform/utils/validation'
|
|
17
|
+
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Path Parameters
|
|
20
|
+
// ============================================================================
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Validate OAuth provider in URL path
|
|
24
|
+
* Used by: GET /oauth/authorize/:provider, GET /oauth/callback/:provider
|
|
25
|
+
*
|
|
26
|
+
* Security: Enum validation prevents bypass attacks with invalid providers
|
|
27
|
+
*/
|
|
28
|
+
export const OAuthProviderParamSchema = z
|
|
29
|
+
.object({
|
|
30
|
+
provider: OAuthProviderSchema
|
|
31
|
+
})
|
|
32
|
+
.strict()
|
|
33
|
+
|
|
34
|
+
// ============================================================================
|
|
35
|
+
// Query Parameters - Authorize Flow
|
|
36
|
+
// ============================================================================
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* OAuth authorize endpoint query parameters
|
|
40
|
+
* GET /oauth/authorize/:provider?credentialName=...&organizationId=...
|
|
41
|
+
*
|
|
42
|
+
* Security:
|
|
43
|
+
* - credentialName validated (alphanumeric + hyphens/underscores)
|
|
44
|
+
* - organizationId required (public endpoint, can't use JWT)
|
|
45
|
+
* - organizationId validated (string format for WorkOS/UUID)
|
|
46
|
+
*/
|
|
47
|
+
export const AuthorizeQuerySchema = z
|
|
48
|
+
.object({
|
|
49
|
+
credentialName: CredentialNameSchema,
|
|
50
|
+
organizationId: z.string().min(1) // WorkOS org IDs or UUIDs
|
|
51
|
+
})
|
|
52
|
+
.strict()
|
|
53
|
+
|
|
54
|
+
// ============================================================================
|
|
55
|
+
// Query Parameters - Callback Flow
|
|
56
|
+
// ============================================================================
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* OAuth callback endpoint query parameters
|
|
60
|
+
* GET /oauth/callback/:provider?code=...&state=...&error=...
|
|
61
|
+
*
|
|
62
|
+
* Security:
|
|
63
|
+
* - code length limited (10-1000 chars)
|
|
64
|
+
* - state parameter validated (Base64-encoded JSON, max 2KB)
|
|
65
|
+
* - error optional (provider-specific error codes)
|
|
66
|
+
*
|
|
67
|
+
* CSRF Protection:
|
|
68
|
+
* - State parameter contains organizationId and credentialName
|
|
69
|
+
* - State validated to ensure request originated from our authorize endpoint
|
|
70
|
+
*/
|
|
71
|
+
export const CallbackQuerySchema = z
|
|
72
|
+
.object({
|
|
73
|
+
code: OAuthCodeSchema.optional(),
|
|
74
|
+
state: OAuthStateParamSchema.optional(),
|
|
75
|
+
error: z.string().max(100).optional() // OAuth error codes (access_denied, etc.)
|
|
76
|
+
})
|
|
77
|
+
.passthrough() // OAuth2 spec: "client MUST ignore unrecognized response parameters"
|
|
78
|
+
.refine(
|
|
79
|
+
(data) => data.code || data.error,
|
|
80
|
+
{
|
|
81
|
+
message: 'Either code or error parameter must be provided'
|
|
82
|
+
}
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
// ============================================================================
|
|
86
|
+
// TypeScript Type Exports
|
|
87
|
+
// ============================================================================
|
|
88
|
+
|
|
89
|
+
// Export inferred types for use in route handlers
|
|
90
|
+
export type OAuthProviderParam = z.infer<typeof OAuthProviderParamSchema>
|
|
91
|
+
export type AuthorizeQuery = z.infer<typeof AuthorizeQuerySchema>
|
|
92
|
+
export type CallbackQuery = z.infer<typeof CallbackQuerySchema>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Integration Exports
|
|
3
|
+
*
|
|
4
|
+
* Browser-safe exports (types and provider registry)
|
|
5
|
+
* Server-only exports (refresh functions with process.env) in ./server.ts
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export * from './types'
|
|
9
|
+
export * from './provider-registry'
|
|
10
|
+
|
|
11
|
+
// Validation schemas
|
|
12
|
+
export {
|
|
13
|
+
OAuthProviderParamSchema,
|
|
14
|
+
AuthorizeQuerySchema,
|
|
15
|
+
CallbackQuerySchema,
|
|
16
|
+
type OAuthProviderParam,
|
|
17
|
+
type AuthorizeQuery,
|
|
18
|
+
type CallbackQuery
|
|
19
|
+
} from './api-schemas'
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { OAuthProviderConfig } from './types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* OAuth Provider Registry
|
|
5
|
+
*
|
|
6
|
+
* Add new integration = add config object here (no new code needed)
|
|
7
|
+
*
|
|
8
|
+
* Standard token exchange methods:
|
|
9
|
+
* - basic-auth: client_id:client_secret in Authorization header
|
|
10
|
+
* - form-encoded: credentials in URL-encoded body (Google)
|
|
11
|
+
* - json-body: credentials in JSON body (most providers)
|
|
12
|
+
*
|
|
13
|
+
* Custom overrides for edge cases:
|
|
14
|
+
* - customAuthFlow: Override authorization URL building
|
|
15
|
+
* - customTokenExchange: Override token exchange logic
|
|
16
|
+
*/
|
|
17
|
+
export const OAUTH_PROVIDERS: Record<string, OAuthProviderConfig> = {
|
|
18
|
+
'google-sheets': {
|
|
19
|
+
id: 'google-sheets',
|
|
20
|
+
name: 'Google Sheets',
|
|
21
|
+
authUrl: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
22
|
+
tokenUrl: 'https://oauth2.googleapis.com/token',
|
|
23
|
+
authParams: {
|
|
24
|
+
access_type: 'offline', // Required for refresh token
|
|
25
|
+
prompt: 'consent' // Force consent to get refresh token on reconnect
|
|
26
|
+
},
|
|
27
|
+
tokenExchange: 'form-encoded',
|
|
28
|
+
scopes: ['https://www.googleapis.com/auth/spreadsheets']
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
dropbox: {
|
|
32
|
+
id: 'dropbox',
|
|
33
|
+
name: 'Dropbox',
|
|
34
|
+
authUrl: 'https://www.dropbox.com/oauth2/authorize',
|
|
35
|
+
tokenUrl: 'https://api.dropboxapi.com/oauth2/token',
|
|
36
|
+
authParams: {
|
|
37
|
+
token_access_type: 'offline' // Required for refresh token
|
|
38
|
+
},
|
|
39
|
+
tokenExchange: 'form-encoded',
|
|
40
|
+
scopes: ['files.content.write', 'files.content.read', 'files.metadata.write']
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Get provider config by ID
|
|
46
|
+
* @throws Error if provider not found
|
|
47
|
+
*/
|
|
48
|
+
export function getProviderConfig(providerId: string): OAuthProviderConfig {
|
|
49
|
+
const config = OAUTH_PROVIDERS[providerId]
|
|
50
|
+
if (!config) {
|
|
51
|
+
throw new Error(`Unknown OAuth provider: ${providerId}`)
|
|
52
|
+
}
|
|
53
|
+
return config
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* List all available providers (for frontend)
|
|
58
|
+
*/
|
|
59
|
+
export function listProviders(): OAuthProviderConfig[] {
|
|
60
|
+
return Object.values(OAUTH_PROVIDERS)
|
|
61
|
+
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
|
2
|
+
import { refreshOAuthTokenIfExpired, forceRefreshOAuthToken, _getInflightRefreshCount } from '../refresh'
|
|
3
|
+
import type { OAuthToken } from '../../types'
|
|
4
|
+
|
|
5
|
+
describe('concurrent OAuth token refresh deduplication', () => {
|
|
6
|
+
const originalFetch = global.fetch
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
process.env.DROPBOX_APP_KEY = 'test-dropbox-app-key'
|
|
10
|
+
process.env.DROPBOX_APP_SECRET = 'test-dropbox-app-secret'
|
|
11
|
+
process.env.GOOGLE_OAUTH_CLIENT_ID = 'test-google-client-id'
|
|
12
|
+
process.env.GOOGLE_OAUTH_CLIENT_SECRET = 'test-google-client-secret'
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
afterEach(() => {
|
|
16
|
+
global.fetch = originalFetch
|
|
17
|
+
vi.restoreAllMocks()
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
function makeExpiredToken(overrides?: Partial<OAuthToken>): OAuthToken {
|
|
21
|
+
return {
|
|
22
|
+
provider: 'dropbox',
|
|
23
|
+
accessToken: 'expired-access-token',
|
|
24
|
+
refreshToken: 'shared-refresh-token',
|
|
25
|
+
expiresAt: new Date(Date.now() - 10 * 60 * 1000).toISOString(),
|
|
26
|
+
tokenType: 'Bearer',
|
|
27
|
+
...overrides
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
it('should make only one fetch call when two concurrent refreshes use the same token', async () => {
|
|
32
|
+
let resolveRefresh!: (value: Response) => void
|
|
33
|
+
const mockFetch = vi.fn().mockReturnValue(
|
|
34
|
+
new Promise<Response>((resolve) => {
|
|
35
|
+
resolveRefresh = resolve
|
|
36
|
+
})
|
|
37
|
+
)
|
|
38
|
+
global.fetch = mockFetch
|
|
39
|
+
|
|
40
|
+
const token = makeExpiredToken()
|
|
41
|
+
|
|
42
|
+
// Fire two concurrent refreshes
|
|
43
|
+
const promise1 = refreshOAuthTokenIfExpired(token)
|
|
44
|
+
const promise2 = refreshOAuthTokenIfExpired(token)
|
|
45
|
+
|
|
46
|
+
// While in-flight, there should be exactly one tracked refresh
|
|
47
|
+
expect(_getInflightRefreshCount()).toBe(1)
|
|
48
|
+
|
|
49
|
+
// Resolve the single fetch call
|
|
50
|
+
resolveRefresh(
|
|
51
|
+
new Response(
|
|
52
|
+
JSON.stringify({
|
|
53
|
+
access_token: 'new-access-token',
|
|
54
|
+
refresh_token: 'new-refresh-token',
|
|
55
|
+
expires_in: 3600
|
|
56
|
+
}),
|
|
57
|
+
{ status: 200 }
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
const [result1, result2] = await Promise.all([promise1, promise2])
|
|
62
|
+
|
|
63
|
+
// Both get the same result
|
|
64
|
+
expect(result1.accessToken).toBe('new-access-token')
|
|
65
|
+
expect(result2.accessToken).toBe('new-access-token')
|
|
66
|
+
|
|
67
|
+
// Only one actual API call was made
|
|
68
|
+
expect(mockFetch).toHaveBeenCalledTimes(1)
|
|
69
|
+
|
|
70
|
+
// Map is cleaned up
|
|
71
|
+
expect(_getInflightRefreshCount()).toBe(0)
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it('should make separate fetch calls for different providers', async () => {
|
|
75
|
+
const mockFetch = vi.fn().mockImplementation(() =>
|
|
76
|
+
Promise.resolve(
|
|
77
|
+
new Response(
|
|
78
|
+
JSON.stringify({
|
|
79
|
+
access_token: 'new-token',
|
|
80
|
+
refresh_token: 'new-refresh',
|
|
81
|
+
expires_in: 3600
|
|
82
|
+
}),
|
|
83
|
+
{ status: 200 }
|
|
84
|
+
)
|
|
85
|
+
)
|
|
86
|
+
)
|
|
87
|
+
global.fetch = mockFetch
|
|
88
|
+
|
|
89
|
+
const dropboxToken = makeExpiredToken()
|
|
90
|
+
const googleToken = makeExpiredToken({
|
|
91
|
+
provider: 'google-sheets',
|
|
92
|
+
refreshToken: 'google-refresh-token'
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
await Promise.all([refreshOAuthTokenIfExpired(dropboxToken), refreshOAuthTokenIfExpired(googleToken)])
|
|
96
|
+
|
|
97
|
+
// Different providers = separate API calls
|
|
98
|
+
expect(mockFetch).toHaveBeenCalledTimes(2)
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('should make separate fetch calls for different refresh tokens on the same provider', async () => {
|
|
102
|
+
const mockFetch = vi.fn().mockImplementation(() =>
|
|
103
|
+
Promise.resolve(
|
|
104
|
+
new Response(
|
|
105
|
+
JSON.stringify({
|
|
106
|
+
access_token: 'new-token',
|
|
107
|
+
refresh_token: 'new-refresh',
|
|
108
|
+
expires_in: 3600
|
|
109
|
+
}),
|
|
110
|
+
{ status: 200 }
|
|
111
|
+
)
|
|
112
|
+
)
|
|
113
|
+
)
|
|
114
|
+
global.fetch = mockFetch
|
|
115
|
+
|
|
116
|
+
const token1 = makeExpiredToken({ refreshToken: 'user-a-refresh' })
|
|
117
|
+
const token2 = makeExpiredToken({ refreshToken: 'user-b-refresh' })
|
|
118
|
+
|
|
119
|
+
await Promise.all([refreshOAuthTokenIfExpired(token1), refreshOAuthTokenIfExpired(token2)])
|
|
120
|
+
|
|
121
|
+
// Different refresh tokens = different users = separate API calls
|
|
122
|
+
expect(mockFetch).toHaveBeenCalledTimes(2)
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
it('should propagate errors to all waiters when the refresh fails', async () => {
|
|
126
|
+
const mockFetch = vi.fn().mockResolvedValue(
|
|
127
|
+
new Response(
|
|
128
|
+
JSON.stringify({
|
|
129
|
+
error: 'invalid_grant',
|
|
130
|
+
error_description: 'Token revoked'
|
|
131
|
+
}),
|
|
132
|
+
{ status: 400 }
|
|
133
|
+
)
|
|
134
|
+
)
|
|
135
|
+
global.fetch = mockFetch
|
|
136
|
+
|
|
137
|
+
const token = makeExpiredToken()
|
|
138
|
+
|
|
139
|
+
const promise1 = forceRefreshOAuthToken(token)
|
|
140
|
+
const promise2 = forceRefreshOAuthToken(token)
|
|
141
|
+
|
|
142
|
+
// Both should reject with the same error
|
|
143
|
+
await expect(promise1).rejects.toThrow('invalid_grant')
|
|
144
|
+
await expect(promise2).rejects.toThrow('invalid_grant')
|
|
145
|
+
|
|
146
|
+
// Only one API call was made
|
|
147
|
+
expect(mockFetch).toHaveBeenCalledTimes(1)
|
|
148
|
+
|
|
149
|
+
// Map is cleaned up even on failure
|
|
150
|
+
expect(_getInflightRefreshCount()).toBe(0)
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
it('should allow a new refresh after the previous one completes', async () => {
|
|
154
|
+
let callCount = 0
|
|
155
|
+
const mockFetch = vi.fn().mockImplementation(() => {
|
|
156
|
+
callCount++
|
|
157
|
+
return Promise.resolve(
|
|
158
|
+
new Response(
|
|
159
|
+
JSON.stringify({
|
|
160
|
+
access_token: `token-${callCount}`,
|
|
161
|
+
refresh_token: 'new-refresh',
|
|
162
|
+
expires_in: 3600
|
|
163
|
+
}),
|
|
164
|
+
{ status: 200 }
|
|
165
|
+
)
|
|
166
|
+
)
|
|
167
|
+
})
|
|
168
|
+
global.fetch = mockFetch
|
|
169
|
+
|
|
170
|
+
const token = makeExpiredToken()
|
|
171
|
+
|
|
172
|
+
// First refresh
|
|
173
|
+
const result1 = await forceRefreshOAuthToken(token)
|
|
174
|
+
expect(result1.accessToken).toBe('token-1')
|
|
175
|
+
|
|
176
|
+
// Second refresh (after first completed)
|
|
177
|
+
const result2 = await forceRefreshOAuthToken(token)
|
|
178
|
+
expect(result2.accessToken).toBe('token-2')
|
|
179
|
+
|
|
180
|
+
// Two separate API calls (not deduplicated since they were sequential)
|
|
181
|
+
expect(mockFetch).toHaveBeenCalledTimes(2)
|
|
182
|
+
})
|
|
183
|
+
})
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { refreshOAuthTokenIfExpired } from '../refresh'
|
|
3
|
+
import type { OAuthToken } from '../../types'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Integration tests for OAuth token refresh with real provider APIs
|
|
7
|
+
*
|
|
8
|
+
* These tests use real credentials but manipulate the expiry date to force refresh.
|
|
9
|
+
* This allows testing the actual OAuth provider endpoints without waiting for token expiry.
|
|
10
|
+
*
|
|
11
|
+
* SETUP REQUIRED:
|
|
12
|
+
* 1. Ensure environment variables are set:
|
|
13
|
+
* - NOTION_CLIENT_ID
|
|
14
|
+
* - NOTION_CLIENT_SECRET
|
|
15
|
+
* - GOOGLE_OAUTH_CLIENT_ID (optional)
|
|
16
|
+
* - GOOGLE_OAUTH_CLIENT_SECRET (optional)
|
|
17
|
+
*
|
|
18
|
+
* 2. To get a real refresh token for testing:
|
|
19
|
+
* a. Complete OAuth flow via the app (AI Studio → Settings → Credentials)
|
|
20
|
+
* b. Retrieve the stored credential from the database
|
|
21
|
+
* c. Decrypt and extract the refresh_token
|
|
22
|
+
* d. Set it in the test below
|
|
23
|
+
*
|
|
24
|
+
* NOTE: These tests are skipped by default. Run with:
|
|
25
|
+
* pnpm test -- refresh.integration.test.ts
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
describe('OAuth Token Refresh Integration Tests', () => {
|
|
29
|
+
// Skip these tests by default since they require real credentials
|
|
30
|
+
// To run: update the token below and run `pnpm test -- refresh.integration.test.ts`
|
|
31
|
+
const SKIP_INTEGRATION_TESTS = true
|
|
32
|
+
|
|
33
|
+
describe('Notion provider (basic-auth)', () => {
|
|
34
|
+
it.skipIf(SKIP_INTEGRATION_TESTS)(
|
|
35
|
+
'should refresh Notion token with real API',
|
|
36
|
+
async () => {
|
|
37
|
+
// SETUP: Replace with a real Notion refresh token
|
|
38
|
+
const realNotionToken: OAuthToken = {
|
|
39
|
+
provider: 'notion',
|
|
40
|
+
accessToken: 'expired-or-old-access-token', // Will be replaced after refresh
|
|
41
|
+
refreshToken: 'YOUR_REAL_NOTION_REFRESH_TOKEN_HERE', // <-- UPDATE THIS
|
|
42
|
+
expiresAt: new Date(Date.now() - 10 * 60 * 1000).toISOString(), // Force refresh (10 min ago)
|
|
43
|
+
tokenType: 'Bearer'
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// This will make a real API call to Notion's token endpoint
|
|
47
|
+
const refreshedToken = await refreshOAuthTokenIfExpired(realNotionToken)
|
|
48
|
+
|
|
49
|
+
// Verify the refresh worked
|
|
50
|
+
expect(refreshedToken.provider).toBe('notion')
|
|
51
|
+
expect(refreshedToken.accessToken).not.toBe(realNotionToken.accessToken)
|
|
52
|
+
expect(refreshedToken.accessToken).toBeTruthy()
|
|
53
|
+
expect(refreshedToken.refreshToken).toBeTruthy()
|
|
54
|
+
|
|
55
|
+
// Verify new token will expire in the future
|
|
56
|
+
const expiresAt = new Date(refreshedToken.expiresAt).getTime()
|
|
57
|
+
const now = Date.now()
|
|
58
|
+
expect(expiresAt).toBeGreaterThan(now)
|
|
59
|
+
|
|
60
|
+
// Log result for debugging
|
|
61
|
+
console.log('✓ Notion token refreshed successfully')
|
|
62
|
+
console.log(' New access token (first 20 chars):', refreshedToken.accessToken.substring(0, 20) + '...')
|
|
63
|
+
console.log(' Expires at:', refreshedToken.expiresAt)
|
|
64
|
+
console.log(' Time until expiry:', Math.round((expiresAt - now) / 60000), 'minutes')
|
|
65
|
+
},
|
|
66
|
+
{ timeout: 10000 } // 10 second timeout for API call
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
it.skipIf(SKIP_INTEGRATION_TESTS)(
|
|
70
|
+
'should handle Notion token that is still valid',
|
|
71
|
+
async () => {
|
|
72
|
+
// SETUP: Replace with a real Notion refresh token
|
|
73
|
+
const validNotionToken: OAuthToken = {
|
|
74
|
+
provider: 'notion',
|
|
75
|
+
accessToken: 'current-valid-access-token',
|
|
76
|
+
refreshToken: 'YOUR_REAL_NOTION_REFRESH_TOKEN_HERE', // <-- UPDATE THIS
|
|
77
|
+
expiresAt: new Date(Date.now() + 30 * 60 * 1000).toISOString(), // 30 min in future
|
|
78
|
+
tokenType: 'Bearer'
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Should return same token without API call (still valid)
|
|
82
|
+
const result = await refreshOAuthTokenIfExpired(validNotionToken)
|
|
83
|
+
|
|
84
|
+
expect(result).toBe(validNotionToken) // Same object reference
|
|
85
|
+
console.log('✓ Valid token returned unchanged (no API call made)')
|
|
86
|
+
}
|
|
87
|
+
)
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
describe('Google Sheets provider (form-encoded)', () => {
|
|
91
|
+
it.skipIf(SKIP_INTEGRATION_TESTS)(
|
|
92
|
+
'should refresh Google Sheets token with real API',
|
|
93
|
+
async () => {
|
|
94
|
+
// SETUP: Replace with a real Google Sheets refresh token
|
|
95
|
+
const realGoogleToken: OAuthToken = {
|
|
96
|
+
provider: 'google-sheets',
|
|
97
|
+
accessToken: 'expired-or-old-access-token',
|
|
98
|
+
refreshToken: 'YOUR_REAL_GOOGLE_REFRESH_TOKEN_HERE', // <-- UPDATE THIS
|
|
99
|
+
expiresAt: new Date(Date.now() - 10 * 60 * 1000).toISOString(), // Force refresh
|
|
100
|
+
tokenType: 'Bearer',
|
|
101
|
+
scope: 'https://www.googleapis.com/auth/spreadsheets'
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const refreshedToken = await refreshOAuthTokenIfExpired(realGoogleToken)
|
|
105
|
+
|
|
106
|
+
expect(refreshedToken.provider).toBe('google-sheets')
|
|
107
|
+
expect(refreshedToken.accessToken).not.toBe(realGoogleToken.accessToken)
|
|
108
|
+
expect(refreshedToken.accessToken).toBeTruthy()
|
|
109
|
+
expect(refreshedToken.refreshToken).toBeTruthy()
|
|
110
|
+
|
|
111
|
+
// Verify scope is preserved
|
|
112
|
+
expect(refreshedToken.scope).toBe('https://www.googleapis.com/auth/spreadsheets')
|
|
113
|
+
|
|
114
|
+
console.log('✓ Google Sheets token refreshed successfully')
|
|
115
|
+
console.log(' New access token (first 20 chars):', refreshedToken.accessToken.substring(0, 20) + '...')
|
|
116
|
+
console.log(' Expires at:', refreshedToken.expiresAt)
|
|
117
|
+
},
|
|
118
|
+
{ timeout: 10000 }
|
|
119
|
+
)
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
describe('Error scenarios with real API', () => {
|
|
123
|
+
it.skipIf(SKIP_INTEGRATION_TESTS)(
|
|
124
|
+
'should handle invalid refresh token with real Notion API',
|
|
125
|
+
async () => {
|
|
126
|
+
const tokenWithInvalidRefreshToken: OAuthToken = {
|
|
127
|
+
provider: 'notion',
|
|
128
|
+
accessToken: 'old-token',
|
|
129
|
+
refreshToken: 'completely-invalid-refresh-token-12345', // Invalid token
|
|
130
|
+
expiresAt: new Date(Date.now() - 10 * 60 * 1000).toISOString(),
|
|
131
|
+
tokenType: 'Bearer'
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Should throw error from Notion API
|
|
135
|
+
await expect(refreshOAuthTokenIfExpired(tokenWithInvalidRefreshToken)).rejects.toThrow()
|
|
136
|
+
|
|
137
|
+
console.log('✓ Invalid refresh token correctly rejected by Notion API')
|
|
138
|
+
},
|
|
139
|
+
{ timeout: 10000 }
|
|
140
|
+
)
|
|
141
|
+
})
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* HELPER: Script to test with a credential from the database
|
|
146
|
+
*
|
|
147
|
+
* To use this with a real stored credential:
|
|
148
|
+
*
|
|
149
|
+
* 1. Get credential from database:
|
|
150
|
+
* ```sql
|
|
151
|
+
* SELECT * FROM credentials
|
|
152
|
+
* WHERE name = 'notion-prod'
|
|
153
|
+
* AND organization_id = 'your-org-id';
|
|
154
|
+
* ```
|
|
155
|
+
*
|
|
156
|
+
* 2. Decrypt the encrypted_value using CredentialsService
|
|
157
|
+
*
|
|
158
|
+
* 3. Extract the token object
|
|
159
|
+
*
|
|
160
|
+
* 4. Manipulate the expiresAt field:
|
|
161
|
+
* ```typescript
|
|
162
|
+
* const token = decryptedCredential as OAuthToken
|
|
163
|
+
* const expiredToken = {
|
|
164
|
+
* ...token,
|
|
165
|
+
* expiresAt: new Date(Date.now() - 10 * 60 * 1000).toISOString()
|
|
166
|
+
* }
|
|
167
|
+
* ```
|
|
168
|
+
*
|
|
169
|
+
* 5. Test refresh:
|
|
170
|
+
* ```typescript
|
|
171
|
+
* const refreshed = await refreshOAuthTokenIfExpired(expiredToken)
|
|
172
|
+
* ```
|
|
173
|
+
*
|
|
174
|
+
* 6. Save refreshed token back to database:
|
|
175
|
+
* ```typescript
|
|
176
|
+
* await credentialsService.updateCredential(orgId, credentialName, refreshed)
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
|
|
180
|
+
describe('Real Credential Testing Pattern', () => {
|
|
181
|
+
it('demonstrates how to test with database credentials', async () => {
|
|
182
|
+
// This is a documentation test showing the pattern
|
|
183
|
+
// Not meant to run - just shows the workflow
|
|
184
|
+
|
|
185
|
+
// Step 1: Load credential from database (pseudo-code)
|
|
186
|
+
// const credential = await credentialsService.getCredential(orgId, 'notion-prod')
|
|
187
|
+
// const token = credential as OAuthToken
|
|
188
|
+
|
|
189
|
+
// Step 2: Manipulate expiry to force refresh
|
|
190
|
+
// const mockToken: OAuthToken = {
|
|
191
|
+
// provider: 'notion',
|
|
192
|
+
// accessToken: 'secret_abc123...', // Real token from DB
|
|
193
|
+
// refreshToken: 'secret_refresh_xyz...', // Real refresh token from DB
|
|
194
|
+
// expiresAt: new Date(Date.now() - 10 * 60 * 1000).toISOString(), // MANIPULATED: 10 min ago
|
|
195
|
+
// tokenType: 'Bearer'
|
|
196
|
+
// }
|
|
197
|
+
|
|
198
|
+
// Step 3: Test refresh (would make real API call if not skipped)
|
|
199
|
+
// const refreshed = await refreshOAuthTokenIfExpired(mockToken)
|
|
200
|
+
|
|
201
|
+
// Step 4: Verify and optionally save back
|
|
202
|
+
// expect(refreshed.accessToken).not.toBe(mockToken.accessToken)
|
|
203
|
+
// await credentialsService.updateCredential(orgId, 'notion-prod', refreshed)
|
|
204
|
+
|
|
205
|
+
// This test is just documentation - always passes
|
|
206
|
+
expect(true).toBe(true)
|
|
207
|
+
})
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* MANUAL TESTING SCRIPT
|
|
212
|
+
*
|
|
213
|
+
* To manually test token refresh with a real credential:
|
|
214
|
+
*
|
|
215
|
+
* 1. Create a test file: packages/core/src/integrations/oauth/server/__tests__/manual-refresh-test.ts
|
|
216
|
+
*
|
|
217
|
+
* 2. Add this code:
|
|
218
|
+
*
|
|
219
|
+
* ```typescript
|
|
220
|
+
* import { refreshOAuthTokenIfExpired } from '../refresh'
|
|
221
|
+
* import type { OAuthToken } from '../../types'
|
|
222
|
+
*
|
|
223
|
+
* async function testRefresh() {
|
|
224
|
+
* // Get a real token from your database
|
|
225
|
+
* const realToken: OAuthToken = {
|
|
226
|
+
* provider: 'notion',
|
|
227
|
+
* accessToken: 'paste-real-access-token-here',
|
|
228
|
+
* refreshToken: 'paste-real-refresh-token-here',
|
|
229
|
+
* expiresAt: new Date(Date.now() - 10 * 60 * 1000).toISOString(), // Force refresh
|
|
230
|
+
* tokenType: 'Bearer'
|
|
231
|
+
* }
|
|
232
|
+
*
|
|
233
|
+
* console.log('Original token:', {
|
|
234
|
+
* accessToken: realToken.accessToken.substring(0, 20) + '...',
|
|
235
|
+
* expiresAt: realToken.expiresAt
|
|
236
|
+
* })
|
|
237
|
+
*
|
|
238
|
+
* try {
|
|
239
|
+
* const refreshed = await refreshOAuthTokenIfExpired(realToken)
|
|
240
|
+
*
|
|
241
|
+
* console.log('Refreshed token:', {
|
|
242
|
+
* accessToken: refreshed.accessToken.substring(0, 20) + '...',
|
|
243
|
+
* expiresAt: refreshed.expiresAt,
|
|
244
|
+
* changed: refreshed.accessToken !== realToken.accessToken
|
|
245
|
+
* })
|
|
246
|
+
*
|
|
247
|
+
* console.log('✓ Token refresh successful!')
|
|
248
|
+
* } catch (error) {
|
|
249
|
+
* console.error('✗ Token refresh failed:', error)
|
|
250
|
+
* }
|
|
251
|
+
* }
|
|
252
|
+
*
|
|
253
|
+
* testRefresh()
|
|
254
|
+
* ```
|
|
255
|
+
*
|
|
256
|
+
* 3. Run with: pnpm tsx packages/core/src/integrations/oauth/server/__tests__/manual-refresh-test.ts
|
|
257
|
+
*/
|