@omega.js/backend 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/LICENSE +98 -0
- package/README.md +1053 -0
- package/bin/omega +2 -0
- package/bin/omega-backend +2 -0
- package/bin/omg +2 -0
- package/cli.js +3 -0
- package/dist/cli/command-table.js +268 -0
- package/dist/cli/commands/auth.js +259 -0
- package/dist/cli/commands/base-command.js +451 -0
- package/dist/cli/commands/build.js +27 -0
- package/dist/cli/commands/clean.js +13 -0
- package/dist/cli/commands/clear.js +11 -0
- package/dist/cli/commands/cwd.js +9 -0
- package/dist/cli/commands/deploy.js +205 -0
- package/dist/cli/commands/emulator-orphans.js +440 -0
- package/dist/cli/commands/emulator.js +1829 -0
- package/dist/cli/commands/firebase-init.js +101 -0
- package/dist/cli/commands/firestore.js +261 -0
- package/dist/cli/commands/indexes.js +51 -0
- package/dist/cli/commands/install.js +151 -0
- package/dist/cli/commands/logs.js +358 -0
- package/dist/cli/commands/mcp.js +41 -0
- package/dist/cli/commands/migrate-markers.js +176 -0
- package/dist/cli/commands/migrate-rules.js +90 -0
- package/dist/cli/commands/migrate.js +59 -0
- package/dist/cli/commands/serve.js +208 -0
- package/dist/cli/commands/setup-tests/base-test.js +174 -0
- package/dist/cli/commands/setup-tests/emulator-config.js +109 -0
- package/dist/cli/commands/setup-tests/env-runtime-config-deprecated.js +47 -0
- package/dist/cli/commands/setup-tests/firebase-admin.js +49 -0
- package/dist/cli/commands/setup-tests/firebase-auth.js +26 -0
- package/dist/cli/commands/setup-tests/firebase-cli.js +26 -0
- package/dist/cli/commands/setup-tests/firebase-functions.js +49 -0
- package/dist/cli/commands/setup-tests/firestore-indexes-file.js +72 -0
- package/dist/cli/commands/setup-tests/firestore-indexes-in-json.js +20 -0
- package/dist/cli/commands/setup-tests/firestore-indexes-required.js +108 -0
- package/dist/cli/commands/setup-tests/firestore-indexes-synced.js +236 -0
- package/dist/cli/commands/setup-tests/firestore-rules-file.js +115 -0
- package/dist/cli/commands/setup-tests/firestore-rules-in-json.js +49 -0
- package/dist/cli/commands/setup-tests/functions-package.js +44 -0
- package/dist/cli/commands/setup-tests/gcloud-cli.js +26 -0
- package/dist/cli/commands/setup-tests/gitignore.js +122 -0
- package/dist/cli/commands/setup-tests/helpers/merge-line-files.js +28 -0
- package/dist/cli/commands/setup-tests/helpers/required-indexes.js +109 -0
- package/dist/cli/commands/setup-tests/helpers/seed-campaigns.js +246 -0
- package/dist/cli/commands/setup-tests/helpers.js +72 -0
- package/dist/cli/commands/setup-tests/hosting-folder.js +23 -0
- package/dist/cli/commands/setup-tests/hosting-rewrites.js +52 -0
- package/dist/cli/commands/setup-tests/index.js +111 -0
- package/dist/cli/commands/setup-tests/is-firebase-project.js +21 -0
- package/dist/cli/commands/setup-tests/java-installed.js +27 -0
- package/dist/cli/commands/setup-tests/legacy-tests-cleanup.js +43 -0
- package/dist/cli/commands/setup-tests/marketing-campaigns-seeded.js +230 -0
- package/dist/cli/commands/setup-tests/node-version.js +60 -0
- package/dist/cli/commands/setup-tests/npm-project-scripts.js +42 -0
- package/dist/cli/commands/setup-tests/nvmrc-version.js +36 -0
- package/dist/cli/commands/setup-tests/omega-backend.js +42 -0
- package/dist/cli/commands/setup-tests/omega-config.js +84 -0
- package/dist/cli/commands/setup-tests/project-directories.js +34 -0
- package/dist/cli/commands/setup-tests/project-id-consistency.js +201 -0
- package/dist/cli/commands/setup-tests/public-html-files.js +22 -0
- package/dist/cli/commands/setup-tests/realtime-rules-file.js +69 -0
- package/dist/cli/commands/setup-tests/realtime-rules-in-json.js +20 -0
- package/dist/cli/commands/setup-tests/remoteconfig-template-file.js +32 -0
- package/dist/cli/commands/setup-tests/remoteconfig-template-in-json.js +31 -0
- package/dist/cli/commands/setup-tests/service-account.js +86 -0
- package/dist/cli/commands/setup-tests/storage-lifecycle-policy.js +81 -0
- package/dist/cli/commands/setup-tests/storage-rules-file.js +32 -0
- package/dist/cli/commands/setup-tests/storage-rules-in-json.js +20 -0
- package/dist/cli/commands/stripe.js +14 -0
- package/dist/cli/commands/test-lanes/stripe-live.js +440 -0
- package/dist/cli/commands/test.js +976 -0
- package/dist/cli/commands/update.js +27 -0
- package/dist/cli/commands/version.js +10 -0
- package/dist/cli/commands/watch.js +196 -0
- package/dist/cli/flags.js +13 -0
- package/dist/cli/index.js +173 -0
- package/dist/cli/run.js +33 -0
- package/dist/cli/utils/attach-log-file.js +4 -0
- package/dist/cli/utils/compile-rules.js +1155 -0
- package/dist/cli/utils/ensure-target.js +314 -0
- package/dist/cli/utils/project-type.js +140 -0
- package/dist/cli/utils/public-files.js +49 -0
- package/dist/cli/utils/safe-install.js +4 -0
- package/dist/cli/utils/spawn-shell.js +94 -0
- package/dist/cli/utils/stage-functions.js +338 -0
- package/dist/cli/utils/stage-local-packages.js +210 -0
- package/dist/cli/utils/target-checks.js +161 -0
- package/dist/cli/utils/target.js +24 -0
- package/dist/cli/utils/ui.js +292 -0
- package/dist/defaults/AGENTS.md +125 -0
- package/dist/defaults/CHANGELOG.md +15 -0
- package/dist/defaults/CLAUDE.md +1 -0
- package/dist/defaults/_.gitignore +65 -0
- package/dist/defaults/docs/README.md +17 -0
- package/dist/defaults/test/README.md +65 -0
- package/dist/defaults/test/_init.js +14 -0
- package/dist/defaults/test/helpers/connect-trap.js +72 -0
- package/dist/defaults/test/unit/registration.test.js +143 -0
- package/dist/defaults/test/unit/rules-posture.test.js +101 -0
- package/dist/defaults/test/unit/socket-free.test.js +43 -0
- package/dist/manager/events/auth/before-create.js +89 -0
- package/dist/manager/events/auth/before-signin.js +76 -0
- package/dist/manager/events/auth/on-create.js +112 -0
- package/dist/manager/events/auth/on-delete.js +141 -0
- package/dist/manager/events/auth/utils.js +93 -0
- package/dist/manager/events/cron/daily/blog-auto-publisher.js +287 -0
- package/dist/manager/events/cron/daily/data-requests.js +57 -0
- package/dist/manager/events/cron/daily/expire-paypal-cancellations.js +191 -0
- package/dist/manager/events/cron/daily/marketing-prune.js +486 -0
- package/dist/manager/events/cron/daily/reset-usage.js +188 -0
- package/dist/manager/events/cron/daily/trial-lapse-sweep.js +355 -0
- package/dist/manager/events/cron/daily.js +3 -0
- package/dist/manager/events/cron/frequent/abandoned-carts.js +204 -0
- package/dist/manager/events/cron/frequent/email-queue.js +71 -0
- package/dist/manager/events/cron/frequent/marketing-campaigns.js +463 -0
- package/dist/manager/events/cron/frequent/retry-failed-webhooks.js +70 -0
- package/dist/manager/events/cron/frequent.js +3 -0
- package/dist/manager/events/cron/runner.js +64 -0
- package/dist/manager/events/firestore/notifications/on-write.js +123 -0
- package/dist/manager/events/firestore/payments-disputes/on-write.js +256 -0
- package/dist/manager/events/firestore/payments-disputes/providers/stripe.js +218 -0
- package/dist/manager/events/firestore/payments-disputes/providers/test.js +231 -0
- package/dist/manager/events/firestore/payments-webhooks/analytics.js +687 -0
- package/dist/manager/events/firestore/payments-webhooks/on-write.js +1224 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/index.js +395 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/one-time/purchase-completed.js +58 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/one-time/purchase-failed.js +28 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/one-time/purchase-refunded.js +30 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/send-email.js +74 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/cancellation-removed.js +14 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/cancellation-requested.js +28 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/checkout-declined.js +18 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/new-subscription.js +67 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/payment-failed.js +25 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/payment-recovered.js +26 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/payment-refunded.js +34 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/plan-changed.js +42 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/subscription-cancelled.js +33 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/subscription-winback.js +17 -0
- package/dist/manager/functions/_legacy/actions/create-post-handler.js +188 -0
- package/dist/manager/functions/_legacy/actions/generate-uuid.js +63 -0
- package/dist/manager/functions/_legacy/actions/sign-up-handler.js +205 -0
- package/dist/manager/functions/_legacy/admin/create-post.js +207 -0
- package/dist/manager/functions/_legacy/admin/firestore-write.js +72 -0
- package/dist/manager/functions/_legacy/admin/get-stats.js +218 -0
- package/dist/manager/functions/_legacy/admin/query.js +198 -0
- package/dist/manager/functions/_legacy/admin/send-notification.js +206 -0
- package/dist/manager/functions/_legacy/template.js +33 -0
- package/dist/manager/functions/_legacy/test/authenticate.js +40 -0
- package/dist/manager/functions/_legacy/test/webhook.js +37 -0
- package/dist/manager/functions/wrappers/mailchimp/addToList.js +25 -0
- package/dist/manager/helpers/analytics.js +498 -0
- package/dist/manager/helpers/api-manager.js +313 -0
- package/dist/manager/helpers/backend-router.js +37 -0
- package/dist/manager/helpers/context/authenticate.js +215 -0
- package/dist/manager/helpers/context/client-info.js +91 -0
- package/dist/manager/helpers/context/index.js +228 -0
- package/dist/manager/helpers/context/logging.js +150 -0
- package/dist/manager/helpers/context/parse.js +160 -0
- package/dist/manager/helpers/context/respond.js +247 -0
- package/dist/manager/helpers/event-middleware.js +109 -0
- package/dist/manager/helpers/metadata.js +32 -0
- package/dist/manager/helpers/middleware.js +541 -0
- package/dist/manager/helpers/redact-secret.js +25 -0
- package/dist/manager/helpers/resolved-config.js +34 -0
- package/dist/manager/helpers/roles.js +69 -0
- package/dist/manager/helpers/safe-compare.js +31 -0
- package/dist/manager/helpers/schema-engine.js +314 -0
- package/dist/manager/helpers/schema-zod.js +203 -0
- package/dist/manager/helpers/settings.js +215 -0
- package/dist/manager/helpers/usage.js +541 -0
- package/dist/manager/helpers/user.js +57 -0
- package/dist/manager/helpers/utilities.js +565 -0
- package/dist/manager/index.js +1404 -0
- package/dist/manager/libraries/abandoned-cart-config.js +12 -0
- package/dist/manager/libraries/ai/index.js +321 -0
- package/dist/manager/libraries/ai/prompt.js +85 -0
- package/dist/manager/libraries/ai/providers/anthropic-format.js +297 -0
- package/dist/manager/libraries/ai/providers/anthropic.js +169 -0
- package/dist/manager/libraries/ai/providers/claude-code.js +183 -0
- package/dist/manager/libraries/ai/providers/openai.js +1272 -0
- package/dist/manager/libraries/ai/providers/test.js +257 -0
- package/dist/manager/libraries/ai/tokens.js +54 -0
- package/dist/manager/libraries/analytics/conversions.js +478 -0
- package/dist/manager/libraries/analytics/match-data.js +573 -0
- package/dist/manager/libraries/analytics/signup.js +120 -0
- package/dist/manager/libraries/auth-user.js +46 -0
- package/dist/manager/libraries/content/feed-parser.js +198 -0
- package/dist/manager/libraries/content/ghostii.js +191 -0
- package/dist/manager/libraries/content/source-resolver.js +629 -0
- package/dist/manager/libraries/email/constants.js +532 -0
- package/dist/manager/libraries/email/data/blocked-local-parts.json +55 -0
- package/dist/manager/libraries/email/data/blocked-local-patterns.js +14 -0
- package/dist/manager/libraries/email/data/corporate-domains.json +23 -0
- package/dist/manager/libraries/email/data/custom-disposable-domains.json +58 -0
- package/dist/manager/libraries/email/data/disposable-domains.json +8184 -0
- package/dist/manager/libraries/email/data/typo-domains.js +83 -0
- package/dist/manager/libraries/email/disposable-domains.js +92 -0
- package/dist/manager/libraries/email/generators/lib/filter.js +179 -0
- package/dist/manager/libraries/email/generators/lib/image-host.js +344 -0
- package/dist/manager/libraries/email/generators/lib/image-illustrator.js +154 -0
- package/dist/manager/libraries/email/generators/lib/markdown-renderer.js +294 -0
- package/dist/manager/libraries/email/generators/lib/mjml-template.js +120 -0
- package/dist/manager/libraries/email/generators/lib/structure.js +299 -0
- package/dist/manager/libraries/email/generators/lib/svg-illustrator.js +197 -0
- package/dist/manager/libraries/email/generators/lib/templates/base.js +229 -0
- package/dist/manager/libraries/email/generators/lib/templates/card.js +33 -0
- package/dist/manager/libraries/email/generators/lib/templates/classic-schema.js +59 -0
- package/dist/manager/libraries/email/generators/lib/templates/clean.js +82 -0
- package/dist/manager/libraries/email/generators/lib/templates/editorial/helpers.js +100 -0
- package/dist/manager/libraries/email/generators/lib/templates/editorial/index.js +318 -0
- package/dist/manager/libraries/email/generators/lib/templates/feedback.js +101 -0
- package/dist/manager/libraries/email/generators/lib/templates/field-report/helpers.js +138 -0
- package/dist/manager/libraries/email/generators/lib/templates/field-report/index.js +494 -0
- package/dist/manager/libraries/email/generators/lib/templates/index.js +47 -0
- package/dist/manager/libraries/email/generators/lib/templates/newsletter-shared.js +610 -0
- package/dist/manager/libraries/email/generators/lib/templates/order.js +461 -0
- package/dist/manager/libraries/email/generators/lib/templates/plain.js +83 -0
- package/dist/manager/libraries/email/generators/lib/templates/shared-campaign.js +64 -0
- package/dist/manager/libraries/email/generators/newsletter.js +899 -0
- package/dist/manager/libraries/email/index.js +146 -0
- package/dist/manager/libraries/email/marketing/index.js +754 -0
- package/dist/manager/libraries/email/prepare.js +365 -0
- package/dist/manager/libraries/email/providers/beehiiv.js +589 -0
- package/dist/manager/libraries/email/providers/sendgrid.js +845 -0
- package/dist/manager/libraries/email/transactional/index.js +510 -0
- package/dist/manager/libraries/email/utm.js +86 -0
- package/dist/manager/libraries/email/validation-provider-neverbounce.js +70 -0
- package/dist/manager/libraries/email/validation-provider-zerobounce.js +42 -0
- package/dist/manager/libraries/email/validation.js +255 -0
- package/dist/manager/libraries/env.js +198 -0
- package/dist/manager/libraries/infer-contact.js +101 -0
- package/dist/manager/libraries/load-provider.js +65 -0
- package/dist/manager/libraries/notification.js +256 -0
- package/dist/manager/libraries/openai.js +13 -0
- package/dist/manager/libraries/payment/discount-codes.js +204 -0
- package/dist/manager/libraries/payment/fetch-failure.js +56 -0
- package/dist/manager/libraries/payment/license.js +44 -0
- package/dist/manager/libraries/payment/order-id.js +57 -0
- package/dist/manager/libraries/payment/provider-errors.js +71 -0
- package/dist/manager/libraries/payment/providers/chargebee.js +817 -0
- package/dist/manager/libraries/payment/providers/coinbase.js +330 -0
- package/dist/manager/libraries/payment/providers/paypal.js +987 -0
- package/dist/manager/libraries/payment/providers/stripe.js +755 -0
- package/dist/manager/libraries/payment/providers/test.js +250 -0
- package/dist/manager/libraries/payment/refund-linkage.js +78 -0
- package/dist/manager/libraries/payment/refund-policy.js +113 -0
- package/dist/manager/libraries/payment/winback.js +55 -0
- package/dist/manager/libraries/prompts/infer-contact.md +78 -0
- package/dist/manager/libraries/rate-limits.js +17 -0
- package/dist/manager/libraries/recaptcha.js +58 -0
- package/dist/manager/libraries/user-doc.js +234 -0
- package/dist/manager/routes/admin/backup/post.js +106 -0
- package/dist/manager/routes/admin/cron/post.js +37 -0
- package/dist/manager/routes/admin/database/get.js +35 -0
- package/dist/manager/routes/admin/database/post.js +34 -0
- package/dist/manager/routes/admin/email/post.js +74 -0
- package/dist/manager/routes/admin/firestore/get.js +35 -0
- package/dist/manager/routes/admin/firestore/post.js +56 -0
- package/dist/manager/routes/admin/firestore/query/post.js +128 -0
- package/dist/manager/routes/admin/hook/post.js +104 -0
- package/dist/manager/routes/admin/infer-contact/post.js +35 -0
- package/dist/manager/routes/admin/notification/post.js +37 -0
- package/dist/manager/routes/admin/payment/post.js +56 -0
- package/dist/manager/routes/admin/post/deduplicate-image-alts.js +52 -0
- package/dist/manager/routes/admin/post/dispatch-deploy.js +36 -0
- package/dist/manager/routes/admin/post/post.js +487 -0
- package/dist/manager/routes/admin/post/put.js +146 -0
- package/dist/manager/routes/admin/post/templates/post.html +14 -0
- package/dist/manager/routes/admin/repo/content/post.js +106 -0
- package/dist/manager/routes/admin/stats/get.js +222 -0
- package/dist/manager/routes/admin/users/disable/post.js +50 -0
- package/dist/manager/routes/admin/users/list/get.js +110 -0
- package/dist/manager/routes/admin/users/sync/post.js +119 -0
- package/dist/manager/routes/brand/get.js +26 -0
- package/dist/manager/routes/content/post/get.js +110 -0
- package/dist/manager/routes/general/email/post.js +89 -0
- package/dist/manager/routes/general/email/templates/general/download-app-link.js +42 -0
- package/dist/manager/routes/general/uuid/post.js +31 -0
- package/dist/manager/routes/handler/post/post.js +142 -0
- package/dist/manager/routes/health/get.js +43 -0
- package/dist/manager/routes/index.js +11 -0
- package/dist/manager/routes/marketing/campaign/delete.js +45 -0
- package/dist/manager/routes/marketing/campaign/get.js +69 -0
- package/dist/manager/routes/marketing/campaign/post.js +124 -0
- package/dist/manager/routes/marketing/campaign/put.js +86 -0
- package/dist/manager/routes/marketing/campaign/utils.js +59 -0
- package/dist/manager/routes/marketing/contact/delete.js +100 -0
- package/dist/manager/routes/marketing/contact/post.js +149 -0
- package/dist/manager/routes/marketing/contact/put.js +37 -0
- package/dist/manager/routes/marketing/email-preferences/post.js +275 -0
- package/dist/manager/routes/marketing/webhook/forward/post.js +170 -0
- package/dist/manager/routes/marketing/webhook/post.js +123 -0
- package/dist/manager/routes/marketing/webhook/providers/beehiiv.js +197 -0
- package/dist/manager/routes/marketing/webhook/providers/sendgrid.js +194 -0
- package/dist/manager/routes/payments/cancel/_is-trialing.js +40 -0
- package/dist/manager/routes/payments/cancel/post.js +149 -0
- package/dist/manager/routes/payments/cancel/providers/chargebee.js +41 -0
- package/dist/manager/routes/payments/cancel/providers/paypal.js +56 -0
- package/dist/manager/routes/payments/cancel/providers/stripe.js +33 -0
- package/dist/manager/routes/payments/cancel/providers/test.js +118 -0
- package/dist/manager/routes/payments/discount/get.js +25 -0
- package/dist/manager/routes/payments/dispute-alert/post.js +117 -0
- package/dist/manager/routes/payments/dispute-alert/providers/chargeblast.js +55 -0
- package/dist/manager/routes/payments/intent/post.js +341 -0
- package/dist/manager/routes/payments/intent/providers/chargebee.js +197 -0
- package/dist/manager/routes/payments/intent/providers/coinbase.js +94 -0
- package/dist/manager/routes/payments/intent/providers/paypal.js +244 -0
- package/dist/manager/routes/payments/intent/providers/stripe.js +141 -0
- package/dist/manager/routes/payments/intent/providers/test.js +341 -0
- package/dist/manager/routes/payments/plan/post.js +147 -0
- package/dist/manager/routes/payments/plan/providers/chargebee.js +62 -0
- package/dist/manager/routes/payments/plan/providers/paypal.js +62 -0
- package/dist/manager/routes/payments/plan/providers/stripe.js +59 -0
- package/dist/manager/routes/payments/plan/providers/test.js +113 -0
- package/dist/manager/routes/payments/portal/post.js +113 -0
- package/dist/manager/routes/payments/portal/providers/chargebee.js +62 -0
- package/dist/manager/routes/payments/portal/providers/paypal.js +25 -0
- package/dist/manager/routes/payments/portal/providers/stripe.js +62 -0
- package/dist/manager/routes/payments/portal/providers/test.js +18 -0
- package/dist/manager/routes/payments/refund/post.js +207 -0
- package/dist/manager/routes/payments/refund/providers/chargebee.js +147 -0
- package/dist/manager/routes/payments/refund/providers/coinbase.js +40 -0
- package/dist/manager/routes/payments/refund/providers/paypal.js +239 -0
- package/dist/manager/routes/payments/refund/providers/stripe.js +160 -0
- package/dist/manager/routes/payments/refund/providers/test.js +204 -0
- package/dist/manager/routes/payments/trial-eligibility/get.js +29 -0
- package/dist/manager/routes/payments/uncancel/post.js +106 -0
- package/dist/manager/routes/payments/uncancel/providers/chargebee.js +30 -0
- package/dist/manager/routes/payments/uncancel/providers/paypal.js +25 -0
- package/dist/manager/routes/payments/uncancel/providers/stripe.js +27 -0
- package/dist/manager/routes/payments/uncancel/providers/test.js +114 -0
- package/dist/manager/routes/payments/webhook/post.js +157 -0
- package/dist/manager/routes/payments/webhook/providers/chargebee.js +218 -0
- package/dist/manager/routes/payments/webhook/providers/coinbase.js +91 -0
- package/dist/manager/routes/payments/webhook/providers/paypal.js +214 -0
- package/dist/manager/routes/payments/webhook/providers/stripe.js +182 -0
- package/dist/manager/routes/payments/webhook/providers/test.js +18 -0
- package/dist/manager/routes/payments/winback/post.js +276 -0
- package/dist/manager/routes/payments/winback/providers/chargebee.js +24 -0
- package/dist/manager/routes/payments/winback/providers/paypal.js +22 -0
- package/dist/manager/routes/payments/winback/providers/stripe.js +41 -0
- package/dist/manager/routes/payments/winback/providers/test.js +42 -0
- package/dist/manager/routes/restart/index.js +37 -0
- package/dist/manager/routes/special/electron-client/post.js +59 -0
- package/dist/manager/routes/test/authenticate/get.js +11 -0
- package/dist/manager/routes/test/health/get.js +8 -0
- package/dist/manager/routes/test/index.js +16 -0
- package/dist/manager/routes/test/lab/post.js +17 -0
- package/dist/manager/routes/test/redirect/get.js +27 -0
- package/dist/manager/routes/test/reset-account/post.js +79 -0
- package/dist/manager/routes/test/roster/get.js +40 -0
- package/dist/manager/routes/test/schema/post.js +20 -0
- package/dist/manager/routes/test/usage/post.js +44 -0
- package/dist/manager/routes/test/webhook/post.js +21 -0
- package/dist/manager/routes/user/api-keys/post.js +51 -0
- package/dist/manager/routes/user/connections/_context.js +194 -0
- package/dist/manager/routes/user/connections/_grant.js +247 -0
- package/dist/manager/routes/user/connections/_lease.js +184 -0
- package/dist/manager/routes/user/connections/_providers.js +191 -0
- package/dist/manager/routes/user/connections/_state.js +117 -0
- package/dist/manager/routes/user/connections/delete.js +55 -0
- package/dist/manager/routes/user/connections/get.js +167 -0
- package/dist/manager/routes/user/connections/post.js +370 -0
- package/dist/manager/routes/user/connections/providers/discord.js +41 -0
- package/dist/manager/routes/user/connections/providers/google.js +55 -0
- package/dist/manager/routes/user/connections/providers/kick.js +68 -0
- package/dist/manager/routes/user/connections/providers/spotify.js +40 -0
- package/dist/manager/routes/user/connections/providers/twitch.js +52 -0
- package/dist/manager/routes/user/data-request/delete.js +84 -0
- package/dist/manager/routes/user/data-request/get.js +229 -0
- package/dist/manager/routes/user/data-request/post.js +136 -0
- package/dist/manager/routes/user/delete.js +149 -0
- package/dist/manager/routes/user/feedback/post.js +81 -0
- package/dist/manager/routes/user/get.js +14 -0
- package/dist/manager/routes/user/orders/get.js +95 -0
- package/dist/manager/routes/user/sessions/delete.js +95 -0
- package/dist/manager/routes/user/sessions/get.js +40 -0
- package/dist/manager/routes/user/settings/validate/post.js +86 -0
- package/dist/manager/routes/user/signup/post.js +662 -0
- package/dist/manager/routes/user/subscription/get.js +77 -0
- package/dist/manager/routes/user/token/post.js +30 -0
- package/dist/manager/routes/verts/delete.js +43 -0
- package/dist/manager/routes/verts/get.js +49 -0
- package/dist/manager/routes/verts/post.js +61 -0
- package/dist/manager/routes/verts/put.js +75 -0
- package/dist/manager/routes/verts/redirect/get.js +36 -0
- package/dist/manager/routes/verts/serve/get.js +67 -0
- package/dist/manager/routes/verts/utils.js +436 -0
- package/dist/manager/schemas/admin/backup/post.js +8 -0
- package/dist/manager/schemas/admin/cron/post.js +8 -0
- package/dist/manager/schemas/admin/database/get.js +5 -0
- package/dist/manager/schemas/admin/database/post.js +6 -0
- package/dist/manager/schemas/admin/email/post.js +31 -0
- package/dist/manager/schemas/admin/firestore/get.js +5 -0
- package/dist/manager/schemas/admin/firestore/post.js +8 -0
- package/dist/manager/schemas/admin/firestore/query/post.js +5 -0
- package/dist/manager/schemas/admin/hook/post.js +8 -0
- package/dist/manager/schemas/admin/infer-contact/post.js +6 -0
- package/dist/manager/schemas/admin/notification/post.js +23 -0
- package/dist/manager/schemas/admin/payment/post.js +8 -0
- package/dist/manager/schemas/admin/post/post.js +23 -0
- package/dist/manager/schemas/admin/post/put.js +13 -0
- package/dist/manager/schemas/admin/repo/content/post.js +10 -0
- package/dist/manager/schemas/admin/stats/get.js +5 -0
- package/dist/manager/schemas/admin/users/disable/post.js +9 -0
- package/dist/manager/schemas/admin/users/list/get.js +10 -0
- package/dist/manager/schemas/admin/users/sync/post.js +7 -0
- package/dist/manager/schemas/brand/get.js +3 -0
- package/dist/manager/schemas/content/post/get.js +8 -0
- package/dist/manager/schemas/general/email/post.js +10 -0
- package/dist/manager/schemas/general/uuid/post.js +9 -0
- package/dist/manager/schemas/handler/post/post.js +13 -0
- package/dist/manager/schemas/health/get.js +3 -0
- package/dist/manager/schemas/marketing/campaign/delete.js +8 -0
- package/dist/manager/schemas/marketing/campaign/get.js +13 -0
- package/dist/manager/schemas/marketing/campaign/post.js +43 -0
- package/dist/manager/schemas/marketing/campaign/put.js +37 -0
- package/dist/manager/schemas/marketing/contact/delete.js +8 -0
- package/dist/manager/schemas/marketing/contact/post.js +14 -0
- package/dist/manager/schemas/marketing/contact/put.js +8 -0
- package/dist/manager/schemas/marketing/email-preferences/post.js +15 -0
- package/dist/manager/schemas/marketing/webhook/forward/post.js +8 -0
- package/dist/manager/schemas/marketing/webhook/post.js +7 -0
- package/dist/manager/schemas/payments/cancel/post.js +15 -0
- package/dist/manager/schemas/payments/discount/get.js +8 -0
- package/dist/manager/schemas/payments/dispute-alert/post.js +6 -0
- package/dist/manager/schemas/payments/intent/post.js +28 -0
- package/dist/manager/schemas/payments/plan/post.js +11 -0
- package/dist/manager/schemas/payments/portal/post.js +12 -0
- package/dist/manager/schemas/payments/refund/post.js +14 -0
- package/dist/manager/schemas/payments/trial-eligibility/get.js +7 -0
- package/dist/manager/schemas/payments/uncancel/post.js +9 -0
- package/dist/manager/schemas/payments/webhook/post.js +6 -0
- package/dist/manager/schemas/payments/winback/post.js +12 -0
- package/dist/manager/schemas/restart/index.js +5 -0
- package/dist/manager/schemas/special/electron-client/post.js +11 -0
- package/dist/manager/schemas/test/authenticate/get.js +3 -0
- package/dist/manager/schemas/test/health/get.js +3 -0
- package/dist/manager/schemas/test/index.js +5 -0
- package/dist/manager/schemas/test/lab/post.js +3 -0
- package/dist/manager/schemas/test/redirect/get.js +7 -0
- package/dist/manager/schemas/test/reset-account/post.js +3 -0
- package/dist/manager/schemas/test/roster/get.js +3 -0
- package/dist/manager/schemas/test/schema/post.js +70 -0
- package/dist/manager/schemas/test/usage/post.js +8 -0
- package/dist/manager/schemas/test/webhook/post.js +7 -0
- package/dist/manager/schemas/user/api-keys/post.js +6 -0
- package/dist/manager/schemas/user/connections/delete.js +8 -0
- package/dist/manager/schemas/user/connections/get.js +21 -0
- package/dist/manager/schemas/user/connections/post.js +12 -0
- package/dist/manager/schemas/user/data-request/delete.js +3 -0
- package/dist/manager/schemas/user/data-request/get.js +5 -0
- package/dist/manager/schemas/user/data-request/post.js +6 -0
- package/dist/manager/schemas/user/delete.js +6 -0
- package/dist/manager/schemas/user/feedback/post.js +8 -0
- package/dist/manager/schemas/user/get.js +3 -0
- package/dist/manager/schemas/user/orders/get.js +6 -0
- package/dist/manager/schemas/user/sessions/delete.js +6 -0
- package/dist/manager/schemas/user/sessions/get.js +6 -0
- package/dist/manager/schemas/user/settings/validate/post.js +8 -0
- package/dist/manager/schemas/user/signup/post.js +27 -0
- package/dist/manager/schemas/user/subscription/get.js +5 -0
- package/dist/manager/schemas/user/token/post.js +5 -0
- package/dist/manager/schemas/verts/delete.js +8 -0
- package/dist/manager/schemas/verts/get.js +9 -0
- package/dist/manager/schemas/verts/post.js +23 -0
- package/dist/manager/schemas/verts/put.js +20 -0
- package/dist/manager/schemas/verts/redirect/get.js +10 -0
- package/dist/manager/schemas/verts/serve/get.js +14 -0
- package/dist/manager/server-manager.js +69 -0
- package/dist/mcp/client.js +98 -0
- package/dist/mcp/handler.js +521 -0
- package/dist/mcp/index.js +157 -0
- package/dist/mcp/tools.js +555 -0
- package/dist/mcp/utils.js +108 -0
- package/dist/omega-bin.js +6 -0
- package/dist/require.js +3 -0
- package/dist/test/fixtures/firebase-project/.firebaserc +5 -0
- package/dist/test/fixtures/firebase-project/config/omega.json5 +131 -0
- package/dist/test/fixtures/firebase-project/database.rules.json +6 -0
- package/dist/test/fixtures/firebase-project/firebase.json +49 -0
- package/dist/test/fixtures/firebase-project/firestore.indexes.json +4 -0
- package/dist/test/fixtures/firebase-project/package.json +14 -0
- package/dist/test/fixtures/firebase-project/src/index.js +11 -0
- package/dist/test/fixtures/firebase-project/storage.rules +8 -0
- package/dist/test/parse-audit.js +25 -0
- package/dist/test/run-tests.js +90 -0
- package/dist/test/runner.js +982 -0
- package/dist/test/seed.js +242 -0
- package/dist/test/test-accounts.js +2660 -0
- package/dist/test/utils/assertions.js +189 -0
- package/dist/test/utils/email-capture.js +252 -0
- package/dist/test/utils/extended-mode-warning.js +11 -0
- package/dist/test/utils/firestore-rules-client.js +277 -0
- package/dist/test/utils/http-client.js +228 -0
- package/dist/test/utils/test-mode-file.js +192 -0
- package/dist/utils/merge-line-files.js +6 -0
- package/dist/utils/scaffold-defaults.js +71 -0
- package/dist/utils/test-lanes.js +62 -0
- package/dist/vendor/account/engine.js +182 -0
- package/dist/vendor/account/features.js +220 -0
- package/dist/vendor/account/index.js +53 -0
- package/dist/vendor/account/schema.js +272 -0
- package/dist/vendor/account/subscription.js +38 -0
- package/dist/vendor/analytics/adapters/ga4.js +26 -0
- package/dist/vendor/analytics/adapters/meta.js +26 -0
- package/dist/vendor/analytics/adapters/resolve.js +130 -0
- package/dist/vendor/analytics/adapters/tiktok.js +27 -0
- package/dist/vendor/analytics/catalog.js +908 -0
- package/dist/vendor/analytics/identity.js +136 -0
- package/dist/vendor/config/company.js +31 -0
- package/dist/vendor/config/defaults.js +173 -0
- package/dist/vendor/config/demo.js +18 -0
- package/dist/vendor/config/desktop-artifacts.js +110 -0
- package/dist/vendor/config/edit.js +769 -0
- package/dist/vendor/config/env-delivery.js +145 -0
- package/dist/vendor/config/env-rules.js +93 -0
- package/dist/vendor/config/env-schema.js +1078 -0
- package/dist/vendor/config/env.js +445 -0
- package/dist/vendor/config/hooks.js +97 -0
- package/dist/vendor/config/index.js +237 -0
- package/dist/vendor/config/instances.js +208 -0
- package/dist/vendor/config/load.js +490 -0
- package/dist/vendor/config/merge.js +68 -0
- package/dist/vendor/config/order.js +139 -0
- package/dist/vendor/config/ports.js +374 -0
- package/dist/vendor/config/providers.js +32 -0
- package/dist/vendor/config/repo.js +142 -0
- package/dist/vendor/config/retired-keys.js +430 -0
- package/dist/vendor/config/schema.js +1610 -0
- package/dist/vendor/config/secrets.js +50 -0
- package/dist/vendor/config/seed.js +34 -0
- package/dist/vendor/config/site-global.js +205 -0
- package/dist/vendor/config/validate.js +554 -0
- package/dist/vendor/config/winback.js +61 -0
- package/dist/vendor/devkit/attach-log-file.js +262 -0
- package/dist/vendor/devkit/bare-requires.js +153 -0
- package/dist/vendor/devkit/command-path.js +46 -0
- package/dist/vendor/devkit/defaults-engine.js +372 -0
- package/dist/vendor/devkit/deploy-record.js +180 -0
- package/dist/vendor/devkit/deploy.js +286 -0
- package/dist/vendor/devkit/license.js +155 -0
- package/dist/vendor/devkit/local-https.js +360 -0
- package/dist/vendor/devkit/local.js +1905 -0
- package/dist/vendor/devkit/logger.js +128 -0
- package/dist/vendor/devkit/merge-line-files.js +296 -0
- package/dist/vendor/devkit/npm-registry.js +52 -0
- package/dist/vendor/devkit/omega-bin.js +345 -0
- package/dist/vendor/devkit/parse-audit.js +74 -0
- package/dist/vendor/devkit/safe-install.js +18 -0
- package/dist/vendor/devkit/scaffold-guard.js +96 -0
- package/dist/vendor/devkit/stop-signals.js +28 -0
- package/dist/vendor/devkit/test/assert.js +120 -0
- package/dist/vendor/devkit/test/define-cases.js +104 -0
- package/dist/vendor/devkit/test/runner-core.js +554 -0
- package/dist/vendor/devkit/test/scope.js +162 -0
- package/dist/vendor/devkit/update.js +569 -0
- package/dist/vendor/monitoring/core.js +180 -0
- package/dist/vendor/monitoring/env.js +49 -0
- package/dist/vendor/monitoring/logger.js +39 -0
- package/dist/vendor/monitoring/node.js +72 -0
- package/docs/admin-post-route.md +57 -0
- package/docs/ai-library.md +171 -0
- package/docs/architecture.md +62 -0
- package/docs/audit.md +70 -0
- package/docs/auth-hooks.md +74 -0
- package/docs/build-system.md +65 -0
- package/docs/cdp-debugging.md +29 -0
- package/docs/cli-firestore-auth.md +85 -0
- package/docs/cli-logs.md +67 -0
- package/docs/cli-output.md +146 -0
- package/docs/code-patterns.md +77 -0
- package/docs/common-mistakes.md +12 -0
- package/docs/common-operations.md +60 -0
- package/docs/connections.md +212 -0
- package/docs/consent.md +362 -0
- package/docs/directory-structure.md +150 -0
- package/docs/email-system.md +459 -0
- package/docs/environment-detection.md +93 -0
- package/docs/file-naming.md +10 -0
- package/docs/firestore.md +134 -0
- package/docs/ghostii.md +240 -0
- package/docs/index.md +299 -0
- package/docs/key-files.md +37 -0
- package/docs/logging.md +60 -0
- package/docs/marketing-campaigns.md +407 -0
- package/docs/marketing-fields.md +25 -0
- package/docs/mcp.md +222 -0
- package/docs/migration.md +129 -0
- package/docs/payment-system.md +856 -0
- package/docs/paypal-sandbox-qa.md +105 -0
- package/docs/response-headers.md +9 -0
- package/docs/routes.md +211 -0
- package/docs/sanitization.md +71 -0
- package/docs/schemas.md +163 -0
- package/docs/shared/agent-docs.md +89 -0
- package/docs/shared/analytics.md +612 -0
- package/docs/shared/brands.md +51 -0
- package/docs/shared/breaking-changes.md +497 -0
- package/docs/shared/config.md +1387 -0
- package/docs/shared/deploys.md +215 -0
- package/docs/shared/icons.md +201 -0
- package/docs/shared/local-dev.md +147 -0
- package/docs/shared/logging.md +202 -0
- package/docs/shared/monitoring.md +153 -0
- package/docs/shared/publishing.md +183 -0
- package/docs/shared/rulings.md +34 -0
- package/docs/shared/testing.md +147 -0
- package/docs/shared/theming.md +604 -0
- package/docs/shared/translation.md +291 -0
- package/docs/shared/updates.md +61 -0
- package/docs/stripe-webhook-forwarding.md +20 -0
- package/docs/test-boot-layer.md +67 -0
- package/docs/test-framework.md +583 -0
- package/docs/usage-rate-limiting.md +121 -0
- package/docs/verts.md +29 -0
- package/package.json +143 -0
- package/templates/config/omega.json5 +322 -0
- package/templates/database.rules.json +82 -0
- package/templates/firebase.json +67 -0
- package/templates/firestore.framework.rules +191 -0
- package/templates/firestore.indexes.json +4 -0
- package/templates/firestore.rules +59 -0
- package/templates/index.js +12 -0
- package/templates/public/404.html +26 -0
- package/templates/public/index.html +24 -0
- package/templates/remoteconfig.template.json +1 -0
- package/templates/storage-lifecycle-config-1-day.json +9 -0
- package/templates/storage-lifecycle-config-30-days.json +9 -0
- package/templates/storage.rules +11 -0
- package/test/_init/accounts-validation.js +58 -0
- package/test/ai/tools-live.test.js +171 -0
- package/test/analytics/conversion-delivery.test.js +1013 -0
- package/test/analytics/match-normalization.test.js +238 -0
- package/test/analytics/signup-conversion.test.js +135 -0
- package/test/boot/cli-dispatch.test.js +142 -0
- package/test/boot/defaults-scaffold.test.js +248 -0
- package/test/boot/deploy-staging.test.js +446 -0
- package/test/boot/disposable-domains.test.js +154 -0
- package/test/boot/emulator-boots.test.js +39 -0
- package/test/boot/emulator-port-preflight.test.js +126 -0
- package/test/boot/emulator-ready-timeout.test.js +46 -0
- package/test/boot/project-id-refresh.test.js +73 -0
- package/test/boot/suite-portability.test.js +278 -0
- package/test/boot/update-command.test.js +63 -0
- package/test/cli/cross-platform.test.js +168 -0
- package/test/cli/custom-project-type.test.js +426 -0
- package/test/cli/deploy-license-env.test.js +100 -0
- package/test/cli/emulator-adoption.test.js +254 -0
- package/test/cli/emulator-orphans.test.js +658 -0
- package/test/cli/emulator-ownership.test.js +177 -0
- package/test/cli/emulator-port-retry.test.js +395 -0
- package/test/cli/emulator-shutdown.test.js +788 -0
- package/test/cli/emulator-stale-reap.test.js +574 -0
- package/test/cli/ensure-target.test.js +325 -0
- package/test/cli/flags.test.js +64 -0
- package/test/cli/https-trust.test.js +38 -0
- package/test/cli/install-update-dispatch.test.js +47 -0
- package/test/cli/lane-environments.test.js +159 -0
- package/test/cli/marketing-campaigns-seeded.test.js +194 -0
- package/test/cli/migrate-bare-requires.test.js +128 -0
- package/test/cli/migrate-markers.test.js +530 -0
- package/test/cli/required-indexes.test.js +64 -0
- package/test/cli/rules-compile.test.js +622 -0
- package/test/cli/rules-migration-deferral.test.js +259 -0
- package/test/cli/rules-version.test.js +104 -0
- package/test/cli/setup-load-files.test.js +66 -0
- package/test/cli/setup-offline-mode.test.js +276 -0
- package/test/cli/setup-retired.test.js +64 -0
- package/test/cli/setup-shared-project-indexes.test.js +262 -0
- package/test/cli/setup-tests-requires.test.js +45 -0
- package/test/cli/stage-env-compose.test.js +316 -0
- package/test/cli/stripe-live-lane.test.js +303 -0
- package/test/cli/target.test.js +182 -0
- package/test/cli/templates.test.js +66 -0
- package/test/cli/test-runner-env.test.js +115 -0
- package/test/cli/test-stack-shutdown.test.js +275 -0
- package/test/cli/test-target-no-match.test.js +128 -0
- package/test/cli/verb-logs.test.js +118 -0
- package/test/cli/version-dispatch.test.js +39 -0
- package/test/content/blog-generate.test.js +164 -0
- package/test/email/campaign-config-fault.test.js +376 -0
- package/test/email/campaign-cron-pipeline.test.js +536 -0
- package/test/email/campaign-send.test.js +47 -0
- package/test/email/consent-lifecycle.test.js +258 -0
- package/test/email/content-html-policy.test.js +270 -0
- package/test/email/feedback-and-plain-send.test.js +54 -0
- package/test/email/fixtures/clean.json +30 -0
- package/test/email/fixtures/editorial.json +30 -0
- package/test/email/fixtures/field-report.json +53 -0
- package/test/email/identity.test.js +321 -0
- package/test/email/marketing/consent-gate.test.js +265 -0
- package/test/email/marketing/custom-fields-catalog.test.js +259 -0
- package/test/email/marketing/prune-per-provider.test.js +762 -0
- package/test/email/marketing/remove-log-privacy.test.js +225 -0
- package/test/email/marketing-lifecycle.test.js +139 -0
- package/test/email/newsletter-generate.test.js +853 -0
- package/test/email/newsletter-svg-tokens.test.js +51 -0
- package/test/email/newsletter-templates.test.js +492 -0
- package/test/email/order-one-time-cta.test.js +97 -0
- package/test/email/render-content.test.js +248 -0
- package/test/email/safe-url.test.js +0 -0
- package/test/email/sanitize-images.test.js +66 -0
- package/test/email/send-log-privacy.test.js +107 -0
- package/test/email/templates.test.js +288 -0
- package/test/email/testing-capture.test.js +260 -0
- package/test/email/transactional-send.test.js +36 -0
- package/test/email/transactional.test.js +562 -0
- package/test/email/unsubscribe-groups.test.js +155 -0
- package/test/email/unsubscribe-key.test.js +91 -0
- package/test/email/validation-cases.test.js +152 -0
- package/test/email/validation.test.js +746 -0
- package/test/events/auth-delete-conversion.test.js +138 -0
- package/test/events/auth-delete-race.test.js +211 -0
- package/test/events/auth-on-create-log.test.js +164 -0
- package/test/events/auth-signup-conversion.test.js +141 -0
- package/test/events/auth-signup-limit.test.js +142 -0
- package/test/events/auth-trigger-log-privacy.test.js +256 -0
- package/test/events/cron-job-doc-shape.test.js +101 -0
- package/test/events/cron-reset-usage.test.js +116 -0
- package/test/events/notification-conversion.test.js +182 -0
- package/test/events/payments/_webhook-harness.js +307 -0
- package/test/events/payments/abandoned-cart-activity.test.js +135 -0
- package/test/events/payments/analytics-payment-events.test.js +945 -0
- package/test/events/payments/dispute-email-status.test.js +55 -0
- package/test/events/payments/journey-payments-abandoned.test.js +126 -0
- package/test/events/payments/journey-payments-cancel-endpoint.test.js +102 -0
- package/test/events/payments/journey-payments-cancel-no-order.test.js +76 -0
- package/test/events/payments/journey-payments-cancel.test.js +184 -0
- package/test/events/payments/journey-payments-decline.test.js +225 -0
- package/test/events/payments/journey-payments-discount.test.js +91 -0
- package/test/events/payments/journey-payments-dispute.test.js +190 -0
- package/test/events/payments/journey-payments-failure.test.js +148 -0
- package/test/events/payments/journey-payments-legacy-product.test.js +151 -0
- package/test/events/payments/journey-payments-one-time-decline.test.js +127 -0
- package/test/events/payments/journey-payments-one-time-failure.test.js +113 -0
- package/test/events/payments/journey-payments-one-time-refund.test.js +186 -0
- package/test/events/payments/journey-payments-one-time.test.js +175 -0
- package/test/events/payments/journey-payments-plan-change.test.js +146 -0
- package/test/events/payments/journey-payments-plan-switch-trial.test.js +161 -0
- package/test/events/payments/journey-payments-plan-switch.test.js +182 -0
- package/test/events/payments/journey-payments-refund-no-order.test.js +76 -0
- package/test/events/payments/journey-payments-refund-webhook.test.js +225 -0
- package/test/events/payments/journey-payments-suspend.test.js +183 -0
- package/test/events/payments/journey-payments-trial-cancel.test.js +132 -0
- package/test/events/payments/journey-payments-trial.test.js +173 -0
- package/test/events/payments/journey-payments-uid-resolution.test.js +134 -0
- package/test/events/payments/journey-payments-uncancel.test.js +157 -0
- package/test/events/payments/journey-payments-upgrade.test.js +137 -0
- package/test/events/payments/journey-payments-winback-decline.test.js +171 -0
- package/test/events/payments/journey-payments-winback.test.js +195 -0
- package/test/events/payments/paypal-expiry-cron.test.js +166 -0
- package/test/events/payments/purchase-failed-handler.test.js +80 -0
- package/test/events/payments/purchase-refunded-handler.test.js +108 -0
- package/test/events/payments/test-processor-doc-shape.test.js +162 -0
- package/test/events/payments/transition-order-emails.test.js +185 -0
- package/test/events/payments/transition-promo-lines.test.js +192 -0
- package/test/events/payments/transitions-detect.test.js +767 -0
- package/test/events/payments/trial-lapse-sweep-staleness.test.js +173 -0
- package/test/events/payments/trial-lapse-sweep.test.js +359 -0
- package/test/events/payments/webhook-atomic-writes.test.js +69 -0
- package/test/events/payments/webhook-chargebee-unreachable.test.js +106 -0
- package/test/events/payments/webhook-discount-clear.test.js +189 -0
- package/test/events/payments/webhook-failure-intent.test.js +93 -0
- package/test/events/payments/webhook-hosted-page-uid-trust.test.js +212 -0
- package/test/events/payments/webhook-ordering.test.js +326 -0
- package/test/events/payments/webhook-provider-lookup-trust.test.js +206 -0
- package/test/events/payments/webhook-refund-amount-trust.test.js +223 -0
- package/test/events/payments/webhook-refund-envelope-shape.test.js +148 -0
- package/test/events/payments/webhook-refund-linkage-trust.test.js +404 -0
- package/test/events/payments/webhook-refund-transaction-fallback.test.js +184 -0
- package/test/events/payments/webhook-refund-without-order.test.js +170 -0
- package/test/events/payments/webhook-refusal-reporting.test.js +194 -0
- package/test/events/payments/webhook-refused-intent.test.js +142 -0
- package/test/events/payments/webhook-retry-sweep.test.js +252 -0
- package/test/events/payments/webhook-transition-claim.test.js +389 -0
- package/test/events/payments/webhook-uid-trust.test.js +203 -0
- package/test/events/payments/webhook-user-without-auth.test.js +161 -0
- package/test/fixtures/chargebee/invoice-one-time.json +27 -0
- package/test/fixtures/chargebee/subscription-active.json +44 -0
- package/test/fixtures/chargebee/subscription-cancelled.json +42 -0
- package/test/fixtures/chargebee/subscription-in-trial.json +41 -0
- package/test/fixtures/chargebee/subscription-legacy-plan.json +41 -0
- package/test/fixtures/chargebee/subscription-non-renewing.json +41 -0
- package/test/fixtures/chargebee/subscription-paused.json +42 -0
- package/test/fixtures/chargebee/webhook-payment-failed.json +51 -0
- package/test/fixtures/chargebee/webhook-subscription-created.json +47 -0
- package/test/fixtures/coinbase/charge-confirmed.json +50 -0
- package/test/fixtures/coinbase/charge-failed.json +34 -0
- package/test/fixtures/coinbase/charge-pending.json +34 -0
- package/test/fixtures/migrate/ported-route.js.txt +11 -0
- package/test/fixtures/paypal/capture-completed.json +51 -0
- package/test/fixtures/paypal/capture-refunded.json +43 -0
- package/test/fixtures/paypal/order-approved.json +62 -0
- package/test/fixtures/paypal/order-completed.json +110 -0
- package/test/fixtures/paypal/sale-refunded.json +38 -0
- package/test/fixtures/paypal/subscription-active.json +76 -0
- package/test/fixtures/paypal/subscription-cancelled.json +50 -0
- package/test/fixtures/paypal/subscription-suspended.json +65 -0
- package/test/fixtures/stripe/checkout-session-completed.json +130 -0
- package/test/fixtures/stripe/invoice-payment-failed.json +148 -0
- package/test/fixtures/stripe/invoice-subscription-payment-failed.json +28 -0
- package/test/fixtures/stripe/invoice-subscription-payment-succeeded.json +28 -0
- package/test/fixtures/stripe/subscription-active.json +161 -0
- package/test/fixtures/stripe/subscription-canceled.json +161 -0
- package/test/fixtures/stripe/subscription-trialing.json +161 -0
- package/test/helpers/_shared-config.js +15 -0
- package/test/helpers/ai-request-payload.test.js +619 -0
- package/test/helpers/ai-schema-resolve.test.js +125 -0
- package/test/helpers/ai-test-provider.test.js +227 -0
- package/test/helpers/ai-token-accounting.test.js +150 -0
- package/test/helpers/ai-tools-format.test.js +384 -0
- package/test/helpers/analytics-no-id-notice.test.js +146 -0
- package/test/helpers/analytics-user-data.test.js +194 -0
- package/test/helpers/api-manager.test.js +311 -0
- package/test/helpers/backend-router.test.js +136 -0
- package/test/helpers/content/blog-auto-publisher.test.js +482 -0
- package/test/helpers/content/feed-parser.test.js +529 -0
- package/test/helpers/content/ghostii-blocks.test.js +135 -0
- package/test/helpers/content/ghostii-feed-integration.test.js +405 -0
- package/test/helpers/content/ghostii-write-article.test.js +244 -0
- package/test/helpers/dev-only-routes.test.js +225 -0
- package/test/helpers/env-reader.test.js +362 -0
- package/test/helpers/environment.test.js +263 -0
- package/test/helpers/event-middleware.test.js +407 -0
- package/test/helpers/infer-contact.test.js +157 -0
- package/test/helpers/lane-url.test.js +90 -0
- package/test/helpers/merge-line-files.test.js +272 -0
- package/test/helpers/metadata.test.js +122 -0
- package/test/helpers/middleware-request-log.test.js +134 -0
- package/test/helpers/middleware-user-log.test.js +124 -0
- package/test/helpers/payment/chargebee/parse-webhook.test.js +490 -0
- package/test/helpers/payment/chargebee/refund-details.test.js +198 -0
- package/test/helpers/payment/chargebee/to-unified-one-time.test.js +148 -0
- package/test/helpers/payment/chargebee/to-unified-subscription.test.js +649 -0
- package/test/helpers/payment/coinbase/create-intent.test.js +247 -0
- package/test/helpers/payment/coinbase/parse-webhook.test.js +195 -0
- package/test/helpers/payment/coinbase/refund-unsupported.test.js +141 -0
- package/test/helpers/payment/coinbase/to-unified-one-time.test.js +201 -0
- package/test/helpers/payment/discount-codes.test.js +141 -0
- package/test/helpers/payment/extract-resource.test.js +113 -0
- package/test/helpers/payment/fetch-failure.test.js +215 -0
- package/test/helpers/payment/license-gate.test.js +108 -0
- package/test/helpers/payment/order-id.test.js +99 -0
- package/test/helpers/payment/paypal/create-intent.test.js +382 -0
- package/test/helpers/payment/paypal/fetch-capture.test.js +123 -0
- package/test/helpers/payment/paypal/fetch-sale.test.js +183 -0
- package/test/helpers/payment/paypal/parse-webhook.test.js +678 -0
- package/test/helpers/payment/paypal/refund-details.test.js +202 -0
- package/test/helpers/payment/paypal/resolve-plan-id.test.js +108 -0
- package/test/helpers/payment/paypal/switch-plan.test.js +92 -0
- package/test/helpers/payment/paypal/to-unified-one-time.test.js +383 -0
- package/test/helpers/payment/paypal/to-unified-subscription.test.js +884 -0
- package/test/helpers/payment/stripe/fetch-charge.test.js +147 -0
- package/test/helpers/payment/stripe/parse-webhook.test.js +448 -0
- package/test/helpers/payment/stripe/refund-details.test.js +147 -0
- package/test/helpers/payment/stripe/to-unified-one-time.test.js +307 -0
- package/test/helpers/payment/stripe/to-unified-subscription.test.js +709 -0
- package/test/helpers/persona-domain.test.js +87 -0
- package/test/helpers/recaptcha.test.js +166 -0
- package/test/helpers/resolved-config.test.js +106 -0
- package/test/helpers/response-log-redaction.test.js +262 -0
- package/test/helpers/roles.test.js +155 -0
- package/test/helpers/route-context-debug-gate.test.js +118 -0
- package/test/helpers/route-context-logging.test.js +214 -0
- package/test/helpers/route-context.test.js +129 -0
- package/test/helpers/safe-compare.test.js +114 -0
- package/test/helpers/sanitize.test.js +223 -0
- package/test/helpers/schema-engine.test.js +537 -0
- package/test/helpers/schema-zod.test.js +554 -0
- package/test/helpers/seed-accounts-load.test.js +163 -0
- package/test/helpers/seed-google-personas.test.js +114 -0
- package/test/helpers/seeded-personas.test.js +823 -0
- package/test/helpers/settings.test.js +292 -0
- package/test/helpers/setup-engines-pin.test.js +68 -0
- package/test/helpers/setup-manifest-sync.test.js +116 -0
- package/test/helpers/slugify.test.js +395 -0
- package/test/helpers/storage.test.js +195 -0
- package/test/helpers/test-banner-latch.test.js +139 -0
- package/test/helpers/usage-consume.test.js +460 -0
- package/test/helpers/usage-log-privacy.test.js +121 -0
- package/test/helpers/user-doc-heal.test.js +540 -0
- package/test/helpers/user.test.js +771 -0
- package/test/helpers/webhook-forward.test.js +419 -0
- package/test/helpers/wipe-auth-project.test.js +143 -0
- package/test/mcp/discovery.test.js +52 -0
- package/test/mcp/oauth.test.js +160 -0
- package/test/mcp/protocol.test.js +278 -0
- package/test/mcp/roles.test.js +203 -0
- package/test/mcp/utils.test.js +245 -0
- package/test/notification/identity.test.js +155 -0
- package/test/routes/admin/create-post.test.js +362 -0
- package/test/routes/admin/database.test.js +133 -0
- package/test/routes/admin/deduplicate-image-alts.test.js +191 -0
- package/test/routes/admin/email-content-html.test.js +58 -0
- package/test/routes/admin/email-request-log.test.js +86 -0
- package/test/routes/admin/email.test.js +116 -0
- package/test/routes/admin/firestore-query.test.js +206 -0
- package/test/routes/admin/firestore.test.js +129 -0
- package/test/routes/admin/infer-contact.test.js +220 -0
- package/test/routes/admin/notification.test.js +199 -0
- package/test/routes/admin/post-convert-image.test.js +159 -0
- package/test/routes/admin/post-deploy-flag.test.js +81 -0
- package/test/routes/admin/post-download-error.test.js +90 -0
- package/test/routes/admin/post-resize-image.test.js +185 -0
- package/test/routes/admin/post.test.js +369 -0
- package/test/routes/admin/repo-content.test.js +223 -0
- package/test/routes/admin/stats.test.js +114 -0
- package/test/routes/admin/users-disable.test.js +63 -0
- package/test/routes/admin/users-list.test.js +71 -0
- package/test/routes/content/post.test.js +60 -0
- package/test/routes/general/uuid.test.js +133 -0
- package/test/routes/health.test.js +110 -0
- package/test/routes/marketing/campaign.test.js +184 -0
- package/test/routes/marketing/contact.test.js +416 -0
- package/test/routes/marketing/email-preferences.test.js +293 -0
- package/test/routes/marketing/push-send.test.js +34 -0
- package/test/routes/marketing/webhook-forward.test.js +63 -0
- package/test/routes/marketing/webhook.test.js +641 -0
- package/test/routes/payments/_route-harness.js +145 -0
- package/test/routes/payments/cancel-provider-errors.test.js +227 -0
- package/test/routes/payments/cancel-skip-guards.test.js +126 -0
- package/test/routes/payments/cancel-trialing.test.js +428 -0
- package/test/routes/payments/cancel.test.js +165 -0
- package/test/routes/payments/dedup-race.test.js +186 -0
- package/test/routes/payments/discount.test.js +82 -0
- package/test/routes/payments/dispute-alert.test.js +324 -0
- package/test/routes/payments/intent-discount-amounts.test.js +550 -0
- package/test/routes/payments/intent-discount-coupons.test.js +293 -0
- package/test/routes/payments/intent-one-time-metadata.test.js +122 -0
- package/test/routes/payments/intent-purchaser-guard.test.js +139 -0
- package/test/routes/payments/intent-zero-total.test.js +260 -0
- package/test/routes/payments/intent.test.js +413 -0
- package/test/routes/payments/plan.test.js +367 -0
- package/test/routes/payments/portal-return-url.test.js +107 -0
- package/test/routes/payments/portal.test.js +94 -0
- package/test/routes/payments/refund-one-time.test.js +254 -0
- package/test/routes/payments/refund-paypal-proration.test.js +190 -0
- package/test/routes/payments/refund.test.js +181 -0
- package/test/routes/payments/trial-eligibility.test.js +73 -0
- package/test/routes/payments/uncancel.test.js +270 -0
- package/test/routes/payments/webhook-stripe-invoice.test.js +129 -0
- package/test/routes/payments/webhook-stripe-refund-one-time.test.js +130 -0
- package/test/routes/payments/webhook-test-provider.test.js +156 -0
- package/test/routes/payments/webhook.test.js +115 -0
- package/test/routes/payments/winback-stripe-coupon.test.js +126 -0
- package/test/routes/payments/winback.test.js +597 -0
- package/test/routes/test/authenticate.test.js +79 -0
- package/test/routes/test/redirect.test.js +66 -0
- package/test/routes/test/reset-account.test.js +126 -0
- package/test/routes/test/roster.test.js +101 -0
- package/test/routes/test/schema.test.js +556 -0
- package/test/routes/test/usage.test.js +374 -0
- package/test/routes/user/api-keys.test.js +158 -0
- package/test/routes/user/connections-grant.test.js +759 -0
- package/test/routes/user/connections-identity.test.js +260 -0
- package/test/routes/user/connections-log-privacy.test.js +206 -0
- package/test/routes/user/connections-refresh-lease.test.js +696 -0
- package/test/routes/user/connections-return.test.js +261 -0
- package/test/routes/user/connections-uid.test.js +516 -0
- package/test/routes/user/delete.test.js +138 -0
- package/test/routes/user/feedback.test.js +106 -0
- package/test/routes/user/orders.test.js +233 -0
- package/test/routes/user/sessions.test.js +231 -0
- package/test/routes/user/settings-validate.test.js +84 -0
- package/test/routes/user/signup-emails.test.js +113 -0
- package/test/routes/user/signup-location.test.js +84 -0
- package/test/routes/user/signup-log-privacy.test.js +112 -0
- package/test/routes/user/signup.test.js +579 -0
- package/test/routes/user/subscription.test.js +101 -0
- package/test/routes/user/token.test.js +111 -0
- package/test/routes/user/user.test.js +158 -0
- package/test/routes/verts/cache.test.js +78 -0
- package/test/routes/verts/click-destination.test.js +76 -0
- package/test/routes/verts/crud.test.js +194 -0
- package/test/routes/verts/redirect.test.js +147 -0
- package/test/routes/verts/selection.test.js +237 -0
- package/test/routes/verts/serve.test.js +185 -0
- package/test/routes/verts/unit-document.test.js +117 -0
- package/test/rules/_environment.js +66 -0
- package/test/rules/brand-merge.test.js +195 -0
- package/test/rules/field-helpers.test.js +309 -0
- package/test/rules/notifications.test.js +577 -0
- package/test/rules/payments-carts.test.js +406 -0
- package/test/rules/sessions.test.js +170 -0
- package/test/rules/user.test.js +517 -0
- package/test/rules/verts.test.js +101 -0
- package/test/security/fetch-log-secrets.test.js +124 -0
- package/test/security/primitives.test.js +105 -0
- package/test/security/repo-pinning.test.js +77 -0
- package/test/stripe-live/subscription-lifecycle.test.js +141 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test: a Chargebee webhook the Chargebee API cannot answer writes NOTHING
|
|
3
|
+
*
|
|
4
|
+
* The trigger used to degrade to the payload the webhook carried (flagged stale)
|
|
5
|
+
* whenever the provider lookup failed, and wrote real subscription state from it —
|
|
6
|
+
* an object supplied by whoever posted the event
|
|
7
|
+
* ([#506](https://github.com/Omega-JS-Stack/omega/issues/506)). An unreachable
|
|
8
|
+
* provider is not a provider saying anything at all, so the event now DEFERS: the
|
|
9
|
+
* doc is marked failed, the retry sweep re-pends it, and no user doc, order or
|
|
10
|
+
* intent is written off the payload in the meantime.
|
|
11
|
+
*
|
|
12
|
+
* Chargebee is unconfigured in this brand (no CHARGEBEE_API_KEY), so the lookup
|
|
13
|
+
* fails for real, locally, with no network call and no credential.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
// The suite's own seeded persona ([#406](https://github.com/Omega-JS-Stack/omega/issues/406)):
|
|
17
|
+
// exclusive to this suite, declared in the seed roster, and the half the seed
|
|
18
|
+
// owns here is the AUTH USER — the doc is deleted below on purpose, and proving
|
|
19
|
+
// nothing recreates it is the point.
|
|
20
|
+
|
|
21
|
+
const defineCases = require('../../../dist/vendor/devkit/test/define-cases.js');
|
|
22
|
+
const PERSONA = 'webhook-chargebee-unreachable';
|
|
23
|
+
const ORDER_ID = '6161-6161-6161';
|
|
24
|
+
|
|
25
|
+
module.exports = defineCases({
|
|
26
|
+
description: 'A Chargebee lookup that cannot be answered defers instead of processing the payload',
|
|
27
|
+
type: 'suite',
|
|
28
|
+
timeout: 60000,
|
|
29
|
+
|
|
30
|
+
tests: [
|
|
31
|
+
{
|
|
32
|
+
name: 'send-chargebee-subscription-webhook',
|
|
33
|
+
async run({ accounts, http, firestore, assert, state, config }) {
|
|
34
|
+
state.uid = accounts[PERSONA].uid;
|
|
35
|
+
|
|
36
|
+
// Deleted so the run starts from nothing: anything found afterwards was
|
|
37
|
+
// written by this event, off a payload nothing verified
|
|
38
|
+
await firestore.delete(`users/${state.uid}`);
|
|
39
|
+
await firestore.delete(`payments-orders/${ORDER_ID}`);
|
|
40
|
+
|
|
41
|
+
state.orderId = ORDER_ID;
|
|
42
|
+
state.resourceId = `_test-cb-unreachable-sub-${Date.now()}`;
|
|
43
|
+
state.eventId = `_test-evt-cb-unreachable-${Date.now()}`;
|
|
44
|
+
state.termEnd = Math.floor(Date.now() / 1000) + 86400 * 30;
|
|
45
|
+
|
|
46
|
+
const response = await http.as('none').post(`backend-manager/payments/webhook?provider=chargebee&key=${config.webhookKey}`, {
|
|
47
|
+
id: state.eventId,
|
|
48
|
+
occurred_at: Math.floor(Date.now() / 1000),
|
|
49
|
+
event_type: 'subscription_created',
|
|
50
|
+
content: {
|
|
51
|
+
subscription: {
|
|
52
|
+
id: state.resourceId,
|
|
53
|
+
customer_id: '_test-cb-unreachable-cust',
|
|
54
|
+
status: 'active',
|
|
55
|
+
current_term_start: Math.floor(Date.now() / 1000),
|
|
56
|
+
current_term_end: state.termEnd,
|
|
57
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
58
|
+
started_at: Math.floor(Date.now() / 1000),
|
|
59
|
+
subscription_items: [{ item_price_id: 'premium-monthly', item_type: 'plan', quantity: 1 }],
|
|
60
|
+
meta_data: JSON.stringify({ uid: state.uid, orderId: ORDER_ID }),
|
|
61
|
+
currency_code: 'USD',
|
|
62
|
+
object: 'subscription',
|
|
63
|
+
},
|
|
64
|
+
customer: {
|
|
65
|
+
id: '_test-cb-unreachable-cust',
|
|
66
|
+
email: '_test.cb-unreachable@example.com',
|
|
67
|
+
object: 'customer',
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// The ROUTE still accepts it — storing the event is what makes the retry
|
|
73
|
+
// ladder possible at all. The processing is what refuses to guess.
|
|
74
|
+
assert.isSuccess(response, 'Webhook should be accepted');
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
{
|
|
79
|
+
name: 'the-event-defers-and-nothing-is-written-from-its-payload',
|
|
80
|
+
async run({ firestore, assert, waitFor, state }) {
|
|
81
|
+
// 45s, not the usual 15s: this is the first suite of the run and the emulator
|
|
82
|
+
// is still draining the seeding wipe, which stretches the read back out
|
|
83
|
+
await waitFor(async () => {
|
|
84
|
+
const doc = await firestore.get(`payments-webhooks/${state.eventId}`);
|
|
85
|
+
return doc?.status === 'completed' || doc?.status === 'failed';
|
|
86
|
+
}, 45000, 500);
|
|
87
|
+
|
|
88
|
+
const webhookDoc = await firestore.get(`payments-webhooks/${state.eventId}`);
|
|
89
|
+
|
|
90
|
+
assert.equal(webhookDoc.status, 'failed', 'An unreachable Chargebee defers — the retry sweep is the reconciliation path');
|
|
91
|
+
assert.equal(webhookDoc.retryCount, 1, 'The attempt is counted toward the retry ladder');
|
|
92
|
+
assert.ok(!webhookDoc.refusal, 'A deferral is not a refusal — nothing was decided about this event');
|
|
93
|
+
|
|
94
|
+
// The payload carried a complete active subscription. Anything below that
|
|
95
|
+
// exists could only have come from it.
|
|
96
|
+
const userDoc = await firestore.get(`users/${state.uid}`);
|
|
97
|
+
|
|
98
|
+
assert.ok(!userDoc?.subscription, 'No subscription state is written from a payload the provider never confirmed');
|
|
99
|
+
|
|
100
|
+
const orderDoc = await firestore.get(`payments-orders/${ORDER_ID}`);
|
|
101
|
+
|
|
102
|
+
assert.ok(!orderDoc, 'And no order is minted behind it');
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
});
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test: a persisted discount belongs to the subscription it was applied to
|
|
3
|
+
* ([#333](https://github.com/Omega-JS-Stack/omega/issues/333)).
|
|
4
|
+
*
|
|
5
|
+
* The winback claim writes `users/{uid}.subscription.discount` and nothing ever
|
|
6
|
+
* cleared it. The unified webhook write carries no discount key at all, so the
|
|
7
|
+
* merge PRESERVES the node forever, and a customer who churns and resubscribes
|
|
8
|
+
* carried `source: 'winback'` into the new subscription, where the billing
|
|
9
|
+
* card's pitch gate reads it as "already claimed" and silently never offers the
|
|
10
|
+
* save again, though the backend would grant a fresh one.
|
|
11
|
+
*
|
|
12
|
+
* The claim stamps the subscription it discounted (`discount.resourceId`), so
|
|
13
|
+
* the pipeline can tell the two apart: a webhook for a DIFFERENT subscription is
|
|
14
|
+
* a new subscription, and a new subscription is a clean slate.
|
|
15
|
+
*
|
|
16
|
+
* Plain-node control-flow test (no emulator, no network): the real trigger runs
|
|
17
|
+
* against the shared in-memory Firestore stand-in, which is what lets one test
|
|
18
|
+
* start from an exact prior account state (a live claim stamped with a
|
|
19
|
+
* subscription that is already gone) without minting a persona and a payment
|
|
20
|
+
* history per permutation.
|
|
21
|
+
*/
|
|
22
|
+
const assert = require('node:assert');
|
|
23
|
+
const { runTrigger } = require('./_webhook-harness.js');
|
|
24
|
+
const defineCases = require('../../../dist/vendor/devkit/test/define-cases.js');
|
|
25
|
+
|
|
26
|
+
const UID = '_test-discount-clear-uid';
|
|
27
|
+
const ORDER_ID = '5252-5252-5252';
|
|
28
|
+
const OLD_RESOURCE_ID = '_test-discount-old-sub';
|
|
29
|
+
const NEW_RESOURCE_ID = '_test-discount-new-sub';
|
|
30
|
+
const EVENT_ID = '_test-discount-evt';
|
|
31
|
+
|
|
32
|
+
/** The claimed winback discount, as the apply route persists it */
|
|
33
|
+
function claimedDiscount(resourceId) {
|
|
34
|
+
return {
|
|
35
|
+
valid: true,
|
|
36
|
+
code: 'WINBACK50',
|
|
37
|
+
percent: 50,
|
|
38
|
+
amount: 0,
|
|
39
|
+
duration: 'once',
|
|
40
|
+
source: 'winback',
|
|
41
|
+
resourceId: resourceId,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** A subscriber whose account already carries `discount`, on the subscription `resourceId` */
|
|
46
|
+
function subscriberSeed(discount, resourceId) {
|
|
47
|
+
return {
|
|
48
|
+
[`users/${UID}`]: {
|
|
49
|
+
auth: { uid: UID, email: `${UID}@example.com` },
|
|
50
|
+
subscription: {
|
|
51
|
+
product: { id: 'premium', name: 'Premium' },
|
|
52
|
+
status: 'active',
|
|
53
|
+
payment: { provider: 'test', orderId: ORDER_ID, resourceId: resourceId },
|
|
54
|
+
...(discount ? { discount: discount } : {}),
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** A subscription event for `resourceId`, over an account seeded with `seed` */
|
|
61
|
+
function runEvent({ resourceId, seed }) {
|
|
62
|
+
return runTrigger({
|
|
63
|
+
uid: UID,
|
|
64
|
+
orderId: ORDER_ID,
|
|
65
|
+
resourceId: resourceId,
|
|
66
|
+
eventId: EVENT_ID,
|
|
67
|
+
seed: seed,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
module.exports = defineCases({
|
|
72
|
+
description: 'Webhook pipeline clears a discount the new subscription never claimed',
|
|
73
|
+
type: 'group',
|
|
74
|
+
timeout: 30000,
|
|
75
|
+
|
|
76
|
+
tests: [
|
|
77
|
+
{
|
|
78
|
+
name: 'a resubscribe clears the discount claimed on the subscription that ended',
|
|
79
|
+
|
|
80
|
+
async run() {
|
|
81
|
+
const { store } = await runEvent({
|
|
82
|
+
resourceId: NEW_RESOURCE_ID,
|
|
83
|
+
seed: subscriberSeed(claimedDiscount(OLD_RESOURCE_ID), OLD_RESOURCE_ID),
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const subscription = store.get(`users/${UID}`).subscription;
|
|
87
|
+
|
|
88
|
+
assert.equal(subscription.payment.resourceId, NEW_RESOURCE_ID, 'the new subscription is the one on the account');
|
|
89
|
+
assert.equal(subscription.discount.valid, false, 'the old claim is no longer a discount');
|
|
90
|
+
assert.equal(subscription.discount.code, null, 'nothing names a coupon that ended with the old subscription');
|
|
91
|
+
assert.equal(subscription.discount.percent, 0, 'and it is worth nothing');
|
|
92
|
+
assert.equal(subscription.discount.amount, 0, 'in either shape');
|
|
93
|
+
assert.equal(subscription.discount.duration, null);
|
|
94
|
+
assert.equal(
|
|
95
|
+
subscription.discount.source, null,
|
|
96
|
+
'source is the pitch gate: left at winback, this customer is never offered the save again',
|
|
97
|
+
);
|
|
98
|
+
assert.equal(subscription.discount.resourceId, null, 'and the stamp goes with it');
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
{
|
|
103
|
+
name: 'same-subscription traffic PRESERVES the discount riding it',
|
|
104
|
+
|
|
105
|
+
async run() {
|
|
106
|
+
const discount = claimedDiscount(OLD_RESOURCE_ID);
|
|
107
|
+
const { store } = await runEvent({
|
|
108
|
+
resourceId: OLD_RESOURCE_ID,
|
|
109
|
+
seed: subscriberSeed(discount, OLD_RESOURCE_ID),
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
assert.deepEqual(
|
|
113
|
+
store.get(`users/${UID}`).subscription.discount, discount,
|
|
114
|
+
'a renewal, a cancellation, any update to the SAME subscription leaves the saving exactly as claimed',
|
|
115
|
+
);
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
{
|
|
120
|
+
name: 'an unstamped legacy discount is kept, and adopted by the subscription it is on',
|
|
121
|
+
|
|
122
|
+
async run() {
|
|
123
|
+
// A node written before the stamp existed names no subscription, and
|
|
124
|
+
// nothing can prove it belongs to an older one. Keeping it is the safe
|
|
125
|
+
// read: an account that resubscribed before this shipped keeps a stale
|
|
126
|
+
// claim it already had, and no live discount is ever taken away from
|
|
127
|
+
// someone paying a discounted price. Stamping it now is what ends that:
|
|
128
|
+
// from this event on it is a normal node, and the NEXT resubscribe
|
|
129
|
+
// clears it like any other.
|
|
130
|
+
const legacy = claimedDiscount(OLD_RESOURCE_ID);
|
|
131
|
+
delete legacy.resourceId;
|
|
132
|
+
|
|
133
|
+
const { store } = await runEvent({
|
|
134
|
+
resourceId: OLD_RESOURCE_ID,
|
|
135
|
+
seed: subscriberSeed(legacy, OLD_RESOURCE_ID),
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const discount = store.get(`users/${UID}`).subscription.discount;
|
|
139
|
+
|
|
140
|
+
assert.equal(discount.valid, true, 'the discount survives');
|
|
141
|
+
assert.equal(discount.code, 'WINBACK50', 'unchanged');
|
|
142
|
+
assert.equal(discount.source, 'winback', 'source and all');
|
|
143
|
+
assert.equal(discount.resourceId, OLD_RESOURCE_ID, 'and it now names the subscription it is riding');
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
{
|
|
148
|
+
name: 'a subscription-category event riding an invoice resource never clears the claim',
|
|
149
|
+
|
|
150
|
+
async run() {
|
|
151
|
+
// A subscription-CATEGORY event can carry a non-subscription resource
|
|
152
|
+
// (Stripe charge.refunded rides an invoice; PayPal's raw-payload
|
|
153
|
+
// fallback rides a sale). Its id will never match the stamp, so without
|
|
154
|
+
// the resourceType gate a partial refund on a still-live discounted
|
|
155
|
+
// subscription would silently clear a saving the customer still gets.
|
|
156
|
+
const discount = claimedDiscount(OLD_RESOURCE_ID);
|
|
157
|
+
const { store } = await runTrigger({
|
|
158
|
+
uid: UID,
|
|
159
|
+
orderId: ORDER_ID,
|
|
160
|
+
resourceId: '_test-discount-invoice-id',
|
|
161
|
+
resourceType: 'invoice',
|
|
162
|
+
eventId: EVENT_ID,
|
|
163
|
+
seed: subscriberSeed(discount, OLD_RESOURCE_ID),
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
assert.deepEqual(
|
|
167
|
+
store.get(`users/${UID}`).subscription.discount, discount,
|
|
168
|
+
'only a real subscription resource may judge the stamp',
|
|
169
|
+
);
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
|
|
173
|
+
{
|
|
174
|
+
name: 'an account with no discount is left with none',
|
|
175
|
+
|
|
176
|
+
async run() {
|
|
177
|
+
const { store } = await runEvent({
|
|
178
|
+
resourceId: NEW_RESOURCE_ID,
|
|
179
|
+
seed: subscriberSeed(null, OLD_RESOURCE_ID),
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
assert.equal(
|
|
183
|
+
store.get(`users/${UID}`).subscription.discount, undefined,
|
|
184
|
+
'the pipeline never writes a discount node onto an account that has none',
|
|
185
|
+
);
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test: a failed webhook closes out its checkout intent
|
|
3
|
+
*
|
|
4
|
+
* The webhook trigger resolves the orderId partway through processing, so anything
|
|
5
|
+
* that throws before that point (an unresolvable UID, a fetchResource failure) used
|
|
6
|
+
* to leave payments-intents/{orderId} at 'pending' forever — a checkout the user
|
|
7
|
+
* started that nothing ever closes.
|
|
8
|
+
*
|
|
9
|
+
* The failure path now resolves the orderId from what IS available (the webhook
|
|
10
|
+
* payload the provider library can read one out of) and fails the intent with it.
|
|
11
|
+
*/
|
|
12
|
+
const powertools = require('node-powertools');
|
|
13
|
+
const defineCases = require('../../../dist/vendor/devkit/test/define-cases.js');
|
|
14
|
+
|
|
15
|
+
const ORDER_ID = '9119-9119-9119';
|
|
16
|
+
|
|
17
|
+
module.exports = defineCases({
|
|
18
|
+
description: 'Webhook failure closes out its payments-intent',
|
|
19
|
+
type: 'suite',
|
|
20
|
+
timeout: 30000,
|
|
21
|
+
|
|
22
|
+
tests: [
|
|
23
|
+
{
|
|
24
|
+
name: 'seed-pending-intent',
|
|
25
|
+
async run({ firestore, assert, state }) {
|
|
26
|
+
const now = powertools.timestamp(new Date(), { output: 'string' });
|
|
27
|
+
|
|
28
|
+
state.orderId = ORDER_ID;
|
|
29
|
+
state.resourceId = `_test-sub-no-uid-${Date.now()}`;
|
|
30
|
+
state.eventId = `_test-evt-no-uid-${Date.now()}`;
|
|
31
|
+
|
|
32
|
+
await firestore.set(`payments-intents/${ORDER_ID}`, {
|
|
33
|
+
id: ORDER_ID,
|
|
34
|
+
status: 'pending',
|
|
35
|
+
provider: 'test',
|
|
36
|
+
metadata: {
|
|
37
|
+
created: {
|
|
38
|
+
timestamp: now,
|
|
39
|
+
timestampUNIX: powertools.timestamp(now, { output: 'unix' }),
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const intentDoc = await firestore.get(`payments-intents/${ORDER_ID}`);
|
|
45
|
+
assert.equal(intentDoc.status, 'pending', 'Intent should start pending');
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
{
|
|
50
|
+
name: 'send-webhook-with-no-uid',
|
|
51
|
+
async run({ http, assert, state, config }) {
|
|
52
|
+
// Carries the orderId but no uid, and names a subscription no order was ever
|
|
53
|
+
// written for — so nothing can reconstruct the uid and processing throws
|
|
54
|
+
const response = await http.as('none').post(`backend-manager/payments/webhook?provider=test&key=${config.webhookKey}`, {
|
|
55
|
+
id: state.eventId,
|
|
56
|
+
type: 'customer.subscription.updated',
|
|
57
|
+
data: {
|
|
58
|
+
object: {
|
|
59
|
+
id: state.resourceId,
|
|
60
|
+
object: 'subscription',
|
|
61
|
+
status: 'active',
|
|
62
|
+
metadata: { orderId: state.orderId },
|
|
63
|
+
cancel_at_period_end: false,
|
|
64
|
+
current_period_end: Math.floor(Date.now() / 1000) + 86400,
|
|
65
|
+
current_period_start: Math.floor(Date.now() / 1000),
|
|
66
|
+
start_date: Math.floor(Date.now() / 1000),
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
assert.isSuccess(response, 'Webhook should be accepted (it fails during processing, not at the door)');
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
{
|
|
76
|
+
name: 'webhook-fails-and-intent-is-failed',
|
|
77
|
+
async run({ firestore, assert, state, waitFor }) {
|
|
78
|
+
await waitFor(async () => {
|
|
79
|
+
const doc = await firestore.get(`payments-webhooks/${state.eventId}`);
|
|
80
|
+
return doc?.status === 'failed';
|
|
81
|
+
}, 15000, 500);
|
|
82
|
+
|
|
83
|
+
const webhookDoc = await firestore.get(`payments-webhooks/${state.eventId}`);
|
|
84
|
+
assert.match(webhookDoc.error, /no UID/i, 'The webhook should have failed on the unresolvable UID');
|
|
85
|
+
|
|
86
|
+
// The point: the intent no longer hangs pending behind that failure
|
|
87
|
+
const intentDoc = await firestore.get(`payments-intents/${state.orderId}`);
|
|
88
|
+
assert.equal(intentDoc.status, 'failed', 'The intent should be marked failed, not left pending');
|
|
89
|
+
assert.ok(intentDoc.error, 'The intent should carry the failure reason');
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
});
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test: the hosted page is consulted BEFORE a payload uid is believed
|
|
3
|
+
*
|
|
4
|
+
* A Chargebee hosted-page checkout does not forward `meta_data` to the
|
|
5
|
+
* subscription, so the provider's record carries no uid and the payload's claim
|
|
6
|
+
* steers with a loud warn ([#509](https://github.com/Omega-JS-Stack/omega/issues/509)).
|
|
7
|
+
* But Chargebee DOES hold a second authoritative source for exactly those
|
|
8
|
+
* subscriptions — the hosted page's `pass_thru_content` — and the lookup that
|
|
9
|
+
* reads it was gated on `!uid`, so it was consulted only when the payload claimed
|
|
10
|
+
* nothing: never in the one case where a claim needed checking
|
|
11
|
+
* ([#533](https://github.com/Omega-JS-Stack/omega/issues/533)).
|
|
12
|
+
*
|
|
13
|
+
* The lookup runs first now. A hit STEERS — and a payload that disagrees with it
|
|
14
|
+
* is refused, the same refusal a mismatched record earns. A miss still falls back
|
|
15
|
+
* to the payload with the warn: the scan covers only the last 25 hosted pages, so
|
|
16
|
+
* "no page found" honestly means "not in the window", never "not this uid".
|
|
17
|
+
*
|
|
18
|
+
* Plain-node control-flow test (no emulator, no network): the real trigger module
|
|
19
|
+
* runs against the shared in-memory Firestore stand-in (_webhook-harness.js).
|
|
20
|
+
* Chargebee's credentials + HTTP call are the one thing stubbed — the transport
|
|
21
|
+
* boundary. Everything inward runs for real.
|
|
22
|
+
*
|
|
23
|
+
* Run: npx omega test backend:events/payments/webhook-hosted-page-uid-trust
|
|
24
|
+
*/
|
|
25
|
+
const assert = require('node:assert');
|
|
26
|
+
const { runTrigger } = require('./_webhook-harness.js');
|
|
27
|
+
const Chargebee = require('../../../dist/manager/libraries/payment/providers/chargebee.js');
|
|
28
|
+
const defineCases = require('../../../dist/vendor/devkit/test/define-cases.js');
|
|
29
|
+
|
|
30
|
+
// The subscriber the hosted page says bought this subscription
|
|
31
|
+
const OWNER_UID = '_test-hosted-page-owner';
|
|
32
|
+
const OWNER_ORDER_ID = '5331-5331-5331';
|
|
33
|
+
|
|
34
|
+
// The uid a forged event claims for it, and the order it names
|
|
35
|
+
const FORGED_UID = '_test-hosted-page-forged';
|
|
36
|
+
const FORGED_ORDER_ID = '5330-5330-5330';
|
|
37
|
+
|
|
38
|
+
const SUBSCRIPTION_ID = 'cb_sub_hosted_page';
|
|
39
|
+
const EVENT_ID = '_test-hosted-page-evt';
|
|
40
|
+
|
|
41
|
+
const HOSTED_PAGES = '/hosted_pages?limit=25&sort_by[desc]=created_at';
|
|
42
|
+
|
|
43
|
+
/** Run fn with Chargebee's credentials + HTTP call replaced by stand-ins */
|
|
44
|
+
async function withChargebeeAnswering(request, fn) {
|
|
45
|
+
const realInit = Chargebee.init;
|
|
46
|
+
const realRequest = Chargebee.request;
|
|
47
|
+
|
|
48
|
+
Chargebee.init = () => ({ apiKey: '_test', site: '_test', baseUrl: 'https://_test.chargebee.com/api/v2' });
|
|
49
|
+
Chargebee.request = request;
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
return await fn();
|
|
53
|
+
} finally {
|
|
54
|
+
Chargebee.init = realInit;
|
|
55
|
+
Chargebee.request = realRequest;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** A stand-in that records every endpoint asked for and answers from `responses` */
|
|
60
|
+
function requestReturning(responses, calls) {
|
|
61
|
+
return async (endpoint) => {
|
|
62
|
+
calls.push(endpoint);
|
|
63
|
+
|
|
64
|
+
const response = responses[endpoint];
|
|
65
|
+
|
|
66
|
+
if (!response) {
|
|
67
|
+
const error = new Error(`Chargebee API 404: no stand-in response for ${endpoint}`);
|
|
68
|
+
error.statusCode = 404;
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return JSON.parse(JSON.stringify(response));
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** The hosted-page checkout's subscription: active, and carrying no meta_data at all */
|
|
77
|
+
function subscriptionRecord() {
|
|
78
|
+
const nowUNIX = Math.floor(Date.now() / 1000);
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
subscription: {
|
|
82
|
+
id: SUBSCRIPTION_ID,
|
|
83
|
+
status: 'active',
|
|
84
|
+
started_at: nowUNIX,
|
|
85
|
+
current_term_end: nowUNIX + 86400,
|
|
86
|
+
subscription_items: [{ item_price_id: 'premium-monthly' }],
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** The last 25 hosted pages, holding the one whose pass_thru_content names the owner */
|
|
92
|
+
function hostedPages({ matching = true } = {}) {
|
|
93
|
+
return {
|
|
94
|
+
list: [
|
|
95
|
+
{
|
|
96
|
+
hosted_page: {
|
|
97
|
+
id: 'hp_test_hosted_page',
|
|
98
|
+
content: { subscription: { id: matching ? SUBSCRIPTION_ID : 'cb_sub_someone_else' } },
|
|
99
|
+
pass_thru_content: JSON.stringify({ uid: OWNER_UID, orderId: OWNER_ORDER_ID }),
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* A hosted-page subscription event claiming `payloadUid`, with the page either in
|
|
108
|
+
* the scan window or outside it
|
|
109
|
+
*/
|
|
110
|
+
function runHostedPageEvent({ payloadUid, payloadOrderId, inWindow = true, calls = [] }) {
|
|
111
|
+
const responses = {
|
|
112
|
+
[`/subscriptions/${SUBSCRIPTION_ID}`]: subscriptionRecord(),
|
|
113
|
+
[HOSTED_PAGES]: hostedPages({ matching: inWindow }),
|
|
114
|
+
// The backfill the pipeline fires after a hosted-page resolution
|
|
115
|
+
[`/customers/undefined`]: {},
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
return withChargebeeAnswering(requestReturning(responses, calls), () => runTrigger({
|
|
119
|
+
uid: payloadUid,
|
|
120
|
+
orderId: payloadOrderId,
|
|
121
|
+
resourceId: SUBSCRIPTION_ID,
|
|
122
|
+
eventId: EVENT_ID,
|
|
123
|
+
eventType: 'subscription_changed',
|
|
124
|
+
provider: 'chargebee',
|
|
125
|
+
raw: {
|
|
126
|
+
id: EVENT_ID,
|
|
127
|
+
event_type: 'subscription_changed',
|
|
128
|
+
content: { subscription: { id: SUBSCRIPTION_ID, meta_data: JSON.stringify({ uid: payloadUid, orderId: payloadOrderId }) } },
|
|
129
|
+
},
|
|
130
|
+
// Both uids are real accounts in this project — what is forged is the CLAIM
|
|
131
|
+
authUids: [OWNER_UID, FORGED_UID],
|
|
132
|
+
}));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
module.exports = defineCases({
|
|
136
|
+
description: 'A payload uid is checked against the hosted page before it is allowed to steer',
|
|
137
|
+
type: 'group',
|
|
138
|
+
timeout: 30000,
|
|
139
|
+
|
|
140
|
+
tests: [
|
|
141
|
+
{
|
|
142
|
+
name: 'a forged uid on a hosted-page subscription still in the window is refused',
|
|
143
|
+
|
|
144
|
+
async run() {
|
|
145
|
+
const calls = [];
|
|
146
|
+
const { store } = await runHostedPageEvent({ payloadUid: FORGED_UID, payloadOrderId: FORGED_ORDER_ID, calls });
|
|
147
|
+
|
|
148
|
+
assert.ok(calls.includes(HOSTED_PAGES), 'the second source is consulted exactly when the claim needs checking');
|
|
149
|
+
assert.ok(!store.get(`users/${FORGED_UID}`), 'the uid the caller chose never receives a subscription it did not buy');
|
|
150
|
+
assert.ok(!store.get(`users/${OWNER_UID}`), 'and the refusal acts on nobody, not even the real owner');
|
|
151
|
+
assert.ok(!store.get(`payments-orders/${FORGED_ORDER_ID}`), 'no order behind it either');
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
|
|
155
|
+
{
|
|
156
|
+
name: 'the refusal names the hosted page as the source it disagreed with',
|
|
157
|
+
|
|
158
|
+
async run() {
|
|
159
|
+
const { store, logs } = await runHostedPageEvent({ payloadUid: FORGED_UID, payloadOrderId: FORGED_ORDER_ID });
|
|
160
|
+
const event = store.get(`payments-webhooks/${EVENT_ID}`);
|
|
161
|
+
|
|
162
|
+
assert.equal(event.status, 'completed', 'no retry can make the payload agree — the event must not be redelivered forever');
|
|
163
|
+
assert.equal(event.refusal?.reason, 'uid-mismatch', 'it is the same refusal a mismatched record earns');
|
|
164
|
+
assert.equal(event.refusal?.payloadUid, FORGED_UID, 'the stamp names the uid the payload claimed');
|
|
165
|
+
assert.equal(event.refusal?.providerUid, OWNER_UID, 'and the uid Chargebee\'s hosted page carries');
|
|
166
|
+
assert.equal(event.refusal?.source, 'hosted-page', 'and which of Chargebee\'s records answered');
|
|
167
|
+
assert.match(logs.join('\n'), /UID MISMATCH/, 'the refusal is loud');
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
{
|
|
172
|
+
name: 'a subscription whose page has aged out of the window falls back, never refuses',
|
|
173
|
+
|
|
174
|
+
async run() {
|
|
175
|
+
// The scan covers the last 25 hosted pages: a null answer means "not in
|
|
176
|
+
// the window", not "not this uid". Refusing on it would break every
|
|
177
|
+
// hosted-page checkout older than 25 pages.
|
|
178
|
+
const { store, logs } = await runHostedPageEvent({ payloadUid: FORGED_UID, payloadOrderId: FORGED_ORDER_ID, inWindow: false });
|
|
179
|
+
|
|
180
|
+
assert.ok(!store.get(`payments-webhooks/${EVENT_ID}`)?.refusal, 'a miss is not a mismatch');
|
|
181
|
+
assert.equal(store.get(`users/${FORGED_UID}`)?.subscription?.status, 'active', 'the payload steers, as it did before');
|
|
182
|
+
assert.match(logs.join('\n'), /UID FALLBACK/, 'and the write that was never cross-checked is named out loud');
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
|
|
186
|
+
{
|
|
187
|
+
name: 'a payload uid the hosted page AGREES with steers, and brings its orderId',
|
|
188
|
+
|
|
189
|
+
async run() {
|
|
190
|
+
const { store } = await runHostedPageEvent({ payloadUid: OWNER_UID, payloadOrderId: OWNER_ORDER_ID });
|
|
191
|
+
|
|
192
|
+
assert.ok(!store.get(`payments-webhooks/${EVENT_ID}`)?.refusal, 'a claim the second source confirms is refused nothing');
|
|
193
|
+
assert.equal(store.get(`users/${OWNER_UID}`)?.subscription?.status, 'active', 'the subscription lands on the owner\'s doc');
|
|
194
|
+
assert.equal(store.get(`payments-orders/${OWNER_ORDER_ID}`)?.owner, OWNER_UID, 'and the order the hosted page names is written with it');
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
|
|
198
|
+
{
|
|
199
|
+
name: 'a payload claiming no uid at all still resolves from the hosted page',
|
|
200
|
+
|
|
201
|
+
async run() {
|
|
202
|
+
// The path this lookup was written for ([#347]) — unchanged.
|
|
203
|
+
const { store } = await runHostedPageEvent({ payloadUid: null, payloadOrderId: null });
|
|
204
|
+
const event = store.get(`payments-webhooks/${EVENT_ID}`);
|
|
205
|
+
|
|
206
|
+
assert.ok(!event.refusal, 'a payload that claims nothing contradicts nothing');
|
|
207
|
+
assert.equal(event.owner, OWNER_UID, 'the resolved uid is persisted on the event doc');
|
|
208
|
+
assert.equal(store.get(`users/${OWNER_UID}`)?.subscription?.status, 'active', 'and the subscription lands on it');
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
],
|
|
212
|
+
});
|