@hubspot/app-connect-sdk 1.0.0-alpha.2 → 1.0.0-alpha.4
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/.turbo/turbo-tsdown.log +41 -510
- package/build/tsconfig.browser.tsbuildinfo +1 -1
- package/build/tsconfig.server.tsbuildinfo +1 -1
- package/dist/browser/{HubSpotAppConnect-BW45gyDs.js → HubSpotAppConnect-COQgPrFn.js} +5 -3
- package/dist/browser/HubSpotAppConnect-COQgPrFn.js.map +1 -0
- package/dist/browser/{create-vctOhpX9.js → create-hzqjIhmO.js} +54 -25
- package/dist/browser/create-hzqjIhmO.js.map +1 -0
- package/dist/browser/index.js +1 -1
- package/dist/browser/react/lovable.js +2 -2
- package/dist/browser/react.js +1 -1
- package/dist/server/api-client.d.ts +60625 -197
- package/dist/server/api-client.js +5826 -100
- package/dist/server/api-client.js.map +1 -0
- package/dist/server/{api-client-core/client.js → binary-data-BOalJzKu.js} +58 -3
- package/dist/server/binary-data-BOalJzKu.js.map +1 -0
- package/dist/server/lovable.d.ts +117 -6
- package/dist/server/lovable.js +1458 -3
- package/dist/server/lovable.js.map +1 -0
- package/dist/server/oauth.d.ts +128 -6
- package/dist/server/oauth.js +1 -4
- package/dist/server/sha256-B7y8GBFB.js +228 -0
- package/dist/server/sha256-B7y8GBFB.js.map +1 -0
- package/dist/server/{types.d.ts → types-5gfN91Fq.d.ts} +2 -2
- package/dist/server/{api-client-core/types.d.ts → types-DEOUH4wE.d.ts} +2 -2
- package/package.json +4 -10
- package/src/browser/app-connect-controller/connect-start.ts +2 -1
- package/src/browser/app-connect-controller/init.test.ts +167 -0
- package/src/browser/app-connect-controller/init.ts +70 -19
- package/src/browser/react/components/AppConnectHeader/AppConnectHeader.tsx +3 -5
- package/src/browser/react/components/ConnectButton/ConnectButton.tsx +2 -1
- package/src/server/api-client-core/plugins/fetch-transport.ts +5 -1
- package/src/server/constants.ts +29 -4
- package/src/server/hono/hono-request-handler.ts +42 -15
- package/src/server/hono/hubspot-connect-routes/auth-complete.test.ts +285 -0
- package/src/server/hono/hubspot-connect-routes/{auth-callback.ts → auth-complete.ts} +73 -30
- package/src/server/hono/hubspot-connect-routes/auth-init-session.test.ts +114 -30
- package/src/server/hono/hubspot-connect-routes/auth-init-session.ts +33 -10
- package/src/server/hono/hubspot-connect-routes/auth-logout.test.ts +13 -0
- package/src/server/hono/hubspot-connect-routes/auth-logout.ts +18 -0
- package/src/server/hono/hubspot-connect-routes/auth-refresh.test.ts +6 -0
- package/src/server/hono/hubspot-connect-routes/auth-refresh.ts +6 -0
- package/src/server/hono/hubspot-connect-routes/hubspot-connect-routes.ts +9 -2
- package/src/server/hono/hubspot-connect-routes/utils.ts +57 -1
- package/src/server/hono/types.ts +15 -9
- package/src/server/hono/utils/cookie-utils.ts +27 -2
- package/src/server/hono/utils/cors-middleware.test.ts +79 -0
- package/src/server/hono/utils/cors-middleware.ts +95 -0
- package/src/server/sanitize-request.ts +25 -11
- package/src/server/types.ts +2 -2
- package/src/shared/constants.ts +31 -3
- package/src/shared/wire-types.ts +19 -0
- package/tsdown.config.ts +1 -1
- package/.turbo/turbo-format$colon$check.log +0 -4
- package/.turbo/turbo-lint.log +0 -2
- package/.turbo/turbo-test.log +0 -76
- package/dist/browser/HubSpotAppConnect-BW45gyDs.js.map +0 -1
- package/dist/browser/create-vctOhpX9.js.map +0 -1
- package/dist/server/api-client-core/apis/account/account-info-types.generated.d.ts +0 -111
- package/dist/server/api-client-core/apis/account/account-info.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/account/account-info.generated.js +0 -9
- package/dist/server/api-client-core/apis/account/account-info.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/account/audit-logs-types.generated.d.ts +0 -247
- package/dist/server/api-client-core/apis/account/audit-logs.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/account/audit-logs.generated.js +0 -28
- package/dist/server/api-client-core/apis/account/audit-logs.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/auth/oauth-types.generated.d.ts +0 -121
- package/dist/server/api-client-core/apis/auth/oauth.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/auth/oauth.generated.js +0 -19
- package/dist/server/api-client-core/apis/auth/oauth.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/automation/actions-types.generated.d.ts +0 -933
- package/dist/server/api-client-core/apis/automation/actions.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/automation/actions.generated.js +0 -121
- package/dist/server/api-client-core/apis/automation/actions.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/automation/sequences-types.generated.d.ts +0 -422
- package/dist/server/api-client-core/apis/automation/sequences.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/automation/sequences.generated.js +0 -22
- package/dist/server/api-client-core/apis/automation/sequences.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/business-units-types.generated.d.ts +0 -75
- package/dist/server/api-client-core/apis/business-units.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/business-units.generated.js +0 -12
- package/dist/server/api-client-core/apis/business-units.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/cms/authors-types.generated.d.ts +0 -551
- package/dist/server/api-client-core/apis/cms/authors.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/cms/authors.generated.js +0 -163
- package/dist/server/api-client-core/apis/cms/authors.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/cms/blog-settings-types.generated.d.ts +0 -366
- package/dist/server/api-client-core/apis/cms/blog-settings.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/cms/blog-settings.generated.js +0 -43
- package/dist/server/api-client-core/apis/cms/blog-settings.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/cms/cms-content-audit-types.generated.d.ts +0 -157
- package/dist/server/api-client-core/apis/cms/cms-content-audit.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/cms/cms-content-audit.generated.js +0 -18
- package/dist/server/api-client-core/apis/cms/cms-content-audit.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/cms/domains-types.generated.d.ts +0 -193
- package/dist/server/api-client-core/apis/cms/domains.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/cms/domains.generated.js +0 -20
- package/dist/server/api-client-core/apis/cms/domains.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/cms/hubdb-types.generated.d.ts +0 -1097
- package/dist/server/api-client-core/apis/cms/hubdb.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/cms/hubdb.generated.js +0 -192
- package/dist/server/api-client-core/apis/cms/hubdb.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/cms/media-bridge-types.generated.d.ts +0 -1780
- package/dist/server/api-client-core/apis/cms/media-bridge.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/cms/media-bridge.generated.js +0 -185
- package/dist/server/api-client-core/apis/cms/media-bridge.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/cms/pages-types.generated.d.ts +0 -1768
- package/dist/server/api-client-core/apis/cms/pages.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/cms/pages.generated.js +0 -331
- package/dist/server/api-client-core/apis/cms/pages.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/cms/posts-types.generated.d.ts +0 -1090
- package/dist/server/api-client-core/apis/cms/posts.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/cms/posts.generated.js +0 -201
- package/dist/server/api-client-core/apis/cms/posts.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/cms/site-search-types.generated.d.ts +0 -200
- package/dist/server/api-client-core/apis/cms/site-search.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/cms/site-search.generated.js +0 -32
- package/dist/server/api-client-core/apis/cms/site-search.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/cms/source-code-types.generated.d.ts +0 -218
- package/dist/server/api-client-core/apis/cms/source-code.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/cms/source-code.generated.js +0 -52
- package/dist/server/api-client-core/apis/cms/source-code.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/cms/tags-types.generated.d.ts +0 -515
- package/dist/server/api-client-core/apis/cms/tags.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/cms/tags.generated.js +0 -163
- package/dist/server/api-client-core/apis/cms/tags.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/cms/url-mappings-types.generated.d.ts +0 -177
- package/dist/server/api-client-core/apis/cms/url-mappings.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/cms/url-mappings.generated.js +0 -14
- package/dist/server/api-client-core/apis/cms/url-mappings.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/cms/url-redirects-types.generated.d.ts +0 -226
- package/dist/server/api-client-core/apis/cms/url-redirects.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/cms/url-redirects.generated.js +0 -26
- package/dist/server/api-client-core/apis/cms/url-redirects.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/communication-preferences/subscriptions-types.generated.d.ts +0 -802
- package/dist/server/api-client-core/apis/communication-preferences/subscriptions.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/communication-preferences/subscriptions.generated.js +0 -74
- package/dist/server/api-client-core/apis/communication-preferences/subscriptions.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/conversations/custom-channels-types.generated.d.ts +0 -551
- package/dist/server/api-client-core/apis/conversations/custom-channels.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/conversations/custom-channels.generated.js +0 -80
- package/dist/server/api-client-core/apis/conversations/custom-channels.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/conversations/visitor-identification-types.generated.d.ts +0 -60
- package/dist/server/api-client-core/apis/conversations/visitor-identification.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/conversations/visitor-identification.generated.js +0 -6
- package/dist/server/api-client-core/apis/conversations/visitor-identification.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/conversations-types.generated.d.ts +0 -908
- package/dist/server/api-client-core/apis/conversations.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/conversations.generated.js +0 -108
- package/dist/server/api-client-core/apis/conversations.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/app-uninstalls-types.generated.d.ts +0 -37
- package/dist/server/api-client-core/apis/crm/app-uninstalls.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/app-uninstalls.generated.js +0 -6
- package/dist/server/api-client-core/apis/crm/app-uninstalls.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/appointments-types.generated.d.ts +0 -989
- package/dist/server/api-client-core/apis/crm/appointments.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/appointments.generated.js +0 -118
- package/dist/server/api-client-core/apis/crm/appointments.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/associations-schema-types.generated.d.ts +0 -329
- package/dist/server/api-client-core/apis/crm/associations-schema.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/associations-schema.generated.js +0 -60
- package/dist/server/api-client-core/apis/crm/associations-schema.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/associations-types.generated.d.ts +0 -661
- package/dist/server/api-client-core/apis/crm/associations.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/associations.generated.js +0 -83
- package/dist/server/api-client-core/apis/crm/associations.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/calling-extensions-types.generated.d.ts +0 -466
- package/dist/server/api-client-core/apis/crm/calling-extensions.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/calling-extensions.generated.js +0 -42
- package/dist/server/api-client-core/apis/crm/calling-extensions.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/calls-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/calls.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/calls.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/calls.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/carts-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/carts.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/carts.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/carts.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/commerce-payments-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/commerce-payments.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/commerce-payments.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/commerce-payments.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/commerce-subscriptions-types.generated.d.ts +0 -847
- package/dist/server/api-client-core/apis/crm/commerce-subscriptions.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/commerce-subscriptions.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/commerce-subscriptions.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/communications-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/communications.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/communications.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/communications.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/companies-types.generated.d.ts +0 -884
- package/dist/server/api-client-core/apis/crm/companies.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/companies.generated.js +0 -67
- package/dist/server/api-client-core/apis/crm/companies.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/contacts-types.generated.d.ts +0 -899
- package/dist/server/api-client-core/apis/crm/contacts.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/contacts.generated.js +0 -70
- package/dist/server/api-client-core/apis/crm/contacts.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/contracts-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/contracts.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/contracts.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/contracts.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/courses-types.generated.d.ts +0 -853
- package/dist/server/api-client-core/apis/crm/courses.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/courses.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/courses.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/crm-owners-types.generated.d.ts +0 -140
- package/dist/server/api-client-core/apis/crm/crm-owners.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/crm-owners.generated.js +0 -20
- package/dist/server/api-client-core/apis/crm/crm-owners.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/custom-objects-types.generated.d.ts +0 -934
- package/dist/server/api-client-core/apis/crm/custom-objects.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/custom-objects.generated.js +0 -101
- package/dist/server/api-client-core/apis/crm/custom-objects.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/deal-splits-types.generated.d.ts +0 -196
- package/dist/server/api-client-core/apis/crm/deal-splits.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/deal-splits.generated.js +0 -9
- package/dist/server/api-client-core/apis/crm/deal-splits.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/deals-types.generated.d.ts +0 -872
- package/dist/server/api-client-core/apis/crm/deals.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/deals.generated.js +0 -67
- package/dist/server/api-client-core/apis/crm/deals.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/discounts-types.generated.d.ts +0 -846
- package/dist/server/api-client-core/apis/crm/discounts.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/discounts.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/discounts.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/emails-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/emails.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/emails.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/emails.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/exports-types.generated.d.ts +0 -281
- package/dist/server/api-client-core/apis/crm/exports.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/exports.generated.js +0 -12
- package/dist/server/api-client-core/apis/crm/exports.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/feedback-submissions-types.generated.d.ts +0 -616
- package/dist/server/api-client-core/apis/crm/feedback-submissions.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/feedback-submissions.generated.js +0 -55
- package/dist/server/api-client-core/apis/crm/feedback-submissions.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/fees-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/fees.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/fees.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/fees.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/goal-targets-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/goal-targets.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/goal-targets.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/goal-targets.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/imports-types.generated.d.ts +0 -371
- package/dist/server/api-client-core/apis/crm/imports.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/imports.generated.js +0 -30
- package/dist/server/api-client-core/apis/crm/imports.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/invoices-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/invoices.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/invoices.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/invoices.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/leads-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/leads.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/leads.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/leads.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/limits-tracking-types.generated.d.ts +0 -331
- package/dist/server/api-client-core/apis/crm/limits-tracking.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/limits-tracking.generated.js +0 -22
- package/dist/server/api-client-core/apis/crm/limits-tracking.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/line-items-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/line-items.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/line-items.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/line-items.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/listings-types.generated.d.ts +0 -853
- package/dist/server/api-client-core/apis/crm/listings.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/listings.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/listings.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/lists-types.generated.d.ts +0 -2265
- package/dist/server/api-client-core/apis/crm/lists.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/lists.generated.js +0 -105
- package/dist/server/api-client-core/apis/crm/lists.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/meetings-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/meetings.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/meetings.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/meetings.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/notes-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/notes.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/notes.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/notes.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/object-library-types.generated.d.ts +0 -60
- package/dist/server/api-client-core/apis/crm/object-library.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/object-library.generated.js +0 -9
- package/dist/server/api-client-core/apis/crm/object-library.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/objects-types.generated.d.ts +0 -712
- package/dist/server/api-client-core/apis/crm/objects.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/objects.generated.js +0 -76
- package/dist/server/api-client-core/apis/crm/objects.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/orders-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/orders.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/orders.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/orders.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/partner-clients-types.generated.d.ts +0 -725
- package/dist/server/api-client-core/apis/crm/partner-clients.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/partner-clients.generated.js +0 -71
- package/dist/server/api-client-core/apis/crm/partner-clients.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/partner-services-types.generated.d.ts +0 -725
- package/dist/server/api-client-core/apis/crm/partner-services.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/partner-services.generated.js +0 -71
- package/dist/server/api-client-core/apis/crm/partner-services.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/pipelines-types.generated.d.ts +0 -430
- package/dist/server/api-client-core/apis/crm/pipelines.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/pipelines.generated.js +0 -94
- package/dist/server/api-client-core/apis/crm/pipelines.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/postal-mail-types.generated.d.ts +0 -844
- package/dist/server/api-client-core/apis/crm/postal-mail.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/postal-mail.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/postal-mail.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/products-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/products.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/products.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/products.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/projects-types.generated.d.ts +0 -881
- package/dist/server/api-client-core/apis/crm/projects.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/projects.generated.js +0 -67
- package/dist/server/api-client-core/apis/crm/projects.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/properties-types.generated.d.ts +0 -603
- package/dist/server/api-client-core/apis/crm/properties.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/properties.generated.js +0 -86
- package/dist/server/api-client-core/apis/crm/properties.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/property-validations-types.generated.d.ts +0 -121
- package/dist/server/api-client-core/apis/crm/property-validations.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/property-validations.generated.js +0 -25
- package/dist/server/api-client-core/apis/crm/property-validations.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/public-app-crm-cards-types.generated.d.ts +0 -486
- package/dist/server/api-client-core/apis/crm/public-app-crm-cards.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/public-app-crm-cards.generated.js +0 -34
- package/dist/server/api-client-core/apis/crm/public-app-crm-cards.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/public-app-feature-flags-types.generated.d.ts +0 -247
- package/dist/server/api-client-core/apis/crm/public-app-feature-flags.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/public-app-feature-flags.generated.js +0 -69
- package/dist/server/api-client-core/apis/crm/public-app-feature-flags.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/quotes-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/quotes.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/quotes.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/quotes.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/schemas-types.generated.d.ts +0 -669
- package/dist/server/api-client-core/apis/crm/schemas.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/schemas.generated.js +0 -41
- package/dist/server/api-client-core/apis/crm/schemas.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/services-types.generated.d.ts +0 -853
- package/dist/server/api-client-core/apis/crm/services.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/services.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/services.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/tasks-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/tasks.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/tasks.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/tasks.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/taxes-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/taxes.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/taxes.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/taxes.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/tickets-types.generated.d.ts +0 -884
- package/dist/server/api-client-core/apis/crm/tickets.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/tickets.generated.js +0 -67
- package/dist/server/api-client-core/apis/crm/tickets.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/timeline-types.generated.d.ts +0 -187
- package/dist/server/api-client-core/apis/crm/timeline.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/timeline.generated.js +0 -12
- package/dist/server/api-client-core/apis/crm/timeline.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/transcriptions-types.generated.d.ts +0 -152
- package/dist/server/api-client-core/apis/crm/transcriptions.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/transcriptions.generated.js +0 -15
- package/dist/server/api-client-core/apis/crm/transcriptions.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/users-types.generated.d.ts +0 -850
- package/dist/server/api-client-core/apis/crm/users.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/users.generated.js +0 -66
- package/dist/server/api-client-core/apis/crm/users.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/crm/video-conferencing-extension-types.generated.d.ts +0 -72
- package/dist/server/api-client-core/apis/crm/video-conferencing-extension.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/crm/video-conferencing-extension.generated.js +0 -13
- package/dist/server/api-client-core/apis/crm/video-conferencing-extension.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/events/manage-event-definitions-types.generated.d.ts +0 -1005
- package/dist/server/api-client-core/apis/events/manage-event-definitions.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/events/manage-event-definitions.generated.js +0 -39
- package/dist/server/api-client-core/apis/events/manage-event-definitions.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/events/send-event-completions-types.generated.d.ts +0 -94
- package/dist/server/api-client-core/apis/events/send-event-completions.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/events/send-event-completions.generated.js +0 -9
- package/dist/server/api-client-core/apis/events/send-event-completions.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/events-types.generated.d.ts +0 -137
- package/dist/server/api-client-core/apis/events.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/events.generated.js +0 -23
- package/dist/server/api-client-core/apis/events.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/files-types.generated.d.ts +0 -791
- package/dist/server/api-client-core/apis/files.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/files.generated.js +0 -119
- package/dist/server/api-client-core/apis/files.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/marketing/campaigns-public-api-types.generated.d.ts +0 -989
- package/dist/server/api-client-core/apis/marketing/campaigns-public-api.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/marketing/campaigns-public-api.generated.js +0 -139
- package/dist/server/api-client-core/apis/marketing/campaigns-public-api.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/marketing/marketing-emails-types.generated.d.ts +0 -883
- package/dist/server/api-client-core/apis/marketing/marketing-emails.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/marketing/marketing-emails.generated.js +0 -108
- package/dist/server/api-client-core/apis/marketing/marketing-emails.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/marketing/marketing-events-types.generated.d.ts +0 -1788
- package/dist/server/api-client-core/apis/marketing/marketing-events.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/marketing/marketing-events.generated.js +0 -176
- package/dist/server/api-client-core/apis/marketing/marketing-events.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/marketing/single-send-types.generated.d.ts +0 -123
- package/dist/server/api-client-core/apis/marketing/single-send.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/marketing/single-send.generated.js +0 -6
- package/dist/server/api-client-core/apis/marketing/single-send.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/marketing/transactional-single-send-types.generated.d.ts +0 -257
- package/dist/server/api-client-core/apis/marketing/transactional-single-send.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/marketing/transactional-single-send.generated.js +0 -20
- package/dist/server/api-client-core/apis/marketing/transactional-single-send.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/meta/origins-types.generated.d.ts +0 -77
- package/dist/server/api-client-core/apis/meta/origins.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/meta/origins.generated.js +0 -15
- package/dist/server/api-client-core/apis/meta/origins.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/scheduler/meetings-types.generated.d.ts +0 -913
- package/dist/server/api-client-core/apis/scheduler/meetings.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/scheduler/meetings.generated.js +0 -34
- package/dist/server/api-client-core/apis/scheduler/meetings.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/settings/multicurrency-types.generated.d.ts +0 -404
- package/dist/server/api-client-core/apis/settings/multicurrency.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/settings/multicurrency.generated.js +0 -38
- package/dist/server/api-client-core/apis/settings/multicurrency.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/settings/tax-rates-types.generated.d.ts +0 -111
- package/dist/server/api-client-core/apis/settings/tax-rates.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/settings/tax-rates.generated.js +0 -13
- package/dist/server/api-client-core/apis/settings/tax-rates.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/settings/user-provisioning-types.generated.d.ts +0 -297
- package/dist/server/api-client-core/apis/settings/user-provisioning.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/settings/user-provisioning.generated.js +0 -31
- package/dist/server/api-client-core/apis/settings/user-provisioning.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/webhooks-journal-types.generated.d.ts +0 -643
- package/dist/server/api-client-core/apis/webhooks-journal.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/webhooks-journal.generated.js +0 -75
- package/dist/server/api-client-core/apis/webhooks-journal.generated.js.map +0 -1
- package/dist/server/api-client-core/apis/webhooks-types.generated.d.ts +0 -1016
- package/dist/server/api-client-core/apis/webhooks.generated.d.ts +0 -7
- package/dist/server/api-client-core/apis/webhooks.generated.js +0 -105
- package/dist/server/api-client-core/apis/webhooks.generated.js.map +0 -1
- package/dist/server/api-client-core/binary-data.d.ts +0 -33
- package/dist/server/api-client-core/binary-data.js +0 -29
- package/dist/server/api-client-core/binary-data.js.map +0 -1
- package/dist/server/api-client-core/client.d.ts +0 -14
- package/dist/server/api-client-core/client.js.map +0 -1
- package/dist/server/api-client-core/codegen-helpers/file-op-wrappers.js +0 -25
- package/dist/server/api-client-core/codegen-helpers/file-op-wrappers.js.map +0 -1
- package/dist/server/api-client-core/errors.d.ts +0 -27
- package/dist/server/api-client-core/errors.js +0 -33
- package/dist/server/api-client-core/errors.js.map +0 -1
- package/dist/server/api-client-core/op.d.ts +0 -37
- package/dist/server/api-client-core/op.js +0 -44
- package/dist/server/api-client-core/op.js.map +0 -1
- package/dist/server/api-client-core/pagination.d.ts +0 -60
- package/dist/server/api-client-core/pagination.js +0 -103
- package/dist/server/api-client-core/pagination.js.map +0 -1
- package/dist/server/api-client-core/plugins/fetch-transport.js +0 -72
- package/dist/server/api-client-core/plugins/fetch-transport.js.map +0 -1
- package/dist/server/constants.js +0 -46
- package/dist/server/constants.js.map +0 -1
- package/dist/server/deno/start.d.ts +0 -12
- package/dist/server/deno/start.js +0 -21
- package/dist/server/deno/start.js.map +0 -1
- package/dist/server/hono/hono-request-handler.js +0 -54
- package/dist/server/hono/hono-request-handler.js.map +0 -1
- package/dist/server/hono/hubspot-connect-routes/auth-callback.js +0 -125
- package/dist/server/hono/hubspot-connect-routes/auth-callback.js.map +0 -1
- package/dist/server/hono/hubspot-connect-routes/auth-init-session.js +0 -90
- package/dist/server/hono/hubspot-connect-routes/auth-init-session.js.map +0 -1
- package/dist/server/hono/hubspot-connect-routes/auth-logout.js +0 -97
- package/dist/server/hono/hubspot-connect-routes/auth-logout.js.map +0 -1
- package/dist/server/hono/hubspot-connect-routes/auth-refresh.js +0 -101
- package/dist/server/hono/hubspot-connect-routes/auth-refresh.js.map +0 -1
- package/dist/server/hono/hubspot-connect-routes/cimd-client-metadata-types.d.ts +0 -16
- package/dist/server/hono/hubspot-connect-routes/cimd-client-metadata-types.js +0 -13
- package/dist/server/hono/hubspot-connect-routes/cimd-client-metadata-types.js.map +0 -1
- package/dist/server/hono/hubspot-connect-routes/cimd-public-routes.js +0 -42
- package/dist/server/hono/hubspot-connect-routes/cimd-public-routes.js.map +0 -1
- package/dist/server/hono/hubspot-connect-routes/constants.js +0 -8
- package/dist/server/hono/hubspot-connect-routes/constants.js.map +0 -1
- package/dist/server/hono/hubspot-connect-routes/fetch-hubspot-client-metadata.js +0 -43
- package/dist/server/hono/hubspot-connect-routes/fetch-hubspot-client-metadata.js.map +0 -1
- package/dist/server/hono/hubspot-connect-routes/hubspot-connect-routes.js +0 -35
- package/dist/server/hono/hubspot-connect-routes/hubspot-connect-routes.js.map +0 -1
- package/dist/server/hono/hubspot-connect-routes/load-hubspot-connect-routes-env.js +0 -34
- package/dist/server/hono/hubspot-connect-routes/load-hubspot-connect-routes-env.js.map +0 -1
- package/dist/server/hono/hubspot-connect-routes/oauth-client.js +0 -104
- package/dist/server/hono/hubspot-connect-routes/oauth-client.js.map +0 -1
- package/dist/server/hono/hubspot-connect-routes/utils.js +0 -73
- package/dist/server/hono/hubspot-connect-routes/utils.js.map +0 -1
- package/dist/server/hono/index.js +0 -4
- package/dist/server/hono/types.d.ts +0 -28
- package/dist/server/hono/utils/cookie-utils.js +0 -29
- package/dist/server/hono/utils/cookie-utils.js.map +0 -1
- package/dist/server/import-app-keys.js +0 -42
- package/dist/server/import-app-keys.js.map +0 -1
- package/dist/server/lovable/create-app-function-start.d.ts +0 -26
- package/dist/server/lovable/create-app-function-start.js +0 -28
- package/dist/server/lovable/create-app-function-start.js.map +0 -1
- package/dist/server/lovable/hubspot-connect/index.d.ts +0 -15
- package/dist/server/lovable/hubspot-connect/index.js +0 -20
- package/dist/server/lovable/hubspot-connect/index.js.map +0 -1
- package/dist/server/lovable/hubspot-connect/run-hubspot-connect-lovable-server.js +0 -29
- package/dist/server/lovable/hubspot-connect/run-hubspot-connect-lovable-server.js.map +0 -1
- package/dist/server/proxy.js +0 -68
- package/dist/server/proxy.js.map +0 -1
- package/dist/server/sanitize-request.js +0 -41
- package/dist/server/sanitize-request.js.map +0 -1
- package/dist/server/secure-start-core.d.ts +0 -23
- package/dist/server/secure-start-core.js +0 -28
- package/dist/server/secure-start-core.js.map +0 -1
- package/dist/server/shared/constants.js +0 -17
- package/dist/server/shared/constants.js.map +0 -1
- package/dist/server/shared/encoding/base64.js +0 -45
- package/dist/server/shared/encoding/base64.js.map +0 -1
- package/dist/server/shared/encoding/sha256.d.ts +0 -10
- package/dist/server/shared/encoding/sha256.js +0 -15
- package/dist/server/shared/encoding/sha256.js.map +0 -1
- package/dist/server/shared/logger.d.ts +0 -15
- package/dist/server/shared/logger.js +0 -16
- package/dist/server/shared/logger.js.map +0 -1
- package/dist/server/utils/cookie-utils.js +0 -21
- package/dist/server/utils/cookie-utils.js.map +0 -1
- package/dist/server/utils/dpop-utils.d.ts +0 -67
- package/dist/server/utils/dpop-utils.js +0 -75
- package/dist/server/utils/dpop-utils.js.map +0 -1
- package/dist/server/utils/env-utils.js +0 -54
- package/dist/server/utils/env-utils.js.map +0 -1
- package/dist/server/utils/jwk-utils.d.ts +0 -16
- package/dist/server/utils/jwk-utils.js +0 -24
- package/dist/server/utils/jwk-utils.js.map +0 -1
- package/dist/server/utils/jwt-utils.d.ts +0 -39
- package/dist/server/utils/jwt-utils.js +0 -87
- package/dist/server/utils/jwt-utils.js.map +0 -1
- package/src/server/hono/hubspot-connect-routes/auth-callback.test.ts +0 -225
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sha256-B7y8GBFB.js","names":[],"sources":["../../src/shared/encoding/base64.ts","../../src/server/utils/jwk-utils.ts","../../src/server/utils/jwt-utils.ts","../../src/server/utils/dpop-utils.ts","../../src/shared/encoding/sha256.ts"],"sourcesContent":["/**\n * Base64url encoding and decoding helpers shared by the browser and\n * server halves of `@hubspot/app-connect-sdk`.\n *\n * Base64url (RFC 4648 §5) replaces `+`/`/` with `-`/`_` and drops `=`\n * padding. JWT, DPoP, and JWK thumbprints all use this variant.\n */\n\n/**\n * Encodes a binary buffer as a base64url string (RFC 4648 §5).\n */\nexport function base64url(input: ArrayBuffer | Uint8Array): string {\n const bytes = input instanceof Uint8Array ? input : new Uint8Array(input);\n let binary = '';\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n}\n\n/**\n * Decodes a base64url string into a `Uint8Array`. Tolerates missing\n * padding by re-adding it before delegating to `atob`.\n */\nexport function base64urlDecode(encoded: string): Uint8Array<ArrayBuffer> {\n const padLen = (4 - (encoded.length % 4)) % 4;\n const padded =\n encoded.replace(/-/g, '+').replace(/_/g, '/') + '='.repeat(padLen);\n const binary = atob(padded);\n const out = new Uint8Array(new ArrayBuffer(binary.length));\n for (let i = 0; i < binary.length; i++) {\n out[i] = binary.charCodeAt(i) ?? 0;\n }\n return out;\n}\n\n/**\n * Decodes a *standard* base64 string (with `+`/`/` and required `=`\n * padding) into an `ArrayBuffer`. Used for PKCS8-encoded private keys\n * stored in environment variables.\n */\nexport function base64StandardToArrayBuffer(b64: string): ArrayBuffer {\n const bin = atob(b64);\n const buf = new ArrayBuffer(bin.length);\n const view = new Uint8Array(buf);\n for (let i = 0; i < bin.length; i++) {\n view[i] = bin.charCodeAt(i) ?? 0;\n }\n return buf;\n}\n","import { base64url } from './base64-utils.ts';\n\nexport interface GetJwkThumbprintOptions {\n /** EC P-256 public JWK whose thumbprint to compute. */\n publicKeyJwk: JsonWebKey;\n}\n\n/**\n * Computes the RFC 7638 JWK thumbprint of an EC P-256 public JWK.\n * Per §3.2 the canonical form contains only `crv`, `kty`, `x`, `y`,\n * sorted lexicographically — no whitespace, no other members. The\n * SHA-256 of this canonical UTF-8 JSON, base64url-encoded, is the\n * stable identifier (`jkt`) DPoP uses to bind tokens to public keys.\n */\nexport async function getJwkThumbprint(\n options: GetJwkThumbprintOptions\n): Promise<string> {\n const { publicKeyJwk } = options;\n const canonical = JSON.stringify({\n crv: publicKeyJwk.crv,\n kty: publicKeyJwk.kty,\n x: publicKeyJwk.x,\n y: publicKeyJwk.y,\n });\n const digest = await crypto.subtle.digest(\n 'SHA-256',\n new TextEncoder().encode(canonical)\n );\n return base64url(new Uint8Array(digest));\n}\n","import { base64url, base64urlDecode } from './base64-utils.ts';\n\ninterface EncodeAndSignJwtOptions {\n header: Record<string, unknown>;\n payload: Record<string, unknown>;\n privateKey: CryptoKey;\n}\n\n/**\n * Low-level helper that encodes a JWS Compact Serialization JWT\n * (RFC 7519) and signs it with the supplied `privateKey` using\n * ES256 (P-256 + SHA-256). Returns the three-segment compact form.\n */\nexport async function encodeAndSignJwt(\n options: EncodeAndSignJwtOptions\n): Promise<string> {\n const { header, payload, privateKey } = options;\n\n const encodedHeader = base64url(\n new TextEncoder().encode(JSON.stringify(header))\n );\n const encodedPayload = base64url(\n new TextEncoder().encode(JSON.stringify(payload))\n );\n const signingInput = `${encodedHeader}.${encodedPayload}`;\n const signatureBuffer = await crypto.subtle.sign(\n { name: 'ECDSA', hash: 'SHA-256' },\n privateKey,\n new TextEncoder().encode(signingInput)\n );\n return `${signingInput}.${base64url(new Uint8Array(signatureBuffer))}`;\n}\n\nasync function importPublicKey(jwk: JsonWebKey): Promise<CryptoKey> {\n return crypto.subtle.importKey(\n 'jwk',\n jwk,\n { name: 'ECDSA', namedCurve: 'P-256' },\n false,\n ['verify']\n );\n}\n\ninterface DecodeAndVerifyJwtOptions {\n token: string;\n publicKeyJwk: JsonWebKey;\n}\n\n/**\n * Verifies the ES256 signature on `token` against `publicKeyJwk` and\n * returns the decoded payload. Does not check `exp` — use\n * {@link verifyJwt} when expiry enforcement is desired.\n *\n * @throws {Error} When the token isn't three segments, when the\n * signature fails verification, or when the payload isn't valid\n * JSON.\n */\nexport async function decodeAndVerifyJwt(\n options: DecodeAndVerifyJwtOptions\n): Promise<Record<string, unknown>> {\n const { token, publicKeyJwk } = options;\n const parts = token.split('.');\n if (parts.length !== 3) throw new Error('Invalid JWT format');\n const [encodedHeader, encodedPayload, encodedSignature] = parts as [\n string,\n string,\n string,\n ];\n const publicKey = await importPublicKey(publicKeyJwk);\n const valid = await crypto.subtle.verify(\n { name: 'ECDSA', hash: 'SHA-256' },\n publicKey,\n base64urlDecode(encodedSignature),\n new TextEncoder().encode(`${encodedHeader}.${encodedPayload}`)\n );\n if (!valid) throw new Error('JWT signature verification failed');\n return JSON.parse(\n new TextDecoder().decode(base64urlDecode(encodedPayload))\n ) as Record<string, unknown>;\n}\n\nexport interface VerifyJwtOptions {\n /** Compact-serialized JWT to verify. */\n token: string;\n /** Public key in JWK form. Caller is responsible for trusting it. */\n publicKeyJwk: JsonWebKey;\n}\n\n/**\n * Verifies signature and (if present) `exp` (RFC 7519 §4.1.4) on a\n * JWT and returns its payload.\n *\n * @throws {Error} When the signature fails or when `exp` has passed.\n */\nexport async function verifyJwt(\n options: VerifyJwtOptions\n): Promise<Record<string, unknown>> {\n const { token, publicKeyJwk } = options;\n const payload = await decodeAndVerifyJwt({ token, publicKeyJwk });\n const now = Math.floor(Date.now() / 1000);\n if (typeof payload['exp'] === 'number' && payload['exp'] < now) {\n throw new Error('JWT expired');\n }\n return payload;\n}\n\nexport interface SignJwtOptions {\n /** ES256 private key as a non-extractable WebCrypto key. */\n privateKey: CryptoKey;\n /**\n * Custom claims merged onto an `iat` claim (and `exp` when\n * `ttlSeconds` is supplied). Caller-provided keys override the\n * standard ones.\n */\n payload: Record<string, unknown>;\n /**\n * Lifetime of the token in seconds. When set, the JWT's `exp` claim\n * is computed as `iat + ttlSeconds`. When omitted, no `exp` is added\n * (the caller is responsible for one if needed).\n */\n ttlSeconds?: number;\n}\n\n/**\n * Signs a JWT (RFC 7519) with `alg=ES256, typ=JWT` and returns the\n * compact serialization. Always sets `iat` to the current second; the\n * caller controls every other claim via `payload`.\n */\nexport async function signJwt(options: SignJwtOptions): Promise<string> {\n const { privateKey, payload, ttlSeconds } = options;\n const now = Math.floor(Date.now() / 1000);\n const payloadWithStandardClaims =\n ttlSeconds !== undefined\n ? { iat: now, exp: now + ttlSeconds, ...payload }\n : { iat: now, ...payload };\n return encodeAndSignJwt({\n header: { alg: 'ES256', typ: 'JWT' },\n payload: payloadWithStandardClaims,\n privateKey,\n });\n}\n","import { type AppKeys } from '../types.ts';\nimport { base64urlDecode } from './base64-utils.ts';\nimport { getJwkThumbprint } from './jwk-utils.ts';\nimport { decodeAndVerifyJwt, encodeAndSignJwt } from './jwt-utils.ts';\n\n/**\n * Claims that go into a DPoP proof JWT (RFC 9449 §4.2). Extra\n * properties pass through to the encoder unchanged so callers can\n * include implementation-specific claims.\n */\nexport interface DpopClaims {\n /** HTTP method of the protected request, uppercase. */\n htm: string;\n /** Target URI of the protected request, fully-qualified. */\n htu: string;\n /** Unique proof identifier (RFC 9449 §4.2, recommended UUID). */\n jti: string;\n /** Issuance time, Unix epoch seconds. */\n iat: number;\n /**\n * Hash of the access token presented alongside this proof, if any\n * (RFC 9449 §4.2). Required for resource-server DPoP.\n */\n ath?: string;\n /**\n * App session ID hash. Custom HubSpot extension that lets the auth\n * server bind tokens to the browser session that minted them.\n */\n sid?: string;\n [key: string]: unknown;\n}\n\nfunction ecPublicJwkForDpopHeader(jwk: JsonWebKey): JsonWebKey {\n if (\n jwk.kty !== 'EC' ||\n jwk.crv !== 'P-256' ||\n typeof jwk.x !== 'string' ||\n typeof jwk.y !== 'string'\n ) {\n throw new Error('Expected P-256 EC public JWK');\n }\n return {\n kty: 'EC',\n crv: 'P-256',\n x: jwk.x,\n y: jwk.y,\n };\n}\n\nexport interface SignDpopProofOptions {\n /** App key material produced by `secureStart`. */\n appKeys: AppKeys;\n /** Claims to include in the DPoP proof. */\n claims: DpopClaims;\n}\n\n/**\n * Mints a DPoP proof JWT (RFC 9449) signed with the app's private\n * key. The header is set to `typ=dpop+jwt`, `alg=ES256`, and embeds\n * the public JWK so the receiver can verify the signature without\n * out-of-band key distribution.\n */\nexport async function signDpopProof(\n options: SignDpopProofOptions\n): Promise<string> {\n const { appKeys, claims } = options;\n const publicJwk = ecPublicJwkForDpopHeader(appKeys.appPublicKeyJwk);\n return encodeAndSignJwt({\n header: { alg: 'ES256', typ: 'dpop+jwt', jwk: publicJwk },\n payload: claims,\n privateKey: appKeys.appPrivateKey,\n });\n}\n\n/**\n * Result of a successful {@link verifyDpopProof} call.\n */\nexport interface VerifiedDpopProof {\n /** Public JWK extracted from the proof's header. */\n publicKeyJwk: JsonWebKey;\n /** RFC 7638 JWK thumbprint of `publicKeyJwk`. */\n jkt: string;\n /** Decoded claims from the proof's payload. */\n claims: DpopClaims;\n}\n\nexport interface VerifyDpopProofOptions {\n /** The compact-serialized DPoP proof. */\n proof: string;\n /** Expected HTTP method (RFC 9449 `htm` claim). */\n htm: string;\n /** Expected request URI (RFC 9449 `htu` claim). */\n htu: string;\n /** Expected access-token hash (RFC 9449 `ath` claim). */\n ath?: string;\n /** Expected app-session-ID hash (`sid` claim). */\n sid?: string;\n}\n\ninterface DpopProofHeader {\n typ?: string;\n alg?: string;\n jwk?: JsonWebKey;\n}\n\n/**\n * Verifies a DPoP proof JWT and returns the embedded public JWK,\n * its thumbprint, and the decoded claims.\n *\n * Enforces RFC 9449's required checks:\n *\n * - `typ=dpop+jwt`, `alg=ES256`, and a JWK in the header.\n * - Signature is valid against the embedded JWK.\n * - `htm`, `htu`, and (when supplied) `ath`/`sid` match.\n * - `iat` is within ±5 minutes of \"now\".\n *\n * @throws {Error} If any of the above checks fail.\n */\nexport async function verifyDpopProof(\n options: VerifyDpopProofOptions\n): Promise<VerifiedDpopProof> {\n const { proof, htm, htu, ath, sid } = options;\n const parts = proof.split('.');\n if (parts.length !== 3) throw new Error('Invalid DPoP proof format');\n\n const encodedHeader = parts[0];\n if (!encodedHeader) throw new Error('Missing DPoP header');\n\n const header = JSON.parse(\n new TextDecoder().decode(base64urlDecode(encodedHeader))\n ) as DpopProofHeader;\n\n if (header.typ !== 'dpop+jwt') throw new Error('Invalid DPoP typ header');\n if (header.alg !== 'ES256') throw new Error('Unsupported DPoP algorithm');\n const publicKeyJwk = header.jwk;\n if (!publicKeyJwk) throw new Error('Missing jwk in DPoP header');\n\n const payload = await decodeAndVerifyJwt({ token: proof, publicKeyJwk });\n const claims = payload as unknown as DpopClaims;\n\n if (claims.htm !== htm) {\n throw new Error(`DPoP htm mismatch: expected ${htm}, got ${claims.htm}`);\n }\n if (claims.htu !== htu) {\n throw new Error(`DPoP htu mismatch: expected ${htu}, got ${claims.htu}`);\n }\n if (ath !== undefined && claims.ath !== ath) {\n throw new Error('DPoP ath mismatch');\n }\n if (sid !== undefined && claims.sid !== sid) {\n throw new Error('DPoP sid mismatch');\n }\n\n const now = Math.floor(Date.now() / 1000);\n if (Math.abs(now - claims.iat) > 300) {\n throw new Error('DPoP proof expired or too far in future');\n }\n\n const jkt = await getJwkThumbprint({ publicKeyJwk });\n return { publicKeyJwk, jkt, claims };\n}\n","import { base64url } from './base64.ts';\n\n/**\n * Hashes a UTF-8 string with SHA-256 and encodes the digest as\n * base64url. Used to compute DPoP `ath`/`sid` claims, JWK thumbprints\n * (RFC 7638), and PKCE code challenges.\n */\nexport async function sha256base64url(input: string): Promise<string> {\n const digest = await crypto.subtle.digest(\n 'SHA-256',\n new TextEncoder().encode(input)\n );\n return base64url(new Uint8Array(digest));\n}\n"],"mappings":"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"}
|
|
@@ -131,5 +131,5 @@ interface CreateHubSpotClientOptions {
|
|
|
131
131
|
plugins: Plugin[];
|
|
132
132
|
}
|
|
133
133
|
//#endregion
|
|
134
|
-
export {
|
|
135
|
-
//# sourceMappingURL=types.d.ts.map
|
|
134
|
+
export { Middleware as a, Operation as c, Plugin as d, PluginAPI as f, SyntheticStreamingOperation as h, HubSpotClient as i, PaginatedItem as l, SyntheticOperationContext as m, CreateHubSpotClientOptions as n, MiddlewareContext as o, SyntheticOperation as p, HubSpotApiResponse as r, Next as s, ApiResponse as t, PaginatedResponse as u };
|
|
135
|
+
//# sourceMappingURL=types-DEOUH4wE.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/app-connect-sdk",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.4",
|
|
4
4
|
"description": "HubSpot App Connect SDK (alpha release). Documentation and integration guidance forthcoming.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -23,16 +23,11 @@
|
|
|
23
23
|
},
|
|
24
24
|
"prettier": "@private/prettier-config",
|
|
25
25
|
"peerDependencies": {
|
|
26
|
-
"hono": "^4.0.0",
|
|
27
26
|
"react": "^18.0.0 || ^19.0.0"
|
|
28
27
|
},
|
|
29
|
-
"peerDependenciesMeta": {
|
|
30
|
-
"hono": {
|
|
31
|
-
"optional": true
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
28
|
"dependencies": {
|
|
35
|
-
"@base-ui/react": "^1.4.1"
|
|
29
|
+
"@base-ui/react": "^1.4.1",
|
|
30
|
+
"hono": "^4.7.11"
|
|
36
31
|
},
|
|
37
32
|
"engines": {
|
|
38
33
|
"node": ">=24.0.0"
|
|
@@ -44,14 +39,13 @@
|
|
|
44
39
|
"@vanilla-extract/css": "^1.20.1",
|
|
45
40
|
"@vanilla-extract/rollup-plugin": "^1.5.3",
|
|
46
41
|
"eslint": "10.0.3",
|
|
47
|
-
"hono": "^4.7.11",
|
|
48
42
|
"prettier": "3.8.1",
|
|
49
43
|
"react": "^19.1.0",
|
|
50
44
|
"tsdown": "0.22.0-beta.3",
|
|
51
45
|
"typescript": "6.0.3",
|
|
52
46
|
"vitest": "4.0.18",
|
|
53
|
-
"@private/tsconfig": "0.1.0",
|
|
54
47
|
"@private/eslint-config": "0.1.0",
|
|
48
|
+
"@private/tsconfig": "0.1.0",
|
|
55
49
|
"@private/prettier-config": "0.1.0"
|
|
56
50
|
},
|
|
57
51
|
"scripts": {
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { HUBSPOT_FRONTEND_CALLBACK_PATH } from '../../shared/constants.ts';
|
|
4
|
+
import { noopLogger } from '../../shared/logger.ts';
|
|
5
|
+
import { EXPIRES_AT_KEY } from './constants.ts';
|
|
6
|
+
import { initAppConnect } from './init.ts';
|
|
7
|
+
import type {
|
|
8
|
+
AppConnectContext,
|
|
9
|
+
AppConnectInternalState,
|
|
10
|
+
SessionStorage,
|
|
11
|
+
} from './types.ts';
|
|
12
|
+
import { createStore } from './utils/store-utils.ts';
|
|
13
|
+
|
|
14
|
+
const HUBSPOT_CONNECT_BASE_URL =
|
|
15
|
+
'https://edge.example.com/functions/v1/hubspot-connect';
|
|
16
|
+
|
|
17
|
+
function createInMemorySessionStorage(): SessionStorage {
|
|
18
|
+
const map = new Map<string, string>();
|
|
19
|
+
return {
|
|
20
|
+
getItem: (key) => map.get(key) ?? null,
|
|
21
|
+
setItem: (key, value) => {
|
|
22
|
+
map.set(key, value);
|
|
23
|
+
},
|
|
24
|
+
removeItem: (key) => {
|
|
25
|
+
map.delete(key);
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function createTestContext(): AppConnectContext {
|
|
31
|
+
const initialState: AppConnectInternalState = {
|
|
32
|
+
isInitComplete: false,
|
|
33
|
+
isConnectInFlight: false,
|
|
34
|
+
isSessionConnected: false,
|
|
35
|
+
isDisconnectInFlight: false,
|
|
36
|
+
error: null,
|
|
37
|
+
expiresAt: null,
|
|
38
|
+
};
|
|
39
|
+
return {
|
|
40
|
+
config: { hubSpotConnectBaseUrl: HUBSPOT_CONNECT_BASE_URL },
|
|
41
|
+
logger: noopLogger,
|
|
42
|
+
sessionStorage: createInMemorySessionStorage(),
|
|
43
|
+
store: createStore<AppConnectInternalState>(initialState),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface FakeWindowOptions {
|
|
48
|
+
href: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
interface FakeWindow {
|
|
52
|
+
history: { calls: Array<[unknown, string, string]> };
|
|
53
|
+
windowProxy: {
|
|
54
|
+
location: Pick<Location, 'pathname' | 'search' | 'origin'>;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function installFakeWindow(options: FakeWindowOptions): FakeWindow {
|
|
59
|
+
const url = new URL(options.href);
|
|
60
|
+
const calls: Array<[unknown, string, string]> = [];
|
|
61
|
+
const fakeWindow = {
|
|
62
|
+
location: {
|
|
63
|
+
pathname: url.pathname,
|
|
64
|
+
search: url.search,
|
|
65
|
+
origin: url.origin,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
const fakeHistory = {
|
|
69
|
+
replaceState: (state: unknown, title: string, newUrl: string) => {
|
|
70
|
+
calls.push([state, title, newUrl]);
|
|
71
|
+
const replaced = new URL(newUrl, url.origin);
|
|
72
|
+
fakeWindow.location.pathname = replaced.pathname;
|
|
73
|
+
fakeWindow.location.search = replaced.search;
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
vi.stubGlobal('window', fakeWindow);
|
|
77
|
+
vi.stubGlobal('history', fakeHistory);
|
|
78
|
+
return { history: { calls }, windowProxy: fakeWindow };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
describe('initAppConnect', () => {
|
|
82
|
+
beforeEach(() => {
|
|
83
|
+
vi.useFakeTimers();
|
|
84
|
+
vi.setSystemTime(new Date(1_700_000_000_000));
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
afterEach(() => {
|
|
88
|
+
vi.unstubAllGlobals();
|
|
89
|
+
vi.restoreAllMocks();
|
|
90
|
+
vi.useRealTimers();
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('is a no-op on a normal page (no callback path, no expires_at param)', async () => {
|
|
94
|
+
installFakeWindow({ href: 'https://app.example.com/dashboard' });
|
|
95
|
+
const fetchSpy = vi.spyOn(globalThis, 'fetch');
|
|
96
|
+
const context = createTestContext();
|
|
97
|
+
|
|
98
|
+
await initAppConnect(context);
|
|
99
|
+
|
|
100
|
+
expect(fetchSpy).not.toHaveBeenCalled();
|
|
101
|
+
expect(context.store.getSnapshot().expiresAt).toBeNull();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('POSTs to /auth/complete on the OAuth callback path and persists expires_at + return_path', async () => {
|
|
105
|
+
const expiresAt = Date.now() + 1800 * 1000;
|
|
106
|
+
installFakeWindow({
|
|
107
|
+
href: `https://app.example.com${HUBSPOT_FRONTEND_CALLBACK_PATH}?code=auth-code&state=auth-state`,
|
|
108
|
+
});
|
|
109
|
+
const fetchSpy = vi
|
|
110
|
+
.spyOn(globalThis, 'fetch')
|
|
111
|
+
.mockResolvedValue(
|
|
112
|
+
new Response(
|
|
113
|
+
JSON.stringify({ expires_at: expiresAt, return_path: '/dashboard' }),
|
|
114
|
+
{ status: 200 }
|
|
115
|
+
)
|
|
116
|
+
);
|
|
117
|
+
const context = createTestContext();
|
|
118
|
+
|
|
119
|
+
await initAppConnect(context);
|
|
120
|
+
|
|
121
|
+
expect(fetchSpy).toHaveBeenCalledTimes(1);
|
|
122
|
+
const [calledUrl, calledInit] = fetchSpy.mock.calls[0]!;
|
|
123
|
+
const url = new URL(calledUrl as string);
|
|
124
|
+
expect(url.origin + url.pathname).toBe(
|
|
125
|
+
`${HUBSPOT_CONNECT_BASE_URL}/auth/complete`
|
|
126
|
+
);
|
|
127
|
+
expect(url.searchParams.get('code')).toBe('auth-code');
|
|
128
|
+
expect(url.searchParams.get('state')).toBe('auth-state');
|
|
129
|
+
expect((calledInit as RequestInit).method).toBe('POST');
|
|
130
|
+
expect((calledInit as RequestInit).credentials).toBe('include');
|
|
131
|
+
|
|
132
|
+
expect(context.store.getSnapshot().expiresAt).toBe(expiresAt);
|
|
133
|
+
expect(context.sessionStorage.getItem(EXPIRES_AT_KEY)).toBe(
|
|
134
|
+
String(expiresAt)
|
|
135
|
+
);
|
|
136
|
+
expect(window.location.pathname).toBe('/dashboard');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('throws and clears session storage when /auth/complete returns a non-OK response', async () => {
|
|
140
|
+
installFakeWindow({
|
|
141
|
+
href: `https://app.example.com${HUBSPOT_FRONTEND_CALLBACK_PATH}?code=auth-code&state=bad-state`,
|
|
142
|
+
});
|
|
143
|
+
vi.spyOn(globalThis, 'fetch').mockResolvedValue(
|
|
144
|
+
new Response('{"error":"State mismatch"}', {
|
|
145
|
+
status: 403,
|
|
146
|
+
statusText: 'Forbidden',
|
|
147
|
+
})
|
|
148
|
+
);
|
|
149
|
+
const context = createTestContext();
|
|
150
|
+
context.sessionStorage.setItem(EXPIRES_AT_KEY, '999');
|
|
151
|
+
|
|
152
|
+
await expect(initAppConnect(context)).rejects.toThrow(/Failed to complete/);
|
|
153
|
+
expect(context.sessionStorage.getItem(EXPIRES_AT_KEY)).toBeNull();
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('skips the callback step on the callback path when code or state are missing', async () => {
|
|
157
|
+
installFakeWindow({
|
|
158
|
+
href: `https://app.example.com${HUBSPOT_FRONTEND_CALLBACK_PATH}`,
|
|
159
|
+
});
|
|
160
|
+
const fetchSpy = vi.spyOn(globalThis, 'fetch');
|
|
161
|
+
const context = createTestContext();
|
|
162
|
+
|
|
163
|
+
await initAppConnect(context);
|
|
164
|
+
|
|
165
|
+
expect(fetchSpy).not.toHaveBeenCalled();
|
|
166
|
+
});
|
|
167
|
+
});
|
|
@@ -1,35 +1,86 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AUTH_COMPLETE_CODE_PARAM,
|
|
3
|
+
AUTH_COMPLETE_STATE_PARAM,
|
|
4
|
+
HUBSPOT_FRONTEND_CALLBACK_PATH,
|
|
5
|
+
} from '../../shared/constants.ts';
|
|
6
|
+
import type { AuthCompleteResponse } from '../../shared/wire-types.ts';
|
|
7
|
+
import { EXPIRES_AT_KEY } from './constants.ts';
|
|
2
8
|
import type { AppConnectContext } from './types.ts';
|
|
9
|
+
import { clearSessionStorage } from './utils/session-utils.ts';
|
|
3
10
|
|
|
4
11
|
/**
|
|
5
|
-
*
|
|
6
|
-
* the redirect URL, persists it to the controller, and strips it from
|
|
7
|
-
* the address bar so it's not logged or bookmarked.
|
|
12
|
+
* On `controller.start()`:
|
|
8
13
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
14
|
+
* 1. If the browser has been redirected back to the SDK's frontend
|
|
15
|
+
* OAuth callback path (`HUBSPOT_FRONTEND_CALLBACK_PATH`) with
|
|
16
|
+
* `?code` + `?state`, POST those values to the SDK's
|
|
17
|
+
* `auth/complete` endpoint to finish the token exchange. The
|
|
18
|
+
* server sets the durable session cookies on the response (in the
|
|
19
|
+
* same `(frontend, edge)` CHIPS partition the SDK reads them from
|
|
20
|
+
* on subsequent API fetches) and returns `{ expires_at,
|
|
21
|
+
* return_path }`. Replace the URL with `${return_path}?
|
|
22
|
+
* ${EXPIRES_AT_URL_PARAM}=${expires_at}` so the rest of init
|
|
23
|
+
* runs against the page the user actually started the connect
|
|
24
|
+
* flow from.
|
|
25
|
+
* 2. Pick up `?__hs_expires_at` from `window.location` (placed there
|
|
26
|
+
* by step 1, or by an in-progress refresh hop), persist it to the
|
|
27
|
+
* controller's store + sessionStorage, and strip it from the
|
|
28
|
+
* address bar so it isn't logged or bookmarked.
|
|
29
|
+
*
|
|
30
|
+
* A no-op when neither set of parameters is present (every page
|
|
31
|
+
* load other than the OAuth return trip).
|
|
12
32
|
*/
|
|
13
33
|
export async function initAppConnect(
|
|
14
34
|
context: AppConnectContext
|
|
15
35
|
): Promise<void> {
|
|
36
|
+
await consumeOAuthCallback(context);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function consumeOAuthCallback(context: AppConnectContext): Promise<void> {
|
|
40
|
+
if (window.location.pathname !== HUBSPOT_FRONTEND_CALLBACK_PATH) return;
|
|
41
|
+
|
|
16
42
|
const params = new URLSearchParams(window.location.search);
|
|
17
|
-
const
|
|
18
|
-
|
|
43
|
+
const code = params.get(AUTH_COMPLETE_CODE_PARAM);
|
|
44
|
+
const state = params.get(AUTH_COMPLETE_STATE_PARAM);
|
|
45
|
+
if (!code || !state) return;
|
|
46
|
+
|
|
47
|
+
const completeUrl = new URL(
|
|
48
|
+
`${context.config.hubSpotConnectBaseUrl}/auth/complete`,
|
|
49
|
+
window.location.origin
|
|
50
|
+
);
|
|
51
|
+
completeUrl.searchParams.set(AUTH_COMPLETE_CODE_PARAM, code);
|
|
52
|
+
completeUrl.searchParams.set(AUTH_COMPLETE_STATE_PARAM, state);
|
|
53
|
+
|
|
54
|
+
let response: Response;
|
|
55
|
+
try {
|
|
56
|
+
response = await fetch(completeUrl.toString(), {
|
|
57
|
+
method: 'POST',
|
|
58
|
+
credentials: 'include',
|
|
59
|
+
});
|
|
60
|
+
} catch (err) {
|
|
61
|
+
clearSessionStorage(context);
|
|
62
|
+
throw new Error(
|
|
63
|
+
`Failed to complete HubSpot OAuth: ${err instanceof Error ? err.message : String(err)}`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
19
66
|
|
|
20
|
-
|
|
21
|
-
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
clearSessionStorage(context);
|
|
69
|
+
throw new Error(
|
|
70
|
+
`Failed to complete HubSpot OAuth: ${response.status} ${response.statusText}`
|
|
71
|
+
);
|
|
72
|
+
}
|
|
22
73
|
|
|
23
|
-
|
|
24
|
-
|
|
74
|
+
const body = (await response.json()) as AuthCompleteResponse;
|
|
75
|
+
|
|
76
|
+
const { expires_at: expiresAt, return_path: returnPath } = body;
|
|
77
|
+
context.store.setState({ expiresAt });
|
|
78
|
+
context.sessionStorage.setItem(EXPIRES_AT_KEY, String(expiresAt));
|
|
79
|
+
|
|
80
|
+
const targetUrl = new URL(returnPath, window.location.origin);
|
|
25
81
|
history.replaceState(
|
|
26
82
|
null,
|
|
27
83
|
'',
|
|
28
|
-
|
|
29
|
-
? `${window.location.pathname}?${cleanSearch}`
|
|
30
|
-
: window.location.pathname
|
|
84
|
+
`${targetUrl.pathname}${targetUrl.search}${targetUrl.hash}`
|
|
31
85
|
);
|
|
32
|
-
|
|
33
|
-
context.store.setState({ expiresAt });
|
|
34
|
-
context.sessionStorage.setItem(EXPIRES_AT_KEY, String(expiresAt));
|
|
35
86
|
}
|
|
@@ -37,6 +37,8 @@ interface AppConnectHeaderProps {
|
|
|
37
37
|
|
|
38
38
|
export function AppConnectHeader({ title }: AppConnectHeaderProps) {
|
|
39
39
|
const { status } = useHubSpotAppConnect();
|
|
40
|
+
const connectButton =
|
|
41
|
+
status === 'initializing' ? null : <ConnectButton variant="secondary" />;
|
|
40
42
|
return (
|
|
41
43
|
<header className={styles.header}>
|
|
42
44
|
<div className={styles.titleRow}>
|
|
@@ -48,11 +50,7 @@ export function AppConnectHeader({ title }: AppConnectHeaderProps) {
|
|
|
48
50
|
{status === 'connected' ? <ViewingHubSpotContextRow /> : null}
|
|
49
51
|
</div>
|
|
50
52
|
</div>
|
|
51
|
-
{status === 'connected' ?
|
|
52
|
-
<UserMenu />
|
|
53
|
-
) : (
|
|
54
|
-
<ConnectButton variant="secondary" />
|
|
55
|
-
)}
|
|
53
|
+
{status === 'connected' ? <UserMenu /> : connectButton}
|
|
56
54
|
</header>
|
|
57
55
|
);
|
|
58
56
|
}
|
|
@@ -20,7 +20,8 @@ export function ConnectButton({
|
|
|
20
20
|
className,
|
|
21
21
|
}: ConnectButtonProps) {
|
|
22
22
|
const { status, connectToHubSpot } = useHubSpotAppConnect();
|
|
23
|
-
|
|
23
|
+
console.log('status', status);
|
|
24
|
+
const isConnecting = status === 'connecting' || status === 'initializing';
|
|
24
25
|
const composedClassName = [root, className].filter(Boolean).join(' ');
|
|
25
26
|
const labelClassName = isConnecting ? `${label} ${labelMuted}` : label;
|
|
26
27
|
return (
|
|
@@ -101,11 +101,15 @@ export function fetchTransportPlugin(
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
const response = await fetch(url, init);
|
|
104
|
+
const responseHeaders: Record<string, string> = Object.create(null);
|
|
105
|
+
response.headers.forEach((value, key) => {
|
|
106
|
+
responseHeaders[key] = value;
|
|
107
|
+
});
|
|
104
108
|
|
|
105
109
|
return {
|
|
106
110
|
status: response.status,
|
|
107
111
|
statusText: response.statusText,
|
|
108
|
-
headers:
|
|
112
|
+
headers: responseHeaders,
|
|
109
113
|
// 204 No Content responses have no body to parse
|
|
110
114
|
bodyJson: response.status === 204 ? undefined : await response.json(),
|
|
111
115
|
};
|
package/src/server/constants.ts
CHANGED
|
@@ -12,6 +12,25 @@ export const HUBSPOT_ACCESS_TOKEN_COOKIE_NAME = '__Host-hs_access_token';
|
|
|
12
12
|
*/
|
|
13
13
|
export const HUBSPOT_APP_SID_COOKIE_NAME = '__Host-hs_app_sid';
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Cookie pinning the browser-facing app origin (e.g.
|
|
17
|
+
* `https://app.example.com`) for the lifetime of an app session.
|
|
18
|
+
* Set by `auth/init-session` from the request's `Origin` header and
|
|
19
|
+
* read by:
|
|
20
|
+
*
|
|
21
|
+
* - The CORS middleware to emit a credentialed
|
|
22
|
+
* `Access-Control-Allow-Origin` value (`*` is forbidden when
|
|
23
|
+
* `Access-Control-Allow-Credentials: true`).
|
|
24
|
+
* - `auth/complete` to rebuild the OAuth `redirect_uri` it sent to
|
|
25
|
+
* HubSpot during `init-session` (the token endpoint validates that
|
|
26
|
+
* the two values match).
|
|
27
|
+
*
|
|
28
|
+
* `__Host-` prefixed (Path=/, Secure, no Domain), so the same
|
|
29
|
+
* function host can serve both `hubspot-connect` and `api` routes
|
|
30
|
+
* and read the cookie from either.
|
|
31
|
+
*/
|
|
32
|
+
export const HUBSPOT_APP_ORIGIN_COOKIE_NAME = '__Host-hs_app_origin';
|
|
33
|
+
|
|
15
34
|
/**
|
|
16
35
|
* Prefix used for refresh-token cookies. Each session gets its own
|
|
17
36
|
* cookie name (`hs_refresh_<sidHash>`) so multiple devices/tabs can
|
|
@@ -22,6 +41,7 @@ export const HUBSPOT_REFRESH_COOKIE_PREFIX = 'hs_refresh_';
|
|
|
22
41
|
const PROTECTED_COOKIE_NAMES = new Set([
|
|
23
42
|
HUBSPOT_ACCESS_TOKEN_COOKIE_NAME,
|
|
24
43
|
HUBSPOT_APP_SID_COOKIE_NAME,
|
|
44
|
+
HUBSPOT_APP_ORIGIN_COOKIE_NAME,
|
|
25
45
|
]);
|
|
26
46
|
|
|
27
47
|
/**
|
|
@@ -40,14 +60,19 @@ export function isProtectedCookieName(cookieName: string): boolean {
|
|
|
40
60
|
|
|
41
61
|
/**
|
|
42
62
|
* Cookie carrying the PKCE code verifier between `init-session` and
|
|
43
|
-
* `
|
|
44
|
-
*
|
|
63
|
+
* `auth/complete`. Set with `SameSite=None; Secure; Partitioned` so the
|
|
64
|
+
* frontend's credentialed cross-site `POST /auth/complete` (made from
|
|
65
|
+
* the OAuth callback page on the app origin to the SDK's edge function
|
|
66
|
+
* origin) carries it through. `Lax` would silently drop it on that
|
|
67
|
+
* fetch, breaking every successful HubSpot redirect.
|
|
45
68
|
*/
|
|
46
69
|
export const TEMP_COOKIE_PKCE_VERIFIER = '__hs_pkce_verifier';
|
|
47
70
|
|
|
48
71
|
/**
|
|
49
72
|
* Cookie carrying the OAuth `state` value between `init-session` and
|
|
50
|
-
* `
|
|
51
|
-
* primary CSRF defense.
|
|
73
|
+
* `auth/complete`. Compared against the `state` query parameter as the
|
|
74
|
+
* primary CSRF defense. Same `SameSite=None; Secure; Partitioned`
|
|
75
|
+
* attributes as `TEMP_COOKIE_PKCE_VERIFIER` for the same cross-site
|
|
76
|
+
* `POST /auth/complete` reason.
|
|
52
77
|
*/
|
|
53
78
|
export const TEMP_COOKIE_OAUTH_STATE = '__hs_oauth_state';
|
|
@@ -12,6 +12,7 @@ import { sanitizeRequest } from '../sanitize-request.ts';
|
|
|
12
12
|
import type { AppKeys, UserCredentials } from '../types.ts';
|
|
13
13
|
import { parseCookies } from '../utils/cookie-utils.ts';
|
|
14
14
|
import type { AppConnectHonoBindings, AppConnectHonoEnv } from './types.ts';
|
|
15
|
+
import { corsMiddleware } from './utils/cors-middleware.ts';
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Web-standard fetch handler signature returned by
|
|
@@ -62,6 +63,29 @@ export function createAppConnectRequestHandler(
|
|
|
62
63
|
): AppConnectFetchHandler {
|
|
63
64
|
const { registerRoutes, appKeys, logger = noopLogger } = options;
|
|
64
65
|
const app = new Hono<AppConnectHonoEnv>();
|
|
66
|
+
// Credentialed CORS first: preflights short-circuit with 204
|
|
67
|
+
// before the auth check runs, and 401 responses still carry
|
|
68
|
+
// `Access-Control-Allow-*` headers (the browser drops responses
|
|
69
|
+
// without them on credentialed cross-site fetches).
|
|
70
|
+
app.use('*', corsMiddleware());
|
|
71
|
+
|
|
72
|
+
// Auth gate: every non-OPTIONS request must arrive with the
|
|
73
|
+
// SDK-managed access-token + session-id cookies. The CORS
|
|
74
|
+
// middleware above short-circuits OPTIONS, so this only runs on
|
|
75
|
+
// real requests; missing cookies now surface as a normal 401 with
|
|
76
|
+
// CORS headers attached on the way back out (the previous
|
|
77
|
+
// implementation threw on a missing `Cookie` header before any
|
|
78
|
+
// middleware ran, which broke browser preflights).
|
|
79
|
+
app.use('*', async (c, next) => {
|
|
80
|
+
const { authenticated } = c.env.hubSpot;
|
|
81
|
+
if (!authenticated) {
|
|
82
|
+
return c.json({ error: 'Unauthorized' }, 401);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
await next();
|
|
86
|
+
return;
|
|
87
|
+
});
|
|
88
|
+
|
|
65
89
|
registerRoutes(app);
|
|
66
90
|
|
|
67
91
|
return (request: Request) => {
|
|
@@ -72,33 +96,36 @@ export function createAppConnectRequestHandler(
|
|
|
72
96
|
const cookies = parseCookies(cookie);
|
|
73
97
|
const accessToken = cookies[HUBSPOT_ACCESS_TOKEN_COOKIE_NAME];
|
|
74
98
|
const sessionId = cookies[HUBSPOT_APP_SID_COOKIE_NAME];
|
|
75
|
-
|
|
76
|
-
// Return 401 Unauthorized
|
|
77
|
-
return new Response(null, {
|
|
78
|
-
status: 401,
|
|
79
|
-
statusText: 'Unauthorized',
|
|
80
|
-
headers: {
|
|
81
|
-
'Content-Type': 'application/json',
|
|
82
|
-
},
|
|
83
|
-
});
|
|
84
|
-
}
|
|
99
|
+
|
|
85
100
|
const userCredentials: UserCredentials = { accessToken, sessionId };
|
|
86
101
|
|
|
87
|
-
const
|
|
102
|
+
const proxy = createHubSpotProxy({
|
|
88
103
|
userCredentials,
|
|
89
104
|
appKeys,
|
|
90
105
|
logger,
|
|
91
106
|
});
|
|
92
107
|
|
|
93
|
-
const
|
|
94
|
-
plugins: [
|
|
108
|
+
const client = createHubSpotClient({
|
|
109
|
+
plugins: [
|
|
110
|
+
fetchTransportPlugin({
|
|
111
|
+
getAccessToken: () => {
|
|
112
|
+
if (!accessToken) {
|
|
113
|
+
throw new Error('Missing access token');
|
|
114
|
+
}
|
|
115
|
+
return accessToken;
|
|
116
|
+
},
|
|
117
|
+
}),
|
|
118
|
+
],
|
|
95
119
|
});
|
|
96
120
|
|
|
97
121
|
const sanitizedRequest = sanitizeRequest(request);
|
|
98
122
|
|
|
99
123
|
const honoBindings: AppConnectHonoBindings = {
|
|
100
|
-
|
|
101
|
-
|
|
124
|
+
hubSpot: {
|
|
125
|
+
proxy,
|
|
126
|
+
client,
|
|
127
|
+
authenticated: proxy.authenticated,
|
|
128
|
+
},
|
|
102
129
|
};
|
|
103
130
|
|
|
104
131
|
return app.fetch(sanitizedRequest, honoBindings);
|