@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,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The user doc's BIRTH — the one shape a `users/{uid}` doc is created in, and
|
|
3
|
+
* the heal that recreates it when it went missing behind a real account.
|
|
4
|
+
*
|
|
5
|
+
* A doc is born at signup (auth:on-create). Out-of-sync states happen in the
|
|
6
|
+
* wild, so an auth user whose doc is gone gets it back at the next moment it is
|
|
7
|
+
* needed: sign-in ([#405](https://github.com/Omega-JS-Stack/omega/issues/405)).
|
|
8
|
+
* Both paths build the SAME record here — a heal that hand-rolled its own shape
|
|
9
|
+
* would drift from the one a signup writes the day either side changes.
|
|
10
|
+
*
|
|
11
|
+
* The opposite direction (a doc with no auth user) is never healed: the payment
|
|
12
|
+
* guards refuse it and the users migration cleans it up
|
|
13
|
+
* ([#399](https://github.com/Omega-JS-Stack/omega/issues/399)).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const _ = require('lodash');
|
|
17
|
+
const { getAuthUser } = require('./auth-user.js');
|
|
18
|
+
|
|
19
|
+
// metadata.tag the heal stamps, so a healed doc is findable in the database — it
|
|
20
|
+
// is the only tag that says "this account's doc was recreated after the fact".
|
|
21
|
+
const HEAL_TAG = 'auth:heal';
|
|
22
|
+
|
|
23
|
+
// How long after an account is created the heal stands down and leaves the first
|
|
24
|
+
// write to auth:on-create (which the signup route already polls for).
|
|
25
|
+
const SIGNUP_WINDOW_MS = 120000;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Whether a users/{uid} doc is a REAL user doc rather than residue
|
|
29
|
+
*
|
|
30
|
+
* `auth.uid` is what a birth writes and what nothing else does: auth:before-signin
|
|
31
|
+
* merge-writes activity onto users/{uid} on every sign-in, so a doc-less account
|
|
32
|
+
* already HAS a doc by the time a request arrives — one holding nothing but
|
|
33
|
+
* activity. Existence alone reads that as an account.
|
|
34
|
+
*
|
|
35
|
+
* @param {object|null} data - The doc data, or null when the doc does not exist
|
|
36
|
+
* @returns {boolean}
|
|
37
|
+
*/
|
|
38
|
+
function isUserDoc(data) {
|
|
39
|
+
return !!data?.auth?.uid;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Build the user doc for a Firebase Auth user record
|
|
44
|
+
*
|
|
45
|
+
* @param {object} Manager - The booted Manager (owns the User schema + Metadata)
|
|
46
|
+
* @param {object} user - The firebase-admin UserRecord the doc belongs to
|
|
47
|
+
* @param {string} tag - metadata.tag naming the seam writing it
|
|
48
|
+
* @returns {object} The complete user doc, ready to write
|
|
49
|
+
*/
|
|
50
|
+
function buildUserDoc({ Manager, user, tag }) {
|
|
51
|
+
const providerName = extractProviderName(user);
|
|
52
|
+
|
|
53
|
+
// Create user record using Manager.User() helper
|
|
54
|
+
const userRecord = Manager.User({
|
|
55
|
+
auth: {
|
|
56
|
+
uid: user.uid,
|
|
57
|
+
email: user.email,
|
|
58
|
+
},
|
|
59
|
+
personal: providerName ? {
|
|
60
|
+
name: providerName,
|
|
61
|
+
} : undefined,
|
|
62
|
+
}).properties;
|
|
63
|
+
|
|
64
|
+
// Add metadata tag (merge into existing metadata to preserve metadata.created from User schema)
|
|
65
|
+
const meta = Manager.Metadata().set({ tag: tag });
|
|
66
|
+
userRecord.metadata = { ...userRecord.metadata, ...meta };
|
|
67
|
+
|
|
68
|
+
// Stamp metadata.created from Firebase Auth's creationTime (the canonical account-creation
|
|
69
|
+
// moment) rather than the User schema's "now" — otherwise the doc lands a beat after Auth,
|
|
70
|
+
// and the OMEGA user migration reconciles every new signup against Auth on its next run.
|
|
71
|
+
const creationTime = user.metadata?.creationTime;
|
|
72
|
+
if (creationTime) {
|
|
73
|
+
const createdDate = new Date(creationTime);
|
|
74
|
+
userRecord.metadata.created = {
|
|
75
|
+
timestamp: createdDate.toISOString(),
|
|
76
|
+
timestampUNIX: Math.round(createdDate.getTime() / 1000),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return userRecord;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Recreate a missing user doc for a signed-in caller
|
|
85
|
+
*
|
|
86
|
+
* Idempotent: the write runs in a transaction, so whichever of the two writers
|
|
87
|
+
* arrives second finds the doc and leaves it alone. One doc per uid, never a
|
|
88
|
+
* duplicate account, whichever order the two land in:
|
|
89
|
+
* - on-create first → the transaction reads a real doc and writes nothing.
|
|
90
|
+
* - heal first → on-create's own "already exists" check skips it.
|
|
91
|
+
* The signup window below keeps that second order off a brand-new account
|
|
92
|
+
* entirely, so on-create's write stays the authoritative one for every real
|
|
93
|
+
* signup. Existing values win over the freshly generated schema defaults, so
|
|
94
|
+
* nothing already on the doc (before-signin's activity, an api key) is clobbered.
|
|
95
|
+
*
|
|
96
|
+
* @param {object} Manager - The booted Manager
|
|
97
|
+
* @param {object} ctx - The RouteContext to log through
|
|
98
|
+
* @param {object} admin - The firebase-admin app
|
|
99
|
+
* @param {string} uid - The uid whose doc is missing
|
|
100
|
+
* @returns {Promise<object|null>} The doc that now exists, or null when there was nothing to heal
|
|
101
|
+
*/
|
|
102
|
+
async function healUserDoc({ Manager, ctx, admin, uid }) {
|
|
103
|
+
// The auth user is the proof the doc SHOULD exist. A verified ID token outlives
|
|
104
|
+
// a deleted account by up to an hour, and recreating a doc for one would mint
|
|
105
|
+
// exactly the auth-less zombie the payment guards refuse (#399).
|
|
106
|
+
const authUser = await getAuthUser(admin, uid);
|
|
107
|
+
|
|
108
|
+
if (!authUser) {
|
|
109
|
+
ctx.warn(`Not healing users/${uid}: the ID token verifies but the account no longer exists in Auth`);
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Anonymous accounts get no user doc anywhere in the framework. The same rule
|
|
114
|
+
// auth:on-create applies, read off the same record — an account with no
|
|
115
|
+
// providerData at all is an anonymous sign-in.
|
|
116
|
+
if (isAnonymous(authUser)) {
|
|
117
|
+
ctx.log(`Not healing users/${uid}: anonymous accounts get no user doc`);
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// A signup still in flight belongs to auth:on-create, not here. Its write is
|
|
122
|
+
// what runs the consumer hook, and a heal that got there first would take that
|
|
123
|
+
// job away: on-create's own "already exists" check would then skip the account
|
|
124
|
+
// for good. Inside the window a
|
|
125
|
+
// doc-less caller is answered exactly as it was before the heal existed, and
|
|
126
|
+
// the signup route is already polling for the doc it is waiting on.
|
|
127
|
+
const age = accountAge(authUser);
|
|
128
|
+
|
|
129
|
+
if (age !== null && age < SIGNUP_WINDOW_MS) {
|
|
130
|
+
ctx.log(`Not healing users/${uid}: the account is ${Math.round(age / 1000)}s old, so auth:on-create still owns its first write`);
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const record = buildUserDoc({ Manager: Manager, user: authUser, tag: HEAL_TAG });
|
|
135
|
+
|
|
136
|
+
// A healed account signed up long ago, so its signup flow is long over. Leaving
|
|
137
|
+
// flags.signupProcessed false sends the next page load back through all of it
|
|
138
|
+
// (welcome emails, affiliate credit, marketing sync) against an established
|
|
139
|
+
// account. Stamped on the heal path ONLY — a real new signup still has that
|
|
140
|
+
// flow ahead of it, so what auth:on-create writes is unchanged.
|
|
141
|
+
// Assumes the residue the merge below preserves carries no flags of its own:
|
|
142
|
+
// existing values win there, so a doc-less account that somehow arrived with
|
|
143
|
+
// flags.signupProcessed=false would keep it. Nothing writes flags onto a
|
|
144
|
+
// doc-less account today (before-signin writes metadata + activity, nothing else).
|
|
145
|
+
record.flags = { ...record.flags, signupProcessed: true };
|
|
146
|
+
|
|
147
|
+
const ref = admin.firestore().doc(`users/${uid}`);
|
|
148
|
+
|
|
149
|
+
const result = await admin.firestore().runTransaction(async (transaction) => {
|
|
150
|
+
const snapshot = await transaction.get(ref);
|
|
151
|
+
const existing = snapshot.exists ? snapshot.data() : null;
|
|
152
|
+
|
|
153
|
+
// Somebody won the race — a doc that is already real is left exactly as it is
|
|
154
|
+
if (isUserDoc(existing)) {
|
|
155
|
+
return { doc: existing, wrote: false };
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Deepest-first: the schema-complete record, then whatever residue the doc
|
|
159
|
+
// already carries (real values win over defaults). _.merge mutates its first
|
|
160
|
+
// arg, so start from a fresh object.
|
|
161
|
+
const merged = _.merge({}, record, existing || {});
|
|
162
|
+
|
|
163
|
+
transaction.set(ref, merged);
|
|
164
|
+
|
|
165
|
+
return { doc: merged, wrote: true };
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
if (result.wrote) {
|
|
169
|
+
// Loud on purpose: a signed-in account with no doc is a database out of sync
|
|
170
|
+
// with Auth, and silence here would hide every one of them.
|
|
171
|
+
ctx.warn(`Healed users/${uid}: a verified caller had no user doc, so it was recreated from the Auth record (tag=${HEAL_TAG})`);
|
|
172
|
+
} else {
|
|
173
|
+
ctx.log(`No heal needed for users/${uid}: the doc was written while the heal was running`);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return result.doc;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Whether an Auth record is an anonymous sign-in, exactly as auth:on-create reads it
|
|
181
|
+
*
|
|
182
|
+
* An account with an EMPTY providerData qualifies: nothing federated and no
|
|
183
|
+
* password is what an anonymous sign-in leaves behind.
|
|
184
|
+
*
|
|
185
|
+
* @param {object} user - The firebase-admin UserRecord
|
|
186
|
+
* @returns {boolean}
|
|
187
|
+
*/
|
|
188
|
+
function isAnonymous(user) {
|
|
189
|
+
return !!user.providerData?.every((p) => p.providerId === 'anonymous');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* How long ago Firebase Auth created this account, in ms
|
|
194
|
+
*
|
|
195
|
+
* A future-dated creationTime (an imported record carrying a skewed clock) reads
|
|
196
|
+
* as in-window forever, so such an account is never healed. Assumed acceptable:
|
|
197
|
+
* that is the pre-heal status quo for it, and Auth stamps its own clock on every
|
|
198
|
+
* account created the normal way.
|
|
199
|
+
*
|
|
200
|
+
* @param {object} user - The firebase-admin UserRecord
|
|
201
|
+
* @returns {number|null} The age, or null when the record carries no usable
|
|
202
|
+
* creationTime — nothing to judge the signup window by, so the heal proceeds
|
|
203
|
+
*/
|
|
204
|
+
function accountAge(user) {
|
|
205
|
+
const created = new Date(user.metadata?.creationTime || '').getTime();
|
|
206
|
+
|
|
207
|
+
return Number.isNaN(created) ? null : Date.now() - created;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Extract first/last name from provider data (Google, Facebook, GitHub, etc.)
|
|
212
|
+
* Returns { first, last } or null if no name found
|
|
213
|
+
*/
|
|
214
|
+
function extractProviderName(user) {
|
|
215
|
+
// Try provider-specific displayName first, then top-level displayName
|
|
216
|
+
const displayName = user.providerData?.find(p =>
|
|
217
|
+
p.providerId !== 'password'
|
|
218
|
+
&& p.providerId !== 'anonymous'
|
|
219
|
+
&& p.displayName
|
|
220
|
+
)?.displayName || user.displayName;
|
|
221
|
+
|
|
222
|
+
if (!displayName) {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const parts = displayName.trim().split(/\s+/);
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
first: parts[0] || null,
|
|
230
|
+
last: parts.slice(1).join(' ') || null,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
module.exports = { buildUserDoc, healUserDoc, isUserDoc, extractProviderName, HEAL_TAG, SIGNUP_WINDOW_MS };
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* POST /admin/backup - Backup Firestore
|
|
3
|
+
* Admin-only endpoint to export Firestore to Cloud Storage
|
|
4
|
+
*/
|
|
5
|
+
const moment = require('moment');
|
|
6
|
+
const powertools = require('node-powertools');
|
|
7
|
+
const { Storage } = require('@google-cloud/storage');
|
|
8
|
+
|
|
9
|
+
const storage = new Storage();
|
|
10
|
+
|
|
11
|
+
module.exports = async ({ ctx, Manager, user, settings, analytics, libraries }) => {
|
|
12
|
+
const { admin } = libraries;
|
|
13
|
+
|
|
14
|
+
// Require authentication (allow in dev)
|
|
15
|
+
if (!user.authenticated && ctx.isProduction()) {
|
|
16
|
+
return ctx.respond('Authentication required', { code: 401 });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Require admin (allow in dev)
|
|
20
|
+
if (!user.roles.admin && ctx.isProduction()) {
|
|
21
|
+
return ctx.respond('Admin required.', { code: 403 });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Parse deletion regex if provided
|
|
25
|
+
settings.deletionRegex = settings.deletionRegex
|
|
26
|
+
? powertools.regexify(settings.deletionRegex)
|
|
27
|
+
: settings.deletionRegex;
|
|
28
|
+
|
|
29
|
+
// Setup Firestore Admin Client
|
|
30
|
+
const client = new admin.firestore.v1.FirestoreAdminClient({});
|
|
31
|
+
const projectId = Manager.project.projectId;
|
|
32
|
+
const resourceZone = Manager.project.resourceZone;
|
|
33
|
+
const databaseName = client.databasePath(projectId, '(default)');
|
|
34
|
+
const bucketName = `bm-backup-firestore-${projectId}`;
|
|
35
|
+
const bucketAddress = `gs://${bucketName}`;
|
|
36
|
+
|
|
37
|
+
// Ensure bucket exists
|
|
38
|
+
await createBucket(ctx, bucketName, resourceZone);
|
|
39
|
+
|
|
40
|
+
// Export documents
|
|
41
|
+
const result = await client.exportDocuments({
|
|
42
|
+
name: databaseName,
|
|
43
|
+
outputUriPrefix: bucketAddress,
|
|
44
|
+
collectionIds: [],
|
|
45
|
+
}).catch(async (e) => {
|
|
46
|
+
await setMetaStats(ctx, e);
|
|
47
|
+
return e;
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
if (result instanceof Error) {
|
|
51
|
+
return ctx.respond(result.message, { code: 500 });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const response = result[0];
|
|
55
|
+
|
|
56
|
+
ctx.log('Saved backup successfully:', response.metadata.outputUriPrefix);
|
|
57
|
+
|
|
58
|
+
await setMetaStats(ctx, null);
|
|
59
|
+
|
|
60
|
+
// Track analytics
|
|
61
|
+
analytics.event('admin/backup', { status: 'success' });
|
|
62
|
+
|
|
63
|
+
return ctx.respond({ name: response['name'] });
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// Helper: Set meta stats
|
|
67
|
+
async function setMetaStats(ctx, error) {
|
|
68
|
+
const { admin } = ctx.Manager.libraries;
|
|
69
|
+
const isError = error instanceof Error;
|
|
70
|
+
|
|
71
|
+
await admin.firestore().doc('meta/stats')
|
|
72
|
+
.set({
|
|
73
|
+
backups: {
|
|
74
|
+
lastBackup: {
|
|
75
|
+
date: {
|
|
76
|
+
timestamp: ctx.meta.startTime.timestamp,
|
|
77
|
+
timestampUNIX: ctx.meta.startTime.timestampUNIX,
|
|
78
|
+
},
|
|
79
|
+
status: {
|
|
80
|
+
success: !isError,
|
|
81
|
+
error: isError ? error.message : null,
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
metadata: ctx.Manager.Metadata().set({ tag: 'admin/backup' }),
|
|
86
|
+
}, { merge: true })
|
|
87
|
+
.catch(e => {
|
|
88
|
+
ctx.error('Failed to update meta stats', e);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Helper: Create bucket if it doesn't exist
|
|
93
|
+
async function createBucket(ctx, bucketName, resourceZone) {
|
|
94
|
+
try {
|
|
95
|
+
const meta = await storage.bucket(bucketName).getMetadata();
|
|
96
|
+
ctx.log(`${bucketName} metadata`, meta[0]);
|
|
97
|
+
} catch (e) {
|
|
98
|
+
// Bucket doesn't exist, create it
|
|
99
|
+
const result = await storage.createBucket(bucketName, {
|
|
100
|
+
location: resourceZone,
|
|
101
|
+
storageClass: 'COLDLINE',
|
|
102
|
+
}).catch(err => err);
|
|
103
|
+
|
|
104
|
+
ctx.log('storageCreation', result);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* POST /admin/cron - Run cron job manually
|
|
3
|
+
* Admin-only endpoint to trigger cron jobs
|
|
4
|
+
*/
|
|
5
|
+
module.exports = async ({ ctx, Manager, user, settings, analytics }) => {
|
|
6
|
+
|
|
7
|
+
// Require authentication (allow in dev)
|
|
8
|
+
if (!user.authenticated && ctx.isProduction()) {
|
|
9
|
+
return ctx.respond('Authentication required', { code: 401 });
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Require admin (allow in dev)
|
|
13
|
+
if (!user.roles.admin && ctx.isProduction()) {
|
|
14
|
+
return ctx.respond('Admin required.', { code: 403 });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Check for required parameter
|
|
18
|
+
if (!settings.id) {
|
|
19
|
+
return ctx.respond('Missing parameter {id}', { code: 400 });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
ctx.log('Running cron job:', settings.id);
|
|
23
|
+
|
|
24
|
+
// Run the cron job
|
|
25
|
+
const cronPath = `${Manager.rootDirectory}/events/cron/${settings.id}.js`;
|
|
26
|
+
const cronHandler = require(cronPath);
|
|
27
|
+
const result = await cronHandler({ Manager, ctx, context: {}, libraries: Manager.libraries }).catch(e => e);
|
|
28
|
+
|
|
29
|
+
if (result instanceof Error) {
|
|
30
|
+
return ctx.respond(result.message, { code: 500 });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Track analytics
|
|
34
|
+
analytics.event('admin/cron', { id: settings.id });
|
|
35
|
+
|
|
36
|
+
return ctx.respond(result);
|
|
37
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GET /admin/database - Read Realtime Database
|
|
3
|
+
* Admin-only endpoint to read any path
|
|
4
|
+
*/
|
|
5
|
+
module.exports = async ({ ctx, user, settings, libraries }) => {
|
|
6
|
+
const { admin } = libraries;
|
|
7
|
+
|
|
8
|
+
// Require authentication
|
|
9
|
+
if (!user.authenticated) {
|
|
10
|
+
return ctx.respond('Authentication required', { code: 401 });
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Require admin
|
|
14
|
+
if (!user.roles.admin) {
|
|
15
|
+
return ctx.respond('Admin required.', { code: 403 });
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Require path
|
|
19
|
+
if (!settings.path) {
|
|
20
|
+
return ctx.respond('Path parameter required.', { code: 400 });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
ctx.log('main(): Read', settings.path);
|
|
24
|
+
|
|
25
|
+
// Read from Realtime Database
|
|
26
|
+
const snapshot = await admin.database().ref(settings.path).once('value')
|
|
27
|
+
.catch((e) => e);
|
|
28
|
+
|
|
29
|
+
if (snapshot instanceof Error) {
|
|
30
|
+
return ctx.respond(snapshot.message, { code: 500 });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Return empty object if path doesn't exist (snapshot.val() returns null)
|
|
34
|
+
return ctx.respond(snapshot.val() || {});
|
|
35
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* POST /admin/database - Write Realtime Database
|
|
3
|
+
* Admin-only endpoint to write any path
|
|
4
|
+
*/
|
|
5
|
+
module.exports = async ({ ctx, user, settings, libraries }) => {
|
|
6
|
+
const { admin } = libraries;
|
|
7
|
+
|
|
8
|
+
// Require authentication
|
|
9
|
+
if (!user.authenticated) {
|
|
10
|
+
return ctx.respond('Authentication required', { code: 401 });
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Require admin
|
|
14
|
+
if (!user.roles.admin) {
|
|
15
|
+
return ctx.respond('Admin required.', { code: 403 });
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Require path
|
|
19
|
+
if (!settings.path) {
|
|
20
|
+
return ctx.respond('Path parameter required.', { code: 400 });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
ctx.log('main(): Write', settings.path, settings.document);
|
|
24
|
+
|
|
25
|
+
// Write to Realtime Database
|
|
26
|
+
const write = await admin.database().ref(settings.path).set(settings.document)
|
|
27
|
+
.catch((e) => e);
|
|
28
|
+
|
|
29
|
+
if (write instanceof Error) {
|
|
30
|
+
return ctx.respond(write.message, { code: 500 });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return ctx.respond(settings.document);
|
|
34
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* POST /admin/email - Send email via SendGrid
|
|
3
|
+
*
|
|
4
|
+
* Admin-only endpoint to send transactional emails.
|
|
5
|
+
* Supports flexible recipient formats (string, object, UID, or arrays of mixed).
|
|
6
|
+
*
|
|
7
|
+
* See: src/manager/libraries/email/ for the shared email builder and sender.
|
|
8
|
+
*/
|
|
9
|
+
const prepare = require('../../../libraries/email/prepare.js');
|
|
10
|
+
const env = require('../../../libraries/env.js');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* How many recipients a send carries, across to/cc/bcc.
|
|
14
|
+
*
|
|
15
|
+
* Each field is a string, an object, or an array of either — the count is all the log
|
|
16
|
+
* needs, so no address is ever read out of them.
|
|
17
|
+
*
|
|
18
|
+
* @param {object} settings - Caller-supplied send settings
|
|
19
|
+
* @returns {number} Total recipient entries
|
|
20
|
+
*/
|
|
21
|
+
function recipientCount(settings) {
|
|
22
|
+
return ['to', 'cc', 'bcc'].reduce((total, field) => {
|
|
23
|
+
const value = settings[field];
|
|
24
|
+
|
|
25
|
+
if (!value) {
|
|
26
|
+
return total;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return total + (Array.isArray(value) ? value.length : 1);
|
|
30
|
+
}, 0);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = async ({ ctx, user, settings }) => {
|
|
34
|
+
// Require authentication
|
|
35
|
+
if (!user.authenticated) {
|
|
36
|
+
return ctx.respond('Authentication required', { code: 401 });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Require admin
|
|
40
|
+
if (!user.roles.admin) {
|
|
41
|
+
return ctx.respond('Admin required.', { code: 403 });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// The raw-HTML fields are internal-caller only — this route (and the MCP
|
|
45
|
+
// send_email tool that calls it) sends markdown through the escaped lane.
|
|
46
|
+
const internalOnlyFault = prepare.internalOnlyFieldFault(settings);
|
|
47
|
+
|
|
48
|
+
if (internalOnlyFault) {
|
|
49
|
+
// Log the rejection so the attempt leaves a trace — the field name only, never
|
|
50
|
+
// the payload it tried to smuggle.
|
|
51
|
+
ctx.log(`Rejected: ${internalOnlyFault.message}`);
|
|
52
|
+
|
|
53
|
+
return ctx.respond(internalOnlyFault.message, { code: internalOnlyFault.code });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Check for SendGrid key
|
|
57
|
+
if (!env.has('SENDGRID_API_KEY')) {
|
|
58
|
+
return ctx.respond('SendGrid API key not configured.', { code: 500 });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Metadata only — never the payload. The full settings object carries every
|
|
62
|
+
// recipient address and the body itself, and this line lands in Cloud Logging where
|
|
63
|
+
// it outlives the send ([#127](https://github.com/Omega-JS-Stack/omega/issues/127)).
|
|
64
|
+
ctx.log(`Request: recipients=${recipientCount(settings)}, template=${settings.template}, subject=${settings.subject}`);
|
|
65
|
+
|
|
66
|
+
const email = ctx.Manager.Email(ctx);
|
|
67
|
+
const result = await email.send(settings).catch(e => e);
|
|
68
|
+
|
|
69
|
+
if (result instanceof Error) {
|
|
70
|
+
return ctx.respond(result.message, { code: result.code || 500 });
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return ctx.respond(result);
|
|
74
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GET /admin/firestore - Read Firestore document
|
|
3
|
+
* Admin-only endpoint to read any document
|
|
4
|
+
*/
|
|
5
|
+
module.exports = async ({ ctx, user, settings, libraries }) => {
|
|
6
|
+
const { admin } = libraries;
|
|
7
|
+
|
|
8
|
+
// Require authentication
|
|
9
|
+
if (!user.authenticated) {
|
|
10
|
+
return ctx.respond('Authentication required', { code: 401 });
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Require admin
|
|
14
|
+
if (!user.roles.admin) {
|
|
15
|
+
return ctx.respond('Admin required.', { code: 403 });
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Require path
|
|
19
|
+
if (!settings.path) {
|
|
20
|
+
return ctx.respond('Path parameter required.', { code: 400 });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
ctx.log('main(): Reading', settings.path);
|
|
24
|
+
|
|
25
|
+
// Read from Firestore
|
|
26
|
+
const doc = await admin.firestore().doc(settings.path).get()
|
|
27
|
+
.catch((e) => e);
|
|
28
|
+
|
|
29
|
+
if (doc instanceof Error) {
|
|
30
|
+
return ctx.respond(doc.message, { code: 500 });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Return empty object if document doesn't exist (doc.data() returns undefined)
|
|
34
|
+
return ctx.respond(doc.data() || {});
|
|
35
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const pushid = require('pushid');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* POST /admin/firestore - Write Firestore document
|
|
5
|
+
* Admin-only endpoint to write any document
|
|
6
|
+
*/
|
|
7
|
+
module.exports = async ({ ctx, Manager, user, settings, libraries }) => {
|
|
8
|
+
const { admin } = libraries;
|
|
9
|
+
|
|
10
|
+
// Require authentication
|
|
11
|
+
if (!user.authenticated) {
|
|
12
|
+
return ctx.respond('Authentication required', { code: 401 });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Require admin
|
|
16
|
+
if (!user.roles.admin) {
|
|
17
|
+
return ctx.respond('Admin required.', { code: 403 });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Require path
|
|
21
|
+
if (!settings.path) {
|
|
22
|
+
return ctx.respond('Path parameter required.', { code: 400 });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Process path placeholders
|
|
26
|
+
let path = settings.path;
|
|
27
|
+
|
|
28
|
+
if (path.includes('{pushId}')) {
|
|
29
|
+
path = path.replace(/\{pushId\}/gi, pushid());
|
|
30
|
+
} else if (path.includes('{nanoId}')) {
|
|
31
|
+
path = path.replace(/\{nanoId\}/gi, Manager.Utilities().randomId());
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Prepare document
|
|
35
|
+
const document = {
|
|
36
|
+
...settings.document,
|
|
37
|
+
metadata: Manager.Metadata().set({ tag: settings.metadataTag }),
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// Build options
|
|
41
|
+
const options = {
|
|
42
|
+
merge: settings.merge,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
ctx.log('main(): Writing', path, document, options);
|
|
46
|
+
|
|
47
|
+
// Write to Firestore
|
|
48
|
+
const write = await admin.firestore().doc(path).set(document, options)
|
|
49
|
+
.catch((e) => e);
|
|
50
|
+
|
|
51
|
+
if (write instanceof Error) {
|
|
52
|
+
return ctx.respond(write.message, { code: 500 });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return ctx.respond({ path });
|
|
56
|
+
};
|