@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,17 @@
|
|
|
1
|
+
# Project docs
|
|
2
|
+
|
|
3
|
+
Per-subsystem deep references live here. Keep `AGENTS.md` short — it should read as a **table of contents** that points at files in this directory.
|
|
4
|
+
|
|
5
|
+
## Pattern
|
|
6
|
+
|
|
7
|
+
When you find yourself adding more than a paragraph to `AGENTS.md`, create a new `docs/<topic>.md` instead and link to it from `AGENTS.md`. Goal: the project's `AGENTS.md` stays under ~250 lines (`CLAUDE.md` is only the one-line `@AGENTS.md` pointer).
|
|
8
|
+
|
|
9
|
+
Examples of good `docs/*.md` topics:
|
|
10
|
+
- Subsystem deep-dives (one per area of the codebase)
|
|
11
|
+
- Architectural decisions / "why we built it this way"
|
|
12
|
+
- Defaults tables, behavior matrices, edge cases
|
|
13
|
+
- Setup walkthroughs that don't belong in `README.md`
|
|
14
|
+
|
|
15
|
+
## See also
|
|
16
|
+
|
|
17
|
+
`node_modules/@omega.js/AGENTS.md` is the OMEGA map — follow it to `docs/backend/index.md`, the framework's own overview.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Project tests
|
|
2
|
+
|
|
3
|
+
This project has **two test lanes**, both scaffolded by the OMEGA verbs.
|
|
4
|
+
|
|
5
|
+
| Lane | Command | What it is |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| Static | `npm test` (= `npm run test:static`) | Plain `node --test` over `test/_unit/**/*.test.js`. **Socket-free**: `test/_helpers/connect-trap.js` is preloaded into every test process and turns any TCP connect or DNS lookup into a throw. No emulator, no network, no credentials — seconds to run. |
|
|
8
|
+
| Emulator | `npm run test:emulator` (= `npx omega test`) | Everything below: your suites, and the framework's, against a **real Firebase emulator**. |
|
|
9
|
+
|
|
10
|
+
## The static lane (`test/_unit/`)
|
|
11
|
+
|
|
12
|
+
The `_` prefix is load-bearing: the framework's test discovery skips `_`-prefixed paths, so these suites never run inside the emulator lane. Three skeletons ship with the project and are YOURS to extend:
|
|
13
|
+
|
|
14
|
+
| File | Pins |
|
|
15
|
+
|---|---|
|
|
16
|
+
| `_unit/registration.test.js` | `src/index.js` boots the framework that is actually installed; every route it dispatches to exists and its imports load (a broken require fails here, not at cold start) |
|
|
17
|
+
| `_unit/rules-posture.test.js` | Every Firestore/Storage path your rules open is declared in the suite — adding a rule is a deliberate act, not a diff nobody read |
|
|
18
|
+
| `_unit/socket-free.test.js` | The connect trap is loaded and refuses. Leave this one as shipped: without it, a lane that lost the `--require` flag would pass while reaching live Firebase |
|
|
19
|
+
|
|
20
|
+
A test that needs a real network client belongs in the emulator lane, which boots the environment it talks to. In the static lane, pass a stub.
|
|
21
|
+
|
|
22
|
+
## Layout (emulator lane)
|
|
23
|
+
|
|
24
|
+
Name every test file `<concern>.test.js` — the suffix is how the runner finds it, and a plain `.js` file under `test/` is support code that never runs. Match the framework's layout — OMEGA Backend's test runner discovers files by the directory they sit in. Mirror the same per-area split as the framework's own `test/` (see `node_modules/@omega.js/backend/test/`):
|
|
25
|
+
|
|
26
|
+
| Directory | Use for |
|
|
27
|
+
|---|---|
|
|
28
|
+
| `test/routes/` | Custom HTTP route handlers (`functions/routes/<verb>/<path>.js`) |
|
|
29
|
+
| `test/events/` | Pub/Sub / Firestore-trigger handlers |
|
|
30
|
+
| `test/helpers/` | Shared test utilities for your project |
|
|
31
|
+
| `test/fixtures/` | Static test data (JSON, sample docs) |
|
|
32
|
+
| `test/_init/` | Per-suite setup (Firestore seed data, user accounts) |
|
|
33
|
+
|
|
34
|
+
Tests run inside the Firebase emulator. Use the @omega.js/backend helpers (`ctx`, admin SDK, fixture loaders) instead of mocking — `npx omega emulator` boots the same environment the tests run against.
|
|
35
|
+
|
|
36
|
+
## Extended mode (real external APIs)
|
|
37
|
+
|
|
38
|
+
By default, tests skip REAL external services (SendGrid, OpenAI, Stripe webhooks, etc.) — the routes/libraries short-circuit in-source when not in extended mode. To exercise those paths for real, pass `--extended`:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npx omega test --extended # opt into real external APIs
|
|
42
|
+
TEST_EXTENDED_MODE=true npx omega test # identical — the env-var form
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`--extended` is the CLI shorthand for the shared, unprefixed `TEST_EXTENDED_MODE` env var standardized across @omega.js/backend/BXM/UJM/EM. @omega.js/backend propagates it to BOTH the test runner and the running emulator, so a single flag on the test command flips everything — no need to restart the emulator. Anything an extended test creates in an external system MUST be cleaned up by the test (the runner only wipes local Firestore/Auth).
|
|
46
|
+
|
|
47
|
+
## Coverage
|
|
48
|
+
|
|
49
|
+
Every feature ships with tests at every surface it exposes — logic (handler suites), wiring (route round-trips over `http.as(...)`), and rules (when Firestore rules change). Skip a surface only when the feature genuinely doesn't have one; "the handler test covers it" does not excuse the route round-trip.
|
|
50
|
+
|
|
51
|
+
## Quick example
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
// test/routes/hello.test.js
|
|
55
|
+
module.exports = {
|
|
56
|
+
'GET /hello returns ok': async ({ http }) => {
|
|
57
|
+
const res = await http.get('hello');
|
|
58
|
+
if (res.status !== 200) throw new Error('expected 200');
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## See also
|
|
64
|
+
|
|
65
|
+
The framework's own test suites at `node_modules/@omega.js/backend/test/` are the canonical reference for how each layer is structured.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test lifecycle hook for this project. Runs before any test (not a test itself).
|
|
3
|
+
* See @omega.js/backend/docs/test-framework.md → "test/_init.js".
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
module.exports = ({ config }) => ({
|
|
7
|
+
// Extra test accounts (one per lifecycle this project exercises):
|
|
8
|
+
// { id, uid, email, properties }. email may use the {domain} placeholder.
|
|
9
|
+
accounts: [],
|
|
10
|
+
|
|
11
|
+
// Seed fixtures into the freshly-flushed emulator, after accounts are created.
|
|
12
|
+
async setup({ admin, accounts }) {
|
|
13
|
+
},
|
|
14
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connect trap — the static lane's proof that no test opens a socket.
|
|
3
|
+
*
|
|
4
|
+
* Preloaded into EVERY test process by this target's `test` script
|
|
5
|
+
* (`node --require ./test/_helpers/connect-trap.js --test …`; node forwards the
|
|
6
|
+
* parent's execArgv to each test child, so one flag covers the whole lane).
|
|
7
|
+
*
|
|
8
|
+
* The static lane requires your real source: route handlers, schemas, the
|
|
9
|
+
* framework module itself. One require deeper than you think and that tree
|
|
10
|
+
* reaches firebase-admin's gRPC client — against whatever credentials `.env`
|
|
11
|
+
* and `.omega/secrets/` happen to carry for the REAL project. So the failure
|
|
12
|
+
* mode is made structural: the socket layer itself refuses, loudly, before any
|
|
13
|
+
* DNS lookup or TCP connect can happen.
|
|
14
|
+
*
|
|
15
|
+
* Everything that can open an outbound connection in Node funnels through
|
|
16
|
+
* `net.Socket.prototype.connect` — http/https agents, undici/fetch, gRPC
|
|
17
|
+
* (firebase-admin), and every fetch wrapper on top of them — so trapping that
|
|
18
|
+
* one method covers the lot. `dns.lookup` is trapped too, since a resolver call
|
|
19
|
+
* is already an escape even when the connect never happens.
|
|
20
|
+
*
|
|
21
|
+
* A test that legitimately needs a network client passes it a stub instead. A
|
|
22
|
+
* test that wants the real thing belongs in the EMULATOR lane
|
|
23
|
+
* (`npx omega test`), which boots the environment it talks to.
|
|
24
|
+
*/
|
|
25
|
+
const net = require('node:net');
|
|
26
|
+
const dns = require('node:dns');
|
|
27
|
+
|
|
28
|
+
const MARKER = '__omegaConnectTrap';
|
|
29
|
+
|
|
30
|
+
function refuse(what, detail) {
|
|
31
|
+
const error = new Error(
|
|
32
|
+
`connect-trap: ${what} was attempted in the static test lane (${detail}). `
|
|
33
|
+
+ 'This lane is socket-free by contract — stub the network client instead.',
|
|
34
|
+
);
|
|
35
|
+
error.code = 'CONNECT_TRAP';
|
|
36
|
+
return error;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function describe(target) {
|
|
40
|
+
if (!target) {
|
|
41
|
+
return 'unknown target';
|
|
42
|
+
}
|
|
43
|
+
if (typeof target === 'string' || typeof target === 'number') {
|
|
44
|
+
return String(target);
|
|
45
|
+
}
|
|
46
|
+
return `${target.host || target.path || 'unknown'}:${target.port || '?'}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Sockets — the one funnel every outbound protocol goes through.
|
|
50
|
+
const realConnect = net.Socket.prototype.connect;
|
|
51
|
+
net.Socket.prototype.connect = function connect(...args) {
|
|
52
|
+
throw refuse('a TCP connect', describe(args[0]));
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// Resolver — an escape in its own right, and it runs BEFORE the connect above.
|
|
56
|
+
const realLookup = dns.lookup;
|
|
57
|
+
dns.lookup = function lookup(hostname) {
|
|
58
|
+
throw refuse('a DNS lookup', String(hostname));
|
|
59
|
+
};
|
|
60
|
+
dns.promises.lookup = function lookup(hostname) {
|
|
61
|
+
throw refuse('a DNS lookup', String(hostname));
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// The proof handle: test/_unit/socket-free.test.js asserts this is present, so
|
|
65
|
+
// a lane that silently lost the --require flag fails instead of passing quietly.
|
|
66
|
+
globalThis[MARKER] = {
|
|
67
|
+
installed: true,
|
|
68
|
+
marker: MARKER,
|
|
69
|
+
// The originals are kept ONLY so the trap can describe what it replaced —
|
|
70
|
+
// nothing in the lane is allowed to put them back.
|
|
71
|
+
replaced: { connect: typeof realConnect, lookup: typeof realLookup },
|
|
72
|
+
};
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registration guard — what this target actually deploys, and whether every
|
|
3
|
+
* route it dispatches to still loads.
|
|
4
|
+
*
|
|
5
|
+
* The deployed surface is the FRAMEWORK's own (the `omega_*` functions
|
|
6
|
+
* `Manager.init(exports, {})` registers) PLUS whatever `src/index.js` exports.
|
|
7
|
+
* Nothing below is a hardcoded mirror of your tree:
|
|
8
|
+
*
|
|
9
|
+
* 1. The consumer functions and the route names they dispatch to are READ OUT
|
|
10
|
+
* OF `src/index.js` (as text), not listed here. A function you add there
|
|
11
|
+
* shows up in these assertions on its own.
|
|
12
|
+
* 2. For each route name index.js dispatches, the handler is resolved the way
|
|
13
|
+
* `Middleware.run()` resolves it — `<routesDir>/<name>/<method>.js`, method
|
|
14
|
+
* file first, `index.js` fallback — and then REQUIRED, so a broken import
|
|
15
|
+
* in a route (an ESM-only dependency, a moved util) fails HERE rather than
|
|
16
|
+
* at cold start in production.
|
|
17
|
+
*
|
|
18
|
+
* `src/index.js` is read as TEXT, never required — requiring it boots the
|
|
19
|
+
* Manager (Firebase Admin init, .env cascade, config load), which is exactly the
|
|
20
|
+
* runtime dependency this lane avoids. That nothing in any of these requires
|
|
21
|
+
* reaches the network is not taken on trust: the connect trap preloaded into
|
|
22
|
+
* this process (test/_helpers/connect-trap.js) throws on the first DNS lookup
|
|
23
|
+
* or TCP connect.
|
|
24
|
+
*
|
|
25
|
+
* Yours to extend: pin the resources a function needs (`runWith` memory and
|
|
26
|
+
* timeout), the rewrites your published API paths depend on, and the schema
|
|
27
|
+
* shape each route resolves. See `node_modules/@omega.js/backend/test/` for how
|
|
28
|
+
* the framework does each of those.
|
|
29
|
+
*
|
|
30
|
+
* node --require ./test/_helpers/connect-trap.js --test test/_unit/registration.test.js
|
|
31
|
+
*/
|
|
32
|
+
const assert = require('node:assert/strict');
|
|
33
|
+
const test = require('node:test');
|
|
34
|
+
const fs = require('node:fs');
|
|
35
|
+
const path = require('node:path');
|
|
36
|
+
|
|
37
|
+
const APP_DIR = path.join(__dirname, '..', '..');
|
|
38
|
+
const SRC = path.join(APP_DIR, 'src');
|
|
39
|
+
const INDEX = fs.readFileSync(path.join(SRC, 'index.js'), 'utf8');
|
|
40
|
+
const FIREBASE = JSON.parse(fs.readFileSync(path.join(APP_DIR, 'firebase.json'), 'utf8'));
|
|
41
|
+
|
|
42
|
+
const FRAMEWORK_DIR = path.dirname(require.resolve('@omega.js/backend/package.json', { paths: [APP_DIR] }));
|
|
43
|
+
|
|
44
|
+
// The prefixes the framework's own registrations occupy. A consumer export
|
|
45
|
+
// wearing one would silently overwrite a framework function, or be overwritten
|
|
46
|
+
// by it — either way something stops deploying.
|
|
47
|
+
const RESERVED_PREFIXES = ['omega_', 'bm_'];
|
|
48
|
+
|
|
49
|
+
// The HTTP verbs Middleware.run() looks for as `<route>/<method>.js`.
|
|
50
|
+
const METHOD_FILES = ['get.js', 'post.js', 'put.js', 'patch.js', 'delete.js'];
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The consumer Cloud Functions index.js registers, read out of the source:
|
|
54
|
+
* `exports.<name> = functions….run('<route>')`.
|
|
55
|
+
* @returns {Array<{name: string, route: string}>}
|
|
56
|
+
*/
|
|
57
|
+
function consumerFunctions() {
|
|
58
|
+
return [...INDEX.matchAll(/exports\.(\w+)\s*=([\s\S]*?);\n/g)].map((match) => ({
|
|
59
|
+
name: match[1],
|
|
60
|
+
route: (match[2].match(/\.run\(\s*'([^']+)'/) || [])[1],
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
test('index.js boots the framework from the package that is actually installed', () => {
|
|
65
|
+
assert.match(INDEX, /require\('@omega\.js\/backend'\)/, 'index.js does not boot @omega.js/backend');
|
|
66
|
+
assert.match(INDEX, /\.init\(exports,/, 'Manager.init(exports, …) is the bootstrap call');
|
|
67
|
+
|
|
68
|
+
// The specifier index.js requires, resolved the way NODE resolves it FROM
|
|
69
|
+
// src/ — the same lookup the deployed function performs at cold start. A
|
|
70
|
+
// renamed dependency, a missing workspace link or a `file:` path off by a
|
|
71
|
+
// directory all fail here instead of at boot.
|
|
72
|
+
const resolved = require.resolve('@omega.js/backend', { paths: [SRC] });
|
|
73
|
+
|
|
74
|
+
assert.ok(
|
|
75
|
+
resolved.startsWith(FRAMEWORK_DIR + path.sep),
|
|
76
|
+
`index.js's '@omega.js/backend' resolves to ${resolved}, outside the framework package`,
|
|
77
|
+
);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('no consumer function collides with the framework namespace', () => {
|
|
81
|
+
for (const fn of consumerFunctions()) {
|
|
82
|
+
for (const prefix of RESERVED_PREFIXES) {
|
|
83
|
+
assert.ok(
|
|
84
|
+
!fn.name.startsWith(prefix),
|
|
85
|
+
`exports.${fn.name} takes the framework's reserved "${prefix}" prefix — one of the two functions will not deploy`,
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('every route index.js dispatches to resolves and loads the way the middleware loads it', () => {
|
|
92
|
+
// Middleware.run() resolves `path.resolve(<routesDir>, <route>)` and then
|
|
93
|
+
// takes `<method>.js` if it exists, `index.js` otherwise. A function that
|
|
94
|
+
// does not dispatch through `.run()` carries its handler inline — nothing to
|
|
95
|
+
// resolve, so it is this test's business only if it names a route.
|
|
96
|
+
for (const fn of consumerFunctions().filter((f) => f.route)) {
|
|
97
|
+
const routeDir = path.resolve(SRC, 'routes', fn.route);
|
|
98
|
+
assert.ok(fs.existsSync(routeDir), `src/routes/${fn.route}/ does not exist — the route answers 500`);
|
|
99
|
+
|
|
100
|
+
const handlers = [...METHOD_FILES, 'index.js']
|
|
101
|
+
.map((file) => path.join(routeDir, file))
|
|
102
|
+
.filter((file) => fs.existsSync(file));
|
|
103
|
+
|
|
104
|
+
assert.ok(
|
|
105
|
+
handlers.length > 0,
|
|
106
|
+
`src/routes/${fn.route}/ has no <method>.js and no index.js — every request answers 405`,
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
// Requiring is the point: a route's own imports are exercised here instead
|
|
110
|
+
// of at cold start.
|
|
111
|
+
for (const file of handlers) {
|
|
112
|
+
const handler = require(file);
|
|
113
|
+
|
|
114
|
+
assert.equal(typeof handler, 'function', `${path.relative(APP_DIR, file)} does not export a handler function`);
|
|
115
|
+
assert.equal(handler.constructor.name, 'AsyncFunction', `${path.relative(APP_DIR, file)}'s handler is not async`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test('src/ is the authored tree, so firebase deploys the staged dist/', () => {
|
|
121
|
+
// `omega build` copies src/** → dist/** and firebase.json deploys dist/.
|
|
122
|
+
assert.equal(FIREBASE.functions[0].source, 'dist', 'functions deploy from the staged dist/, never src/');
|
|
123
|
+
assert.equal(FIREBASE.hosting.public, 'dist/public', 'hosting serves the staged public dir');
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test('the omega_api rewrite still serves the framework prefixes, first', () => {
|
|
127
|
+
const rewrites = FIREBASE.hosting.rewrites;
|
|
128
|
+
const api = rewrites.find((r) => r.function === 'omega_api');
|
|
129
|
+
|
|
130
|
+
assert.ok(api, 'no omega_api rewrite — every built-in route would 404');
|
|
131
|
+
|
|
132
|
+
// Firebase hosting glob groups match a WHOLE path, so `/omega/**` alone would
|
|
133
|
+
// not cover the bare `/omega` — each prefix is listed on its own as well.
|
|
134
|
+
const alternatives = api.source.replace(/^\{|\}$/g, '').split(',');
|
|
135
|
+
|
|
136
|
+
for (const prefix of ['/omega', '/omega/**']) {
|
|
137
|
+
assert.ok(alternatives.includes(prefix), `the ${prefix} path is not routed to omega_api`);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// The omega rewrite has to stay FIRST: hosting takes the first match, and a
|
|
141
|
+
// broader pattern above it would swallow the framework prefixes.
|
|
142
|
+
assert.equal(rewrites[0].function, 'omega_api', 'the omega_api rewrite is no longer first');
|
|
143
|
+
});
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rules-posture guard — every rule this brand opens is a rule someone reviewed.
|
|
3
|
+
*
|
|
4
|
+
* `firestore.rules` is YOUR half of the compiled model: `omega build` splices it
|
|
5
|
+
* together with the framework half into `dist/firestore.rules`, and that is what
|
|
6
|
+
* the emulator and `firebase deploy` read. A match block you add here widens (or
|
|
7
|
+
* tightens) real access to real user data, so this suite makes adding one a
|
|
8
|
+
* DELIBERATE act: list the path in `AUTHORED_FIRESTORE_PATHS` below, with a
|
|
9
|
+
* comment saying why it is open, or the suite goes red.
|
|
10
|
+
*
|
|
11
|
+
* Same deal for Storage: the scaffold denies every path, and each one you expose
|
|
12
|
+
* goes in `EXPOSED_STORAGE_PATHS`.
|
|
13
|
+
*
|
|
14
|
+
* Static + emulator-free: reads the rules FILES, compares text. Behavioral rules
|
|
15
|
+
* coverage (allow/deny against a real Firestore) lives in the emulator suite
|
|
16
|
+
* (`npx omega test`), which boots the database it asserts against.
|
|
17
|
+
*
|
|
18
|
+
* Lives under `_unit/` on purpose: the framework's test discovery skips
|
|
19
|
+
* `_`-prefixed paths, so this file runs in the static lane and never inside the
|
|
20
|
+
* emulator lane.
|
|
21
|
+
*
|
|
22
|
+
* node --require ./test/_helpers/connect-trap.js --test test/_unit/rules-posture.test.js
|
|
23
|
+
*/
|
|
24
|
+
const assert = require('node:assert/strict');
|
|
25
|
+
const test = require('node:test');
|
|
26
|
+
const fs = require('node:fs');
|
|
27
|
+
const path = require('node:path');
|
|
28
|
+
|
|
29
|
+
const APP_DIR = path.join(__dirname, '..', '..');
|
|
30
|
+
|
|
31
|
+
// ── Yours to fill in ────────────────────────────────────────────────────────
|
|
32
|
+
// Every collection path YOUR firestore.rules opens, and every Storage path you
|
|
33
|
+
// expose. Empty is the scaffold's posture: the framework half gates everything
|
|
34
|
+
// it owns and the default lock closes the rest.
|
|
35
|
+
//
|
|
36
|
+
// const AUTHORED_FIRESTORE_PATHS = [
|
|
37
|
+
// '/posts/{id}', // public blog posts — read-only to clients, admin writes
|
|
38
|
+
// ];
|
|
39
|
+
const AUTHORED_FIRESTORE_PATHS = [];
|
|
40
|
+
const EXPOSED_STORAGE_PATHS = [];
|
|
41
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
42
|
+
|
|
43
|
+
function read(file) {
|
|
44
|
+
return fs.readFileSync(path.join(APP_DIR, file), 'utf8');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Comments carry no posture — strip them before any rule text is read, so a
|
|
48
|
+
// commented-out example never counts as an open path.
|
|
49
|
+
function rulePaths(contents) {
|
|
50
|
+
const live = contents
|
|
51
|
+
.split('\n')
|
|
52
|
+
.map((line) => line.replace(/\/\/.*$/, ''))
|
|
53
|
+
.join('\n');
|
|
54
|
+
|
|
55
|
+
return [...live.matchAll(/match\s+(\/\S+)/g)].map((match) => match[1]);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
test('firestore.rules opens exactly the paths this brand declared', () => {
|
|
59
|
+
const authored = rulePaths(read('firestore.rules'))
|
|
60
|
+
// The scope opener every rules file carries, not a rule.
|
|
61
|
+
.filter((rulePath) => !rulePath.startsWith('/databases/'));
|
|
62
|
+
|
|
63
|
+
assert.deepEqual(
|
|
64
|
+
authored,
|
|
65
|
+
AUTHORED_FIRESTORE_PATHS,
|
|
66
|
+
'firestore.rules opens a path this suite does not declare — add it to AUTHORED_FIRESTORE_PATHS with the reason, or take the rule out',
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('storage.rules denies every path this brand has not exposed', () => {
|
|
71
|
+
const storage = read('storage.rules');
|
|
72
|
+
|
|
73
|
+
assert.ok(
|
|
74
|
+
/match \/\{allPaths=\*\*\} \{\s*\n\s*allow read, write: if false;/.test(storage),
|
|
75
|
+
'the storage deny-all default is gone — every path without its own rule is now open',
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
const exposed = rulePaths(storage)
|
|
79
|
+
.filter((rulePath) => !rulePath.startsWith('/b/') && rulePath !== '/{allPaths=**}');
|
|
80
|
+
|
|
81
|
+
assert.deepEqual(
|
|
82
|
+
exposed,
|
|
83
|
+
EXPOSED_STORAGE_PATHS,
|
|
84
|
+
'storage.rules exposes a path this suite does not declare — add it to EXPOSED_STORAGE_PATHS with the reason, or take the rule out',
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test('firebase.json reads the COMPILED firestore rules, not the source half', () => {
|
|
89
|
+
const firebase = JSON.parse(read('firebase.json'));
|
|
90
|
+
|
|
91
|
+
// `firestore.rules` here is source: on its own it carries none of the
|
|
92
|
+
// framework's gating. Pointed at directly, a deploy would ship whatever this
|
|
93
|
+
// file alone says — which for a fresh brand is nothing at all.
|
|
94
|
+
assert.equal(
|
|
95
|
+
firebase.firestore.rules,
|
|
96
|
+
'dist/firestore.rules',
|
|
97
|
+
'firestore rules no longer read the compiled artifact — the framework half is not being deployed',
|
|
98
|
+
);
|
|
99
|
+
assert.equal(firebase.database.rules, 'database.rules.json', 'the Realtime Database rules file moved');
|
|
100
|
+
assert.equal(firebase.storage.rules, 'storage.rules', 'the Storage rules file moved');
|
|
101
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The static lane's socket-free contract, asserted rather than assumed.
|
|
3
|
+
*
|
|
4
|
+
* `test/_helpers/connect-trap.js` is preloaded into every test process by the
|
|
5
|
+
* `test` script. If that flag is ever dropped from package.json, or node stops
|
|
6
|
+
* forwarding execArgv to test children, the rest of this lane would still pass
|
|
7
|
+
* — quietly able to reach the REAL Firebase project through the framework tree
|
|
8
|
+
* registration.test.js loads, with whatever credentials the environment happens
|
|
9
|
+
* to carry. This file is what turns that silent regression into a red test.
|
|
10
|
+
*
|
|
11
|
+
* Nothing here is yours to fill in: leave it as shipped.
|
|
12
|
+
*
|
|
13
|
+
* node --require ./test/_helpers/connect-trap.js --test test/_unit/socket-free.test.js
|
|
14
|
+
*/
|
|
15
|
+
const assert = require('node:assert/strict');
|
|
16
|
+
const test = require('node:test');
|
|
17
|
+
const net = require('node:net');
|
|
18
|
+
const dns = require('node:dns');
|
|
19
|
+
|
|
20
|
+
test('the connect trap is loaded in this test process', () => {
|
|
21
|
+
assert.ok(
|
|
22
|
+
globalThis.__omegaConnectTrap?.installed,
|
|
23
|
+
'the connect-trap preload is missing — the static lane can reach the network',
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('opening a TCP socket is refused', () => {
|
|
28
|
+
const socket = new net.Socket();
|
|
29
|
+
|
|
30
|
+
assert.throws(
|
|
31
|
+
() => socket.connect(443, 'firestore.googleapis.com'),
|
|
32
|
+
(e) => e.code === 'CONNECT_TRAP',
|
|
33
|
+
'a TCP connect went through — the live Firestore is one call away',
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('resolving a hostname is refused', () => {
|
|
38
|
+
assert.throws(
|
|
39
|
+
() => dns.lookup('firestore.googleapis.com', () => {}),
|
|
40
|
+
(e) => e.code === 'CONNECT_TRAP',
|
|
41
|
+
'a DNS lookup went through',
|
|
42
|
+
);
|
|
43
|
+
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const { isDisposable } = require('../../libraries/email/validation.js');
|
|
2
|
+
const { runAuthHook, resolveSignupLimit } = require('./utils.js');
|
|
3
|
+
|
|
4
|
+
const ERROR_TOO_MANY_ATTEMPTS = 'Unable to create account at this time. Please try again later.';
|
|
5
|
+
const ERROR_DISPOSABLE_EMAIL = 'This email domain is not allowed. Please use a different email address.';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* beforeUserCreated - Disposable email blocking + IP rate limiting
|
|
9
|
+
*
|
|
10
|
+
* User doc creation is handled by on-create.js (which fires for all user creations including Admin SDK).
|
|
11
|
+
*
|
|
12
|
+
* Why not create user doc here?
|
|
13
|
+
* - Admin SDK (used for tests) does NOT trigger beforeUserCreated
|
|
14
|
+
* - on-create fires for ALL user creations, making it more reliable
|
|
15
|
+
*
|
|
16
|
+
* Available parameters (1st gen):
|
|
17
|
+
*
|
|
18
|
+
* user (AuthUserRecord):
|
|
19
|
+
* uid, email, emailVerified, displayName, photoURL, phoneNumber, disabled,
|
|
20
|
+
* metadata: { creationTime, lastSignInTime },
|
|
21
|
+
* providerData: [{ uid, displayName, email, photoURL, providerId, phoneNumber }],
|
|
22
|
+
* passwordHash, passwordSalt, customClaims, tenantId, tokensValidAfterTime, multiFactor
|
|
23
|
+
*
|
|
24
|
+
* context (AuthEventContext):
|
|
25
|
+
* ipAddress, userAgent, locale, eventId, eventType, authType, resource, timestamp,
|
|
26
|
+
* additionalUserInfo: { providerId, profile, username, isNewUser, recaptchaScore, email, phoneNumber },
|
|
27
|
+
* credential: { providerId, signInMethod, claims, idToken, accessToken, refreshToken, expirationTime, secret } | null,
|
|
28
|
+
* emailType, smsType, params
|
|
29
|
+
*
|
|
30
|
+
* Note: recaptchaScore requires reCAPTCHA Enterprise (Google Cloud level), NOT the Firebase SMS fraud toggle.
|
|
31
|
+
* Note: credential tokens (idToken, accessToken, refreshToken) require opt-in via BlockingOptions.
|
|
32
|
+
*/
|
|
33
|
+
module.exports = async ({ Manager, ctx, user, context, libraries }) => {
|
|
34
|
+
const startTime = Date.now();
|
|
35
|
+
const { functions } = libraries;
|
|
36
|
+
const ipAddress = context.ipAddress || '';
|
|
37
|
+
|
|
38
|
+
// The UID and nothing else. The AuthUserRecord carries the email, the display
|
|
39
|
+
// name and the provider data, the AuthEventContext carries the IP, the user
|
|
40
|
+
// agent and the credential, and a backend line lands in Cloud Logging for the
|
|
41
|
+
// whole retention window — so none of it rides this line
|
|
42
|
+
// ([#657](https://github.com/Omega-JS-Stack/omega/issues/657)). Both stay
|
|
43
|
+
// reachable one level down, at debug.
|
|
44
|
+
ctx.log(`beforeCreate: ${user.uid}`);
|
|
45
|
+
ctx.debug(`beforeCreate: ${user.uid} record`, user, context);
|
|
46
|
+
|
|
47
|
+
// Block disposable email domains
|
|
48
|
+
if (isDisposable(user.email)) {
|
|
49
|
+
ctx.error(`beforeCreate: Blocked disposable email ${user.email}`);
|
|
50
|
+
|
|
51
|
+
throw new functions.auth.HttpsError('invalid-argument', ERROR_DISPOSABLE_EMAIL);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Skip rate limiting if no IP (shouldn't happen in production)
|
|
55
|
+
if (!ipAddress) {
|
|
56
|
+
ctx.log(`beforeCreate: No IP address, skipping rate limit check (${Date.now() - startTime}ms)`);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// IP rate limiting — an EXPLICIT keyed counter, never the caller's own
|
|
61
|
+
// ([#647](https://github.com/Omega-JS-Stack/omega/issues/647)). The limit is
|
|
62
|
+
// this backend's own `auth.signup.maxPerIpPerDay`, not a plan number: a
|
|
63
|
+
// signup gate is a security control and the caller has no account yet.
|
|
64
|
+
// consume() is the whole gate — check, count, write — so a refusal is a
|
|
65
|
+
// throw and there is nothing here to get half right.
|
|
66
|
+
const usage = Manager.Usage().attach(ctx, { log: true }).forKey(ipAddress);
|
|
67
|
+
const maxSignupsPerDay = resolveSignupLimit(Manager.config);
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
await usage.consume('signups', 1, { limit: maxSignupsPerDay });
|
|
71
|
+
} catch (e) {
|
|
72
|
+
// ONLY a rate limit is a rate limit. consume() also throws 500s — a
|
|
73
|
+
// Firestore outage, a feature the catalog does not define — and selling one
|
|
74
|
+
// of those as "too many signups from your IP" is a diagnosis nobody can act
|
|
75
|
+
// on, told to a user who did nothing wrong.
|
|
76
|
+
if (e.code !== 429) {
|
|
77
|
+
throw e;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
ctx.error(`beforeCreate: Too many signups from ${ipAddress} (limit ${maxSignupsPerDay}/day)`);
|
|
81
|
+
|
|
82
|
+
throw new functions.auth.HttpsError('resource-exhausted', ERROR_TOO_MANY_ATTEMPTS);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Run consumer hook (can throw HttpsError to block signup)
|
|
86
|
+
await runAuthHook('before-create', { Manager, ctx, user, context, libraries });
|
|
87
|
+
|
|
88
|
+
ctx.log(`beforeCreate: Completed for ${user.uid} (${Date.now() - startTime}ms)`);
|
|
89
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* beforeUserSignedIn - Update activity + send sign-in analytics
|
|
3
|
+
*
|
|
4
|
+
* This function fires on every sign-in (including right after account creation).
|
|
5
|
+
* It updates last activity and sends sign-in analytics.
|
|
6
|
+
*
|
|
7
|
+
* TODO: Add mailer.sync(uid) here with 1x/day rate limit to keep marketing
|
|
8
|
+
* contact data (name, country, subscription fields) fresh between sessions.
|
|
9
|
+
*
|
|
10
|
+
* Available parameters (1st gen):
|
|
11
|
+
*
|
|
12
|
+
* user (AuthUserRecord):
|
|
13
|
+
* uid, email, emailVerified, displayName, photoURL, phoneNumber, disabled,
|
|
14
|
+
* metadata: { creationTime, lastSignInTime },
|
|
15
|
+
* providerData: [{ uid, displayName, email, photoURL, providerId, phoneNumber }],
|
|
16
|
+
* passwordHash, passwordSalt, customClaims, tenantId, tokensValidAfterTime, multiFactor
|
|
17
|
+
*
|
|
18
|
+
* context (AuthEventContext):
|
|
19
|
+
* ipAddress, userAgent, locale, eventId, eventType, authType, resource, timestamp,
|
|
20
|
+
* additionalUserInfo: { providerId, profile, username, isNewUser, recaptchaScore, email, phoneNumber },
|
|
21
|
+
* credential: { providerId, signInMethod, claims, idToken, accessToken, refreshToken, expirationTime, secret } | null,
|
|
22
|
+
* emailType, smsType, params
|
|
23
|
+
*
|
|
24
|
+
* Note: recaptchaScore requires reCAPTCHA Enterprise (Google Cloud level), NOT the Firebase SMS fraud toggle.
|
|
25
|
+
* Note: credential tokens (idToken, accessToken, refreshToken) require opt-in via BlockingOptions.
|
|
26
|
+
*/
|
|
27
|
+
const { runAuthHook } = require('./utils.js');
|
|
28
|
+
|
|
29
|
+
module.exports = async ({ Manager, ctx, user, context, libraries }) => {
|
|
30
|
+
const startTime = Date.now();
|
|
31
|
+
const { admin } = libraries;
|
|
32
|
+
|
|
33
|
+
// The UID and nothing else. The AuthUserRecord carries the email, the display
|
|
34
|
+
// name and the provider data, the AuthEventContext carries the IP, the user
|
|
35
|
+
// agent and the credential, and a backend line lands in Cloud Logging for the
|
|
36
|
+
// whole retention window — so none of it rides this line
|
|
37
|
+
// ([#657](https://github.com/Omega-JS-Stack/omega/issues/657)). Both stay
|
|
38
|
+
// reachable one level down, at debug.
|
|
39
|
+
ctx.log(`beforeSignIn: ${user.uid}`);
|
|
40
|
+
ctx.debug(`beforeSignIn: ${user.uid} record`, user, context);
|
|
41
|
+
|
|
42
|
+
const now = new Date();
|
|
43
|
+
|
|
44
|
+
// Update last activity and geolocation
|
|
45
|
+
const update = await admin.firestore().doc(`users/${user.uid}`)
|
|
46
|
+
.set({
|
|
47
|
+
metadata: {
|
|
48
|
+
updated: {
|
|
49
|
+
timestamp: now.toISOString(),
|
|
50
|
+
timestampUNIX: Math.round(now.getTime() / 1000),
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
activity: {
|
|
54
|
+
geolocation: {
|
|
55
|
+
ip: context.ipAddress,
|
|
56
|
+
},
|
|
57
|
+
client: {
|
|
58
|
+
userAgent: context.userAgent,
|
|
59
|
+
language: context.locale,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
}, { merge: true })
|
|
63
|
+
.catch(e => e);
|
|
64
|
+
|
|
65
|
+
if (update instanceof Error) {
|
|
66
|
+
ctx.error(`beforeSignIn: Failed to update user ${user.uid}:`, update);
|
|
67
|
+
// Don't block sign-in for activity update failure
|
|
68
|
+
} else {
|
|
69
|
+
ctx.log(`beforeSignIn: Updated user activity`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Run consumer hook (can throw HttpsError to block sign-in)
|
|
73
|
+
await runAuthHook('before-signin', { Manager, ctx, user, context, libraries });
|
|
74
|
+
|
|
75
|
+
ctx.log(`beforeSignIn: Completed for ${user.uid} (${Date.now() - startTime}ms)`);
|
|
76
|
+
};
|