diff --git a/apps/backend/.env b/apps/backend/.env index 9aa8a0d8d..f9f2004bc 100644 --- a/apps/backend/.env +++ b/apps/backend/.env @@ -1,127 +1,127 @@ # Basic -NEXT_PUBLIC_STACK_API_URL=# the base URL of Stack's backend/API. For local development, this is `http://localhost:8102`; for the managed service, this is `https://api.hexclave.com`. -NEXT_PUBLIC_STACK_DASHBOARD_URL=# the URL of Stack's dashboard. For local development, this is `http://localhost:8101`; for the managed service, this is `https://app.hexclave.com`. -NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR=# set to true to enable local emulator-only behaviors (internal local emulator endpoints, read-only environment config overrides, and local emulator auth UX) -STACK_SECRET_SERVER_KEY=# a random, unguessable secret key generated by `pnpm generate-keys` +NEXT_PUBLIC_HEXCLAVE_API_URL=# the base URL of Stack's backend/API. For local development, this is `http://localhost:8102`; for the managed service, this is `https://api.hexclave.com`. +NEXT_PUBLIC_HEXCLAVE_DASHBOARD_URL=# the URL of Stack's dashboard. For local development, this is `http://localhost:8101`; for the managed service, this is `https://app.hexclave.com`. +NEXT_PUBLIC_HEXCLAVE_IS_LOCAL_EMULATOR=# set to true to enable local emulator-only behaviors (internal local emulator endpoints, read-only environment config overrides, and local emulator auth UX) +HEXCLAVE_SECRET_SERVER_KEY=# a random, unguessable secret key generated by `pnpm generate-keys` # seed script settings -STACK_SEED_INTERNAL_PROJECT_SIGN_UP_ENABLED=# true to enable user sign up to the dashboard when seeding -STACK_SEED_INTERNAL_PROJECT_OTP_ENABLED=# true to add OTP auth to the dashboard when seeding -STACK_SEED_INTERNAL_PROJECT_ALLOW_LOCALHOST=# true to allow running dashboard on the localhost, set this to true only in development -STACK_SEED_INTERNAL_PROJECT_OAUTH_PROVIDERS=# list of oauth providers to add to the dashboard when seeding, separated by comma, for example "github,google,facebook" -STACK_SEED_INTERNAL_PROJECT_USER_EMAIL=# default user added to the dashboard -STACK_SEED_INTERNAL_PROJECT_USER_PASSWORD=# default user's password, paired with STACK_SEED_INTERNAL_PROJECT_USER_EMAIL -STACK_SEED_INTERNAL_PROJECT_USER_INTERNAL_ACCESS=# if the default user has access to the internal dashboard project -STACK_SEED_INTERNAL_PROJECT_USER_GITHUB_ID=# add github oauth id to the default user -STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY=# default publishable client key for the internal project -STACK_INTERNAL_PROJECT_SECRET_SERVER_KEY=# default secret server key for the internal project -STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY=# default super secret admin key for the internal project +HEXCLAVE_SEED_INTERNAL_PROJECT_SIGN_UP_ENABLED=# true to enable user sign up to the dashboard when seeding +HEXCLAVE_SEED_INTERNAL_PROJECT_OTP_ENABLED=# true to add OTP auth to the dashboard when seeding +HEXCLAVE_SEED_INTERNAL_PROJECT_ALLOW_LOCALHOST=# true to allow running dashboard on the localhost, set this to true only in development +HEXCLAVE_SEED_INTERNAL_PROJECT_OAUTH_PROVIDERS=# list of oauth providers to add to the dashboard when seeding, separated by comma, for example "github,google,facebook" +HEXCLAVE_SEED_INTERNAL_PROJECT_USER_EMAIL=# default user added to the dashboard +HEXCLAVE_SEED_INTERNAL_PROJECT_USER_PASSWORD=# default user's password, paired with HEXCLAVE_SEED_INTERNAL_PROJECT_USER_EMAIL +HEXCLAVE_SEED_INTERNAL_PROJECT_USER_INTERNAL_ACCESS=# if the default user has access to the internal dashboard project +HEXCLAVE_SEED_INTERNAL_PROJECT_USER_GITHUB_ID=# add github oauth id to the default user +HEXCLAVE_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY=# default publishable client key for the internal project +HEXCLAVE_INTERNAL_PROJECT_SECRET_SERVER_KEY=# default secret server key for the internal project +HEXCLAVE_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY=# default super secret admin key for the internal project # OAuth mock provider settings -STACK_OAUTH_MOCK_URL=# enter the URL of the mock OAuth provider here. For local development, use `http://localhost:8114`. +HEXCLAVE_OAUTH_MOCK_URL=# enter the URL of the mock OAuth provider here. For local development, use `http://localhost:8114`. # OAuth shared keys # Can be set to MOCK to use mock OAuth providers -STACK_GITHUB_CLIENT_ID=# client -STACK_GITHUB_CLIENT_SECRET=# client secret -STACK_GOOGLE_CLIENT_ID=# client id -STACK_GOOGLE_CLIENT_SECRET=# client secret -STACK_MICROSOFT_CLIENT_ID=# client id -STACK_MICROSOFT_CLIENT_SECRET=# client secret -STACK_SPOTIFY_CLIENT_ID=# client id -STACK_SPOTIFY_CLIENT_SECRET=# client secret +HEXCLAVE_GITHUB_CLIENT_ID=# client +HEXCLAVE_GITHUB_CLIENT_SECRET=# client secret +HEXCLAVE_GOOGLE_CLIENT_ID=# client id +HEXCLAVE_GOOGLE_CLIENT_SECRET=# client secret +HEXCLAVE_MICROSOFT_CLIENT_ID=# client id +HEXCLAVE_MICROSOFT_CLIENT_SECRET=# client secret +HEXCLAVE_SPOTIFY_CLIENT_ID=# client id +HEXCLAVE_SPOTIFY_CLIENT_SECRET=# client secret -STACK_ALLOW_SHARED_OAUTH_ACCESS_TOKENS=# allow shared oauth provider to also use connected account access token, this should only be used for development and testing +HEXCLAVE_ALLOW_SHARED_OAUTH_ACCESS_TOKENS=# allow shared oauth provider to also use connected account access token, this should only be used for development and testing -STACK_DISABLE_PLAN_LIMITS=# set to "true" to bypass enforcement of Hexclave's own internal-tenancy plan limits (analytics_events, session_replays, emails_per_month, dashboard_admins seat cap, auth_users soft cap, analytics_timeout_seconds). Default unset/false preserves enforcement. Intended as a temporary cutover safety net while the plan-limits infrastructure rolls out — customer projects' own item APIs are unaffected by this flag. +HEXCLAVE_DISABLE_PLAN_LIMITS=# set to "true" to bypass enforcement of Hexclave's own internal-tenancy plan limits (analytics_events, session_replays, emails_per_month, dashboard_admins seat cap, auth_users soft cap, analytics_timeout_seconds). Default unset/false preserves enforcement. Intended as a temporary cutover safety net while the plan-limits infrastructure rolls out — customer projects' own item APIs are unaffected by this flag. # Email # For local development, you can spin up a local SMTP server like inbucket -STACK_EMAIL_HOST=# for local inbucket: 127.0.0.1 -STACK_EMAIL_PORT=# for local inbucket: 8129 -STACK_EMAIL_USERNAME=# for local inbucket: test -STACK_EMAIL_PASSWORD=# for local inbucket: none -STACK_EMAIL_SENDER=# for local inbucket: noreply@test.com -STACK_EMAILABLE_API_KEY=# Emailable API key for email validation, see https://emailable.com. Use a test key (starting with "test_") for local dev — it does not consume credits. Set to "disable_email_validation" to disable. +HEXCLAVE_EMAIL_HOST=# for local inbucket: 127.0.0.1 +HEXCLAVE_EMAIL_PORT=# for local inbucket: 8129 +HEXCLAVE_EMAIL_USERNAME=# for local inbucket: test +HEXCLAVE_EMAIL_PASSWORD=# for local inbucket: none +HEXCLAVE_EMAIL_SENDER=# for local inbucket: noreply@test.com +HEXCLAVE_EMAILABLE_API_KEY=# Emailable API key for email validation, see https://emailable.com. Use a test key (starting with "test_") for local dev — it does not consume credits. Set to "disable_email_validation" to disable. -STACK_DEFAULT_EMAIL_CAPACITY_PER_HOUR=# the number of emails a new project can send. Defaults to 200 +HEXCLAVE_DEFAULT_EMAIL_CAPACITY_PER_HOUR=# the number of emails a new project can send. Defaults to 200 # Email branching configuration # If you have multiple deployments of compute accessing the same DB or multiple copies of a DBs connected to compute (as # you would in preview/branching environments), you may want to either disable the auto-triggered email queue steps # (those that trigger whenever an email is sent, besides the cron job), or disable email sending as a whole. -STACK_EMAIL_BRANCHING_DISABLE_QUEUE_AUTO_TRIGGER=# set to 'true' to disable the automatic triggering of the email queue step. the cron job must call /email-queue-step to run the queue step. Most useful on production domains where you know the cron job will run on the correct deployment and you don't need the auto-trigger (which may be on the wrong deployment) -STACK_EMAIL_BRANCHING_DISABLE_QUEUE_SENDING=# set to 'true' to throw an error instead of sending emails in the email queue step. Most useful on development branches that have a copy of the production DB, but should not send any emails (as otherwise some emails could be sent twice) +HEXCLAVE_EMAIL_BRANCHING_DISABLE_QUEUE_AUTO_TRIGGER=# set to 'true' to disable the automatic triggering of the email queue step. the cron job must call /email-queue-step to run the queue step. Most useful on production domains where you know the cron job will run on the correct deployment and you don't need the auto-trigger (which may be on the wrong deployment) +HEXCLAVE_EMAIL_BRANCHING_DISABLE_QUEUE_SENDING=# set to 'true' to throw an error instead of sending emails in the email queue step. Most useful on development branches that have a copy of the production DB, but should not send any emails (as otherwise some emails could be sent twice) # Database # For local development: `docker run -it --rm -e POSTGRES_PASSWORD=password -p "8128:5432" postgres` -STACK_DATABASE_CONNECTION_STRING=# enter your connection string here. For local development: `postgres://postgres:PASSWORD-PLACEHOLDER--uqfEC1hmmv@localhost:8128/stackframe` +HEXCLAVE_DATABASE_CONNECTION_STRING=# enter your connection string here. For local development: `postgres://postgres:PASSWORD-PLACEHOLDER--uqfEC1hmmv@localhost:8128/stackframe` # Webhooks -STACK_SVIX_SERVER_URL=# For prod, leave it empty. For local development, use `http://localhost:8113` -STACK_SVIX_API_KEY=# enter the API key for the Svix webhook service here. Use `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NTUxNDA2MzksImV4cCI6MTk3MDUwMDYzOSwibmJmIjoxNjU1MTQwNjM5LCJpc3MiOiJzdml4LXNlcnZlciIsInN1YiI6Im9yZ18yM3JiOFlkR3FNVDBxSXpwZ0d3ZFhmSGlyTXUifQ.En8w77ZJWbd0qrMlHHupHUB-4cx17RfzFykseg95SUk` for local development +HEXCLAVE_SVIX_SERVER_URL=# For prod, leave it empty. For local development, use `http://localhost:8113` +HEXCLAVE_SVIX_API_KEY=# enter the API key for the Svix webhook service here. Use `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NTUxNDA2MzksImV4cCI6MTk3MDUwMDYzOSwibmJmIjoxNjU1MTQwNjM5LCJpc3MiOiJzdml4LXNlcnZlciIsInN1YiI6Im9yZ18yM3JiOFlkR3FNVDBxSXpwZ0d3ZFhmSGlyTXUifQ.En8w77ZJWbd0qrMlHHupHUB-4cx17RfzFykseg95SUk` for local development # S3 -STACK_S3_PUBLIC_ENDPOINT=# publicly accessible endpoint -STACK_S3_ENDPOINT=# S3 API endpoint URL (e.g., 'https://s3.amazonaws.com' for AWS or custom endpoint for S3-compatible services) -STACK_S3_REGION= -STACK_S3_ACCESS_KEY_ID= -STACK_S3_SECRET_ACCESS_KEY= -STACK_S3_BUCKET= -STACK_S3_PRIVATE_BUCKET= +HEXCLAVE_S3_PUBLIC_ENDPOINT=# publicly accessible endpoint +HEXCLAVE_S3_ENDPOINT=# S3 API endpoint URL (e.g., 'https://s3.amazonaws.com' for AWS or custom endpoint for S3-compatible services) +HEXCLAVE_S3_REGION= +HEXCLAVE_S3_ACCESS_KEY_ID= +HEXCLAVE_S3_SECRET_ACCESS_KEY= +HEXCLAVE_S3_BUCKET= +HEXCLAVE_S3_PRIVATE_BUCKET= # AWS configuration -STACK_AWS_REGION= -STACK_AWS_KMS_ENDPOINT= -STACK_AWS_ACCESS_KEY_ID= -STACK_AWS_SECRET_ACCESS_KEY= -STACK_AWS_VERCEL_OIDC_ROLE_ARN= +HEXCLAVE_AWS_REGION= +HEXCLAVE_AWS_KMS_ENDPOINT= +HEXCLAVE_AWS_ACCESS_KEY_ID= +HEXCLAVE_AWS_SECRET_ACCESS_KEY= +HEXCLAVE_AWS_VERCEL_OIDC_ROLE_ARN= # Upstash configuration -STACK_QSTASH_URL= -STACK_QSTASH_TOKEN= -STACK_QSTASH_CURRENT_SIGNING_KEY= -STACK_QSTASH_NEXT_SIGNING_KEY= +HEXCLAVE_QSTASH_URL= +HEXCLAVE_QSTASH_TOKEN= +HEXCLAVE_QSTASH_CURRENT_SIGNING_KEY= +HEXCLAVE_QSTASH_NEXT_SIGNING_KEY= # Email monitor -STACK_EMAIL_MONITOR_RESEND_EMAIL_API_KEY=# enter the resend poller api key here -STACK_EMAIL_MONITOR_RESEND_EMAIL_DOMAIN=# enter the resend domain that should receive the emails -STACK_EMAIL_MONITOR_PROJECT_ID=# enter the project id for the project that the email monitor will attempt to sign up for -STACK_EMAIL_MONITOR_PUBLISHABLE_CLIENT_KEY=# enter the publishable client key for email monitor to use when attempting a sign up -STACK_EMAIL_MONITOR_VERIFICATION_CALLBACK_URL=# enter a valid verification callback url for the project that the email monitor will attempt to sign up for -STACK_EMAIL_MONITOR_INBUCKET_API_URL=# enter a valid inbucket api url for the email monitor to check emails from in test mode -STACK_EMAIL_MONITOR_USE_INBUCKET=# enter true/false based on whether the email monitor should use inbucket or resend. Note that if this is set to true in prod, the email monitor will throw an error. -STACK_EMAIL_MONITOR_SECRET_TOKEN=# enter the secret token value needed for the request to the email monitor to be accepted +HEXCLAVE_EMAIL_MONITOR_RESEND_EMAIL_API_KEY=# enter the resend poller api key here +HEXCLAVE_EMAIL_MONITOR_RESEND_EMAIL_DOMAIN=# enter the resend domain that should receive the emails +HEXCLAVE_EMAIL_MONITOR_PROJECT_ID=# enter the project id for the project that the email monitor will attempt to sign up for +HEXCLAVE_EMAIL_MONITOR_PUBLISHABLE_CLIENT_KEY=# enter the publishable client key for email monitor to use when attempting a sign up +HEXCLAVE_EMAIL_MONITOR_VERIFICATION_CALLBACK_URL=# enter a valid verification callback url for the project that the email monitor will attempt to sign up for +HEXCLAVE_EMAIL_MONITOR_INBUCKET_API_URL=# enter a valid inbucket api url for the email monitor to check emails from in test mode +HEXCLAVE_EMAIL_MONITOR_USE_INBUCKET=# enter true/false based on whether the email monitor should use inbucket or resend. Note that if this is set to true in prod, the email monitor will throw an error. +HEXCLAVE_EMAIL_MONITOR_SECRET_TOKEN=# enter the secret token value needed for the request to the email monitor to be accepted # Clickhouse -STACK_CLICKHOUSE_URL=# URL of the Clickhouse instance -STACK_CLICKHOUSE_ADMIN_USER=# username of the admin account -STACK_CLICKHOUSE_ADMIN_PASSWORD=# password of the admin account -STACK_CLICKHOUSE_EXTERNAL_PASSWORD=# a randomly generated secure string. The user account will be created automatically +HEXCLAVE_CLICKHOUSE_URL=# URL of the Clickhouse instance +HEXCLAVE_CLICKHOUSE_ADMIN_USER=# username of the admin account +HEXCLAVE_CLICKHOUSE_ADMIN_PASSWORD=# password of the admin account +HEXCLAVE_CLICKHOUSE_EXTERNAL_PASSWORD=# a randomly generated secure string. The user account will be created automatically # Misc -STACK_ACCESS_TOKEN_EXPIRATION_TIME=# enter the expiration time for the access token here. Optional, don't specify it for default value -STACK_SETUP_ADMIN_GITHUB_ID=# enter the account ID of the admin user here, and after running the seed script they will be able to access the internal project in the Stack dashboard. Optional, don't specify it for default value +HEXCLAVE_ACCESS_TOKEN_EXPIRATION_TIME=# enter the expiration time for the access token here. Optional, don't specify it for default value +HEXCLAVE_SETUP_ADMIN_GITHUB_ID=# enter the account ID of the admin user here, and after running the seed script they will be able to access the internal project in the Stack dashboard. Optional, don't specify it for default value OTEL_EXPORTER_OTLP_ENDPOINT=# enter the OpenTelemetry endpoint here. Optional, default is `http://localhost:8131` -STACK_INTEGRATION_CLIENTS_CONFIG=# a list of oidc-provider clients for integrations. If not provided, disables integrations -STACK_FREESTYLE_API_KEY=# enter your freestyle.sh api key -STACK_VERCEL_SANDBOX_PROJECT_ID=# enter the project id for the vercel project that the vercel engine will use -STACK_VERCEL_SANDBOX_TEAM_ID=# enter the team id for the vercel project that the vercel engine will use -STACK_VERCEL_SANDBOX_TOKEN=# enter the token for the vercel project that the vercel engine will use -STACK_OPENAI_API_KEY=# enter your openai api key -STACK_FEATUREBASE_API_KEY=# enter your featurebase api key -STACK_STRIPE_SECRET_KEY=# enter your stripe api key -STACK_STRIPE_WEBHOOK_SECRET=# enter your stripe webhook secret -STACK_TELEGRAM_BOT_TOKEN= # enter you telegram bot token -STACK_TELEGRAM_CHAT_ID=# enter your telegram chat id +HEXCLAVE_INTEGRATION_CLIENTS_CONFIG=# a list of oidc-provider clients for integrations. If not provided, disables integrations +HEXCLAVE_FREESTYLE_API_KEY=# enter your freestyle.sh api key +HEXCLAVE_VERCEL_SANDBOX_PROJECT_ID=# enter the project id for the vercel project that the vercel engine will use +HEXCLAVE_VERCEL_SANDBOX_TEAM_ID=# enter the team id for the vercel project that the vercel engine will use +HEXCLAVE_VERCEL_SANDBOX_TOKEN=# enter the token for the vercel project that the vercel engine will use +HEXCLAVE_OPENAI_API_KEY=# enter your openai api key +HEXCLAVE_FEATUREBASE_API_KEY=# enter your featurebase api key +HEXCLAVE_STRIPE_SECRET_KEY=# enter your stripe api key +HEXCLAVE_STRIPE_WEBHOOK_SECRET=# enter your stripe webhook secret +HEXCLAVE_TELEGRAM_BOT_TOKEN= # enter you telegram bot token +HEXCLAVE_TELEGRAM_CHAT_ID=# enter your telegram chat id # Docs AI tool bundle -STACK_MINTLIFY_MCP_URL=# override the Mintlify MCP server used by the backend's AI docs tool bundle. Defaults to https://stackauth-e0affa27.mintlify.app/mcp +HEXCLAVE_MINTLIFY_MCP_URL=# override the Mintlify MCP server used by the backend's AI docs tool bundle. Defaults to https://stackauth-e0affa27.mintlify.app/mcp # MCP review tool (SpacetimeDB) -STACK_SPACETIMEDB_URI=# SpacetimeDB host URI; default empty (logging disabled) -STACK_SPACETIMEDB_DB_NAME=# SpacetimeDB database name -STACK_MCP_LOG_TOKEN=# shared secret gating the log_mcp_call reducer; must match EXPECTED_LOG_TOKEN in apps/internal-tool/spacetimedb/src/index.ts +HEXCLAVE_SPACETIMEDB_URI=# SpacetimeDB host URI; default empty (logging disabled) +HEXCLAVE_SPACETIMEDB_DB_NAME=# SpacetimeDB database name +HEXCLAVE_MCP_LOG_TOKEN=# shared secret gating the log_mcp_call reducer; must match EXPECTED_LOG_TOKEN in apps/internal-tool/spacetimedb/src/index.ts diff --git a/apps/backend/.env.development b/apps/backend/.env.development index 5372d1a9b..590173cf6 100644 --- a/apps/backend/.env.development +++ b/apps/backend/.env.development @@ -1,138 +1,138 @@ -NEXT_PUBLIC_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 -NEXT_PUBLIC_STACK_DASHBOARD_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}01 -NEXT_PUBLIC_STACK_HOSTED_HANDLER_DOMAIN_SUFFIX=.localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}09 -NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR=false -STACK_SERVER_SECRET=23-wuNpik0gIW4mruTz25rbIvhuuvZFrLOLtL7J4tyo +NEXT_PUBLIC_HEXCLAVE_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +NEXT_PUBLIC_HEXCLAVE_DASHBOARD_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}01 +NEXT_PUBLIC_HEXCLAVE_HOSTED_HANDLER_DOMAIN_SUFFIX=.localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}09 +NEXT_PUBLIC_HEXCLAVE_IS_LOCAL_EMULATOR=false +HEXCLAVE_SERVER_SECRET=23-wuNpik0gIW4mruTz25rbIvhuuvZFrLOLtL7J4tyo -STACK_CHANGELOG_URL=https://raw.githubusercontent.com/hexclave/hexclave/refs/heads/dev/CHANGELOG.md +HEXCLAVE_CHANGELOG_URL=https://raw.githubusercontent.com/hexclave/hexclave/refs/heads/dev/CHANGELOG.md -STACK_SEED_ENABLE_DUMMY_PROJECT=true -STACK_SEED_INTERNAL_PROJECT_SIGN_UP_ENABLED=true -STACK_SEED_INTERNAL_PROJECT_OTP_ENABLED=true -STACK_SEED_INTERNAL_PROJECT_ALLOW_LOCALHOST=true -STACK_SEED_INTERNAL_PROJECT_OAUTH_PROVIDERS=github,spotify,google,microsoft -STACK_SEED_INTERNAL_PROJECT_USER_GITHUB_ID=admin@example.com -STACK_SEED_INTERNAL_PROJECT_USER_INTERNAL_ACCESS=true -STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only -STACK_INTERNAL_PROJECT_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only -STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY=this-super-secret-admin-key-is-for-local-development-only +HEXCLAVE_SEED_ENABLE_DUMMY_PROJECT=true +HEXCLAVE_SEED_INTERNAL_PROJECT_SIGN_UP_ENABLED=true +HEXCLAVE_SEED_INTERNAL_PROJECT_OTP_ENABLED=true +HEXCLAVE_SEED_INTERNAL_PROJECT_ALLOW_LOCALHOST=true +HEXCLAVE_SEED_INTERNAL_PROJECT_OAUTH_PROVIDERS=github,spotify,google,microsoft +HEXCLAVE_SEED_INTERNAL_PROJECT_USER_GITHUB_ID=admin@example.com +HEXCLAVE_SEED_INTERNAL_PROJECT_USER_INTERNAL_ACCESS=true +HEXCLAVE_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +HEXCLAVE_INTERNAL_PROJECT_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only +HEXCLAVE_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY=this-super-secret-admin-key-is-for-local-development-only -STACK_OAUTH_MOCK_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}14 -STACK_TURNSTILE_SITEVERIFY_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}14/turnstile/siteverify +HEXCLAVE_OAUTH_MOCK_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}14 +HEXCLAVE_TURNSTILE_SITEVERIFY_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}14/turnstile/siteverify # Cloudflare Turnstile test keys — always-pass widgets, no real challenges # See https://developers.cloudflare.com/turnstile/troubleshooting/testing/ -NEXT_PUBLIC_STACK_BOT_CHALLENGE_SITE_KEY=1x00000000000000000000AA -NEXT_PUBLIC_STACK_BOT_CHALLENGE_INVISIBLE_SITE_KEY=1x00000000000000000000BB -STACK_TURNSTILE_SECRET_KEY=1x0000000000000000000000000000000AA +NEXT_PUBLIC_HEXCLAVE_BOT_CHALLENGE_SITE_KEY=1x00000000000000000000AA +NEXT_PUBLIC_HEXCLAVE_BOT_CHALLENGE_INVISIBLE_SITE_KEY=1x00000000000000000000BB +HEXCLAVE_TURNSTILE_SECRET_KEY=1x0000000000000000000000000000000AA # Set to true to disable Turnstile entirely in local development. # This skips invisible/visible bot challenge flow and removes the Turnstile risk penalty. -STACK_DISABLE_BOT_CHALLENGE=false +HEXCLAVE_DISABLE_BOT_CHALLENGE=false # Default behavior is to block sign-up if the visible challenge cannot be completed. # Flip this only when you intentionally want local sign-up to continue during Turnstile outages. -STACK_ALLOW_SIGN_UP_ON_VISIBLE_BOT_CHALLENGE_FAILURE=false +HEXCLAVE_ALLOW_SIGN_UP_ON_VISIBLE_BOT_CHALLENGE_FAILURE=false -STACK_GITHUB_CLIENT_ID=MOCK -STACK_GITHUB_CLIENT_SECRET=MOCK -STACK_GOOGLE_CLIENT_ID=MOCK -STACK_GOOGLE_CLIENT_SECRET=MOCK -STACK_MICROSOFT_CLIENT_ID=MOCK -STACK_MICROSOFT_CLIENT_SECRET=MOCK -STACK_SPOTIFY_CLIENT_ID=MOCK -STACK_SPOTIFY_CLIENT_SECRET=MOCK +HEXCLAVE_GITHUB_CLIENT_ID=MOCK +HEXCLAVE_GITHUB_CLIENT_SECRET=MOCK +HEXCLAVE_GOOGLE_CLIENT_ID=MOCK +HEXCLAVE_GOOGLE_CLIENT_SECRET=MOCK +HEXCLAVE_MICROSOFT_CLIENT_ID=MOCK +HEXCLAVE_MICROSOFT_CLIENT_SECRET=MOCK +HEXCLAVE_SPOTIFY_CLIENT_ID=MOCK +HEXCLAVE_SPOTIFY_CLIENT_SECRET=MOCK -STACK_ALLOW_SHARED_OAUTH_ACCESS_TOKENS=true +HEXCLAVE_ALLOW_SHARED_OAUTH_ACCESS_TOKENS=true # Default to enforcing plan limits in local dev so behavior matches prod. # Flip to "true" to bypass every Stack-Auth-internal plan-limit enforcement # site (e.g. session_replays, analytics_events, emails_per_month). See # apps/backend/src/lib/plan-entitlements.ts:arePlanLimitsEnforced. -STACK_DISABLE_PLAN_LIMITS=false +HEXCLAVE_DISABLE_PLAN_LIMITS=false -STACK_DATABASE_CONNECTION_STRING=postgres://postgres:PASSWORD-PLACEHOLDER--uqfEC1hmmv@localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}28/stackframe -STACK_DATABASE_REPLICA_CONNECTION_STRING=postgres://postgres:PASSWORD-PLACEHOLDER--uqfEC1hmmv@localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}34/stackframe -STACK_DATABASE_REPLICATION_WAIT_STRATEGY=pg-stat-replication +HEXCLAVE_DATABASE_CONNECTION_STRING=postgres://postgres:PASSWORD-PLACEHOLDER--uqfEC1hmmv@localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}28/stackframe +HEXCLAVE_DATABASE_REPLICA_CONNECTION_STRING=postgres://postgres:PASSWORD-PLACEHOLDER--uqfEC1hmmv@localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}34/stackframe +HEXCLAVE_DATABASE_REPLICATION_WAIT_STRATEGY=pg-stat-replication -STACK_EMAIL_HOST=127.0.0.1 -STACK_EMAIL_PORT=${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}29 -STACK_EMAIL_SECURE=false -STACK_EMAIL_USERNAME="does not matter, ignored by Inbucket" -STACK_EMAIL_PASSWORD="does not matter, ignored by Inbucket" -STACK_EMAIL_SENDER=noreply@example.com +HEXCLAVE_EMAIL_HOST=127.0.0.1 +HEXCLAVE_EMAIL_PORT=${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}29 +HEXCLAVE_EMAIL_SECURE=false +HEXCLAVE_EMAIL_USERNAME="does not matter, ignored by Inbucket" +HEXCLAVE_EMAIL_PASSWORD="does not matter, ignored by Inbucket" +HEXCLAVE_EMAIL_SENDER=noreply@example.com -STACK_ACCESS_TOKEN_EXPIRATION_TIME=60s +HEXCLAVE_ACCESS_TOKEN_EXPIRATION_TIME=60s -STACK_DEFAULT_EMAIL_CAPACITY_PER_HOUR=100000 +HEXCLAVE_DEFAULT_EMAIL_CAPACITY_PER_HOUR=100000 -STACK_SVIX_SERVER_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}13 -STACK_SVIX_API_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NTUxNDA2MzksImV4cCI6MTk3MDUwMDYzOSwibmJmIjoxNjU1MTQwNjM5LCJpc3MiOiJzdml4LXNlcnZlciIsInN1YiI6Im9yZ18yM3JiOFlkR3FNVDBxSXpwZ0d3ZFhmSGlyTXUifQ.En8w77ZJWbd0qrMlHHupHUB-4cx17RfzFykseg95SUk +HEXCLAVE_SVIX_SERVER_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}13 +HEXCLAVE_SVIX_API_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NTUxNDA2MzksImV4cCI6MTk3MDUwMDYzOSwibmJmIjoxNjU1MTQwNjM5LCJpc3MiOiJzdml4LXNlcnZlciIsInN1YiI6Im9yZ18yM3JiOFlkR3FNVDBxSXpwZ0d3ZFhmSGlyTXUifQ.En8w77ZJWbd0qrMlHHupHUB-4cx17RfzFykseg95SUk # Trusted reverse proxy for reading real client IP addresses. # Set to "vercel", "cloudflare", or leave empty/unset for no proxy trust. -STACK_TRUSTED_PROXY= +HEXCLAVE_TRUSTED_PROXY= -STACK_ARTIFICIAL_DEVELOPMENT_DELAY_MS=500 +HEXCLAVE_ARTIFICIAL_DEVELOPMENT_DELAY_MS=500 -STACK_ENABLE_HARDCODED_PASSKEY_CHALLENGE_FOR_TESTING=yes +HEXCLAVE_ENABLE_HARDCODED_PASSKEY_CHALLENGE_FOR_TESTING=yes -STACK_INTEGRATION_CLIENTS_CONFIG='[{"client_id": "neon-local", "client_secret": "neon-local-secret", "id_token_signed_response_alg": "ES256", "redirect_uris": ["http://localhost:30000/api/v2/identity/authorize", "http://localhost:30000/api/v2/auth/authorize"]}, {"client_id": "custom-local", "client_secret": "custom-local-secret", "id_token_signed_response_alg": "ES256", "redirect_uris": ["http://localhost:30000/api/v2/identity/authorize", "http://localhost:30000/api/v2/auth/authorize"]}]' +HEXCLAVE_INTEGRATION_CLIENTS_CONFIG='[{"client_id": "neon-local", "client_secret": "neon-local-secret", "id_token_signed_response_alg": "ES256", "redirect_uris": ["http://localhost:30000/api/v2/identity/authorize", "http://localhost:30000/api/v2/auth/authorize"]}, {"client_id": "custom-local", "client_secret": "custom-local-secret", "id_token_signed_response_alg": "ES256", "redirect_uris": ["http://localhost:30000/api/v2/identity/authorize", "http://localhost:30000/api/v2/auth/authorize"]}]' CRON_SECRET=mock_cron_secret -STACK_FREESTYLE_API_KEY=mock_stack_freestyle_key -STACK_VERCEL_SANDBOX_TOKEN=vercel_sandbox_disabled_for_local_development -STACK_OPENAI_API_KEY=mock_openai_api_key -STACK_STRIPE_SECRET_KEY=sk_test_mockstripekey -STACK_STRIPE_WEBHOOK_SECRET=mock_stripe_webhook_secret -STACK_OPENROUTER_API_KEY=FORWARD_TO_PRODUCTION -STACK_FEEDBACK_MODE=FORWARD_TO_PRODUCTION -STACK_MINTLIFY_MCP_URL=https://stackauth-e0affa27.mintlify.app/mcp +HEXCLAVE_FREESTYLE_API_KEY=mock_stack_freestyle_key +HEXCLAVE_VERCEL_SANDBOX_TOKEN=vercel_sandbox_disabled_for_local_development +HEXCLAVE_OPENAI_API_KEY=mock_openai_api_key +HEXCLAVE_STRIPE_SECRET_KEY=sk_test_mockstripekey +HEXCLAVE_STRIPE_WEBHOOK_SECRET=mock_stripe_webhook_secret +HEXCLAVE_OPENROUTER_API_KEY=FORWARD_TO_PRODUCTION +HEXCLAVE_FEEDBACK_MODE=FORWARD_TO_PRODUCTION +HEXCLAVE_MINTLIFY_MCP_URL=https://stackauth-e0affa27.mintlify.app/mcp # Email monitor configuration for tests -STACK_EMAIL_MONITOR_VERIFICATION_CALLBACK_URL=http://localhost:8101/handler/email-verification -STACK_EMAIL_MONITOR_PROJECT_ID=internal -STACK_EMAIL_MONITOR_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only -STACK_EMAIL_MONITOR_RESEND_EMAIL_DOMAIN=stack-generated.example.com -STACK_EMAIL_MONITOR_RESEND_EMAIL_API_KEY=this-is-a-fake-key -STACK_EMAIL_MONITOR_INBUCKET_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}05 -STACK_EMAIL_MONITOR_USE_INBUCKET=true -STACK_EMAIL_MONITOR_SECRET_TOKEN=this-secret-token-is-for-local-development-only +HEXCLAVE_EMAIL_MONITOR_VERIFICATION_CALLBACK_URL=http://localhost:8101/handler/email-verification +HEXCLAVE_EMAIL_MONITOR_PROJECT_ID=internal +HEXCLAVE_EMAIL_MONITOR_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +HEXCLAVE_EMAIL_MONITOR_RESEND_EMAIL_DOMAIN=stack-generated.example.com +HEXCLAVE_EMAIL_MONITOR_RESEND_EMAIL_API_KEY=this-is-a-fake-key +HEXCLAVE_EMAIL_MONITOR_INBUCKET_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}05 +HEXCLAVE_EMAIL_MONITOR_USE_INBUCKET=true +HEXCLAVE_EMAIL_MONITOR_SECRET_TOKEN=this-secret-token-is-for-local-development-only -STACK_EMAILABLE_API_KEY= +HEXCLAVE_EMAILABLE_API_KEY= -STACK_INTERNAL_FEEDBACK_RECIPIENTS=team@hexclave.com +HEXCLAVE_INTERNAL_FEEDBACK_RECIPIENTS=team@hexclave.com # S3 Configuration for local development using s3mock -STACK_S3_ENDPOINT=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}21 -STACK_S3_REGION=us-east-1 -STACK_S3_ACCESS_KEY_ID=s3mockroot -STACK_S3_SECRET_ACCESS_KEY=s3mockroot -STACK_S3_BUCKET=stack-storage -STACK_S3_PRIVATE_BUCKET=stack-storage-private +HEXCLAVE_S3_ENDPOINT=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}21 +HEXCLAVE_S3_REGION=us-east-1 +HEXCLAVE_S3_ACCESS_KEY_ID=s3mockroot +HEXCLAVE_S3_SECRET_ACCESS_KEY=s3mockroot +HEXCLAVE_S3_BUCKET=stack-storage +HEXCLAVE_S3_PRIVATE_BUCKET=stack-storage-private # AWS region defaults to LocalStack -STACK_AWS_REGION=us-east-1 -STACK_AWS_KMS_ENDPOINT=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}24 -STACK_AWS_ACCESS_KEY_ID=test -STACK_AWS_SECRET_ACCESS_KEY=test +HEXCLAVE_AWS_REGION=us-east-1 +HEXCLAVE_AWS_KMS_ENDPOINT=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}24 +HEXCLAVE_AWS_ACCESS_KEY_ID=test +HEXCLAVE_AWS_SECRET_ACCESS_KEY=test # Upstash defaults to one of the pre-build test users of the local emulator -STACK_QSTASH_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}25 -STACK_QSTASH_TOKEN=eyJVc2VySUQiOiJkZWZhdWx0VXNlciIsIlBhc3N3b3JkIjoiZGVmYXVsdFBhc3N3b3JkIn0= -STACK_QSTASH_CURRENT_SIGNING_KEY=sig_7kYjw48mhY7kAjqNGcy6cr29RJ6r -STACK_QSTASH_NEXT_SIGNING_KEY=sig_5ZB6DVzB1wjE8S6rZ7eenA8Pdnhs +HEXCLAVE_QSTASH_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}25 +HEXCLAVE_QSTASH_TOKEN=eyJVc2VySUQiOiJkZWZhdWx0VXNlciIsIlBhc3N3b3JkIjoiZGVmYXVsdFBhc3N3b3JkIn0= +HEXCLAVE_QSTASH_CURRENT_SIGNING_KEY=sig_7kYjw48mhY7kAjqNGcy6cr29RJ6r +HEXCLAVE_QSTASH_NEXT_SIGNING_KEY=sig_5ZB6DVzB1wjE8S6rZ7eenA8Pdnhs # MCP review tool (SpacetimeDB) -STACK_SPACETIMEDB_URI=ws://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}39 -STACK_SPACETIMEDB_DB_NAME=stack-auth-llm -STACK_MCP_LOG_TOKEN=change-me +HEXCLAVE_SPACETIMEDB_URI=ws://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}39 +HEXCLAVE_SPACETIMEDB_DB_NAME=stack-auth-llm +HEXCLAVE_MCP_LOG_TOKEN=change-me # Clickhouse -STACK_CLICKHOUSE_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}36 -STACK_CLICKHOUSE_ADMIN_USER=stackframe -STACK_CLICKHOUSE_ADMIN_PASSWORD=PASSWORD-PLACEHOLDER--9gKyMxJeMx -STACK_CLICKHOUSE_EXTERNAL_PASSWORD=PASSWORD-PLACEHOLDER--EZeHscBMzE +HEXCLAVE_CLICKHOUSE_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}36 +HEXCLAVE_CLICKHOUSE_ADMIN_USER=stackframe +HEXCLAVE_CLICKHOUSE_ADMIN_PASSWORD=PASSWORD-PLACEHOLDER--9gKyMxJeMx +HEXCLAVE_CLICKHOUSE_EXTERNAL_PASSWORD=PASSWORD-PLACEHOLDER--EZeHscBMzE # Managed emails -STACK_RESEND_API_KEY=mock_resend_api_key -STACK_RESEND_WEBHOOK_SECRET=mock_resend_webhook_secret -STACK_DNSIMPLE_API_TOKEN=mock_dnsimple_api_token -STACK_DNSIMPLE_ACCOUNT_ID=mock_dnsimple_account_id -STACK_DNSIMPLE_API_BASE_URL=https://api.dnsimple.com/v2 +HEXCLAVE_RESEND_API_KEY=mock_resend_api_key +HEXCLAVE_RESEND_WEBHOOK_SECRET=mock_resend_webhook_secret +HEXCLAVE_DNSIMPLE_API_TOKEN=mock_dnsimple_api_token +HEXCLAVE_DNSIMPLE_ACCOUNT_ID=mock_dnsimple_account_id +HEXCLAVE_DNSIMPLE_API_BASE_URL=https://api.dnsimple.com/v2 diff --git a/apps/backend/prisma/seed.ts b/apps/backend/prisma/seed.ts index 20902dc08..a7923aac5 100644 --- a/apps/backend/prisma/seed.ts +++ b/apps/backend/prisma/seed.ts @@ -56,21 +56,21 @@ function enableSeedLogTimestamps() { export async function seed() { enableSeedLogTimestamps(); - process.env.STACK_SEED_MODE = 'true'; + process.env.HEXCLAVE_SEED_MODE = 'true'; console.log('Seeding database...'); // Optional default admin user - const adminEmail = process.env.STACK_SEED_INTERNAL_PROJECT_USER_EMAIL; - const adminPassword = process.env.STACK_SEED_INTERNAL_PROJECT_USER_PASSWORD; - const adminInternalAccess = process.env.STACK_SEED_INTERNAL_PROJECT_USER_INTERNAL_ACCESS === 'true'; - const adminGithubId = process.env.STACK_SEED_INTERNAL_PROJECT_USER_GITHUB_ID; + const adminEmail = (process.env.HEXCLAVE_SEED_INTERNAL_PROJECT_USER_EMAIL || process.env.STACK_SEED_INTERNAL_PROJECT_USER_EMAIL); + const adminPassword = (process.env.HEXCLAVE_SEED_INTERNAL_PROJECT_USER_PASSWORD || process.env.STACK_SEED_INTERNAL_PROJECT_USER_PASSWORD); + const adminInternalAccess = (process.env.HEXCLAVE_SEED_INTERNAL_PROJECT_USER_INTERNAL_ACCESS || process.env.STACK_SEED_INTERNAL_PROJECT_USER_INTERNAL_ACCESS) === 'true'; + const adminGithubId = (process.env.HEXCLAVE_SEED_INTERNAL_PROJECT_USER_GITHUB_ID || process.env.STACK_SEED_INTERNAL_PROJECT_USER_GITHUB_ID); // dashboard settings - const dashboardDomain = process.env.NEXT_PUBLIC_STACK_DASHBOARD_URL; - const oauthProviderIds = process.env.STACK_SEED_INTERNAL_PROJECT_OAUTH_PROVIDERS?.split(',') ?? []; - const otpEnabled = process.env.STACK_SEED_INTERNAL_PROJECT_OTP_ENABLED === 'true'; - const signUpEnabled = process.env.STACK_SEED_INTERNAL_PROJECT_SIGN_UP_ENABLED === 'true'; - const allowLocalhost = process.env.STACK_SEED_INTERNAL_PROJECT_ALLOW_LOCALHOST === 'true'; + const dashboardDomain = (process.env.NEXT_PUBLIC_HEXCLAVE_DASHBOARD_URL || process.env.NEXT_PUBLIC_STACK_DASHBOARD_URL); + const oauthProviderIds = (process.env.HEXCLAVE_SEED_INTERNAL_PROJECT_OAUTH_PROVIDERS || process.env.STACK_SEED_INTERNAL_PROJECT_OAUTH_PROVIDERS)?.split(',') ?? []; + const otpEnabled = (process.env.HEXCLAVE_SEED_INTERNAL_PROJECT_OTP_ENABLED || process.env.STACK_SEED_INTERNAL_PROJECT_OTP_ENABLED) === 'true'; + const signUpEnabled = (process.env.HEXCLAVE_SEED_INTERNAL_PROJECT_SIGN_UP_ENABLED || process.env.STACK_SEED_INTERNAL_PROJECT_SIGN_UP_ENABLED) === 'true'; + const allowLocalhost = (process.env.HEXCLAVE_SEED_INTERNAL_PROJECT_ALLOW_LOCALHOST || process.env.STACK_SEED_INTERNAL_PROJECT_ALLOW_LOCALHOST) === 'true'; const localEmulatorEnabled = isLocalEmulatorEnabled(); @@ -366,22 +366,22 @@ export async function seed() { // seed, email/svix, clickhouse). The emulator CLI authenticates against the // internal project using the pck stored here, so it must land before the rest // of the seed even if something later fails. - const isLocalEmulator = process.env.NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR === 'true'; - const rawPck = process.env.STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY; + const isLocalEmulator = (process.env.NEXT_PUBLIC_HEXCLAVE_IS_LOCAL_EMULATOR || process.env.NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR) === 'true'; + const rawPck = (process.env.HEXCLAVE_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY || process.env.STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY); if (isLocalEmulator && !rawPck) { // Emulator images build before a per-VM pck is available. Runtime boots set - // STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY from the VM-generated + // HEXCLAVE_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY from the VM-generated // random value and re-run the seed, which upserts the internal key set then. console.log('Skipping internal API key set (no pck provided; emulator mode).'); } else { const keySet = { - publishableClientKey: rawPck || throwErr('STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY is not set'), + publishableClientKey: rawPck || throwErr('HEXCLAVE_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY is not set'), secretServerKey: isLocalEmulator - ? (process.env.STACK_INTERNAL_PROJECT_SECRET_SERVER_KEY ?? null) - : (process.env.STACK_INTERNAL_PROJECT_SECRET_SERVER_KEY || throwErr('STACK_INTERNAL_PROJECT_SECRET_SERVER_KEY is not set')), + ? ((process.env.HEXCLAVE_INTERNAL_PROJECT_SECRET_SERVER_KEY || process.env.STACK_INTERNAL_PROJECT_SECRET_SERVER_KEY) ?? null) + : ((process.env.HEXCLAVE_INTERNAL_PROJECT_SECRET_SERVER_KEY || process.env.STACK_INTERNAL_PROJECT_SECRET_SERVER_KEY) || throwErr('HEXCLAVE_INTERNAL_PROJECT_SECRET_SERVER_KEY is not set')), superSecretAdminKey: isLocalEmulator - ? (process.env.STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY ?? null) - : (process.env.STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY || throwErr('STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY is not set')), + ? ((process.env.HEXCLAVE_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY || process.env.STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY) ?? null) + : ((process.env.HEXCLAVE_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY || process.env.STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY) || throwErr('HEXCLAVE_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY is not set')), }; await globalPrismaClient.apiKeySet.upsert({ @@ -401,7 +401,7 @@ export async function seed() { console.log('Updated internal API key set'); } - const shouldSeedDummyProject = process.env.STACK_SEED_ENABLE_DUMMY_PROJECT === 'true'; + const shouldSeedDummyProject = (process.env.HEXCLAVE_SEED_ENABLE_DUMMY_PROJECT || process.env.STACK_SEED_ENABLE_DUMMY_PROJECT) === 'true'; if (shouldSeedDummyProject) { await seedDummyProject({ projectId: DUMMY_PROJECT_ID, diff --git a/apps/backend/src/lib/internal-feedback-emails.tsx b/apps/backend/src/lib/internal-feedback-emails.tsx index dc77bc4f1..43765e62a 100644 --- a/apps/backend/src/lib/internal-feedback-emails.tsx +++ b/apps/backend/src/lib/internal-feedback-emails.tsx @@ -125,35 +125,48 @@ export async function sendSupportFeedbackEmail(options: { } import.meta.vitest?.test("getInternalFeedbackRecipients()", ({ expect }) => { + // getEnvVariable resolves HEXCLAVE_INTERNAL_FEEDBACK_RECIPIENTS first and + // falls back to the legacy STACK_ name, so clear and restore both. // eslint-disable-next-line no-restricted-syntax - const previousValue = process.env.STACK_INTERNAL_FEEDBACK_RECIPIENTS; + const previousValue = process.env.HEXCLAVE_INTERNAL_FEEDBACK_RECIPIENTS; + // eslint-disable-next-line no-restricted-syntax + const previousLegacyValue = process.env.STACK_INTERNAL_FEEDBACK_RECIPIENTS; try { + // eslint-disable-next-line no-restricted-syntax + delete process.env.HEXCLAVE_INTERNAL_FEEDBACK_RECIPIENTS; // eslint-disable-next-line no-restricted-syntax delete process.env.STACK_INTERNAL_FEEDBACK_RECIPIENTS; expect(() => getInternalFeedbackRecipients()).toThrow("Missing environment variable"); // eslint-disable-next-line no-restricted-syntax - process.env.STACK_INTERNAL_FEEDBACK_RECIPIENTS = "TEAM@hexclave.com, team@hexclave.com , another@example.com"; + process.env.HEXCLAVE_INTERNAL_FEEDBACK_RECIPIENTS = "TEAM@hexclave.com, team@hexclave.com , another@example.com"; expect(getInternalFeedbackRecipients()).toEqual([ "team@hexclave.com", "another@example.com", ]); // eslint-disable-next-line no-restricted-syntax - process.env.STACK_INTERNAL_FEEDBACK_RECIPIENTS = "valid@example.com, "; + process.env.HEXCLAVE_INTERNAL_FEEDBACK_RECIPIENTS = "valid@example.com, "; expect(() => getInternalFeedbackRecipients()).toThrow("empty recipient"); // eslint-disable-next-line no-restricted-syntax - process.env.STACK_INTERNAL_FEEDBACK_RECIPIENTS = ", "; + process.env.HEXCLAVE_INTERNAL_FEEDBACK_RECIPIENTS = ", "; expect(() => getInternalFeedbackRecipients()).toThrow("empty recipient"); } finally { if (previousValue === undefined) { + // eslint-disable-next-line no-restricted-syntax + delete process.env.HEXCLAVE_INTERNAL_FEEDBACK_RECIPIENTS; + } else { + // eslint-disable-next-line no-restricted-syntax + process.env.HEXCLAVE_INTERNAL_FEEDBACK_RECIPIENTS = previousValue; + } + if (previousLegacyValue === undefined) { // eslint-disable-next-line no-restricted-syntax delete process.env.STACK_INTERNAL_FEEDBACK_RECIPIENTS; } else { // eslint-disable-next-line no-restricted-syntax - process.env.STACK_INTERNAL_FEEDBACK_RECIPIENTS = previousValue; + process.env.STACK_INTERNAL_FEEDBACK_RECIPIENTS = previousLegacyValue; } } }); diff --git a/apps/dashboard/.env b/apps/dashboard/.env index 21c9b22b9..5378b0119 100644 --- a/apps/dashboard/.env +++ b/apps/dashboard/.env @@ -1,20 +1,20 @@ # Basic -NEXT_PUBLIC_STACK_API_URL=# enter your stack endpoint here, For local development: http://localhost:8102 (no trailing slash) -NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR=# set to true to enable local emulator UI behavior (auto-login + read-only environment config updates) -NEXT_PUBLIC_STACK_PROJECT_ID=internal -NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=# enter your Stack publishable client key here. For local development, just enter a random string, then run `pnpm db:reset` -STACK_SECRET_SERVER_KEY=# enter your Stack secret client key here. For local development, do the same as above -NEXT_PUBLIC_STACK_DOCS_BASE_URL=# enter the base URL of the docs here -NEXT_PUBLIC_STACK_EXTRA_REQUEST_HEADERS=# a list of extra request headers to add to all Hexclave API requests, as a JSON record -NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY=# enter your Stripe publishable key here +NEXT_PUBLIC_HEXCLAVE_API_URL=# enter your stack endpoint here, For local development: http://localhost:8102 (no trailing slash) +NEXT_PUBLIC_HEXCLAVE_IS_LOCAL_EMULATOR=# set to true to enable local emulator UI behavior (auto-login + read-only environment config updates) +NEXT_PUBLIC_HEXCLAVE_PROJECT_ID=internal +NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=# enter your Stack publishable client key here. For local development, just enter a random string, then run `pnpm db:reset` +HEXCLAVE_SECRET_SERVER_KEY=# enter your Stack secret client key here. For local development, do the same as above +NEXT_PUBLIC_HEXCLAVE_DOCS_BASE_URL=# enter the base URL of the docs here +NEXT_PUBLIC_HEXCLAVE_EXTRA_REQUEST_HEADERS=# a list of extra request headers to add to all Hexclave API requests, as a JSON record +NEXT_PUBLIC_HEXCLAVE_STRIPE_PUBLISHABLE_KEY=# enter your Stripe publishable key here # Webhooks -NEXT_PUBLIC_STACK_SVIX_SERVER_URL=# For prod, leave it empty. For local development, use `http://localhost:8113` +NEXT_PUBLIC_HEXCLAVE_SVIX_SERVER_URL=# For prod, leave it empty. For local development, use `http://localhost:8113` # Misc, optional -NEXT_PUBLIC_STACK_HEAD_TAGS='[{ "tagName": "script", "attributes": {}, "innerHTML": "// insert head tags here" }]' -STACK_DEVELOPMENT_TRANSLATION_LOCALE=# enter the locale to use for the translation provider here, for example: de-DE. Only works during development, not in production. Optional, by default don't translate -NEXT_PUBLIC_STACK_ENABLE_DEVELOPMENT_FEATURES_PROJECT_IDS='["internal"]' -NEXT_PUBLIC_STACK_DEBUGGER_ON_ASSERTION_ERROR=# set to true to open the debugger on assertion errors (set to true in .env.development) -STACK_FEATUREBASE_JWT_SECRET=# used for Featurebase SSO, you probably won't have to set this -STACK_CHANGELOG_URL=# Used for raw github link to root changelog.md file. +NEXT_PUBLIC_HEXCLAVE_HEAD_TAGS='[{ "tagName": "script", "attributes": {}, "innerHTML": "// insert head tags here" }]' +HEXCLAVE_DEVELOPMENT_TRANSLATION_LOCALE=# enter the locale to use for the translation provider here, for example: de-DE. Only works during development, not in production. Optional, by default don't translate +NEXT_PUBLIC_HEXCLAVE_ENABLE_DEVELOPMENT_FEATURES_PROJECT_IDS='["internal"]' +NEXT_PUBLIC_HEXCLAVE_DEBUGGER_ON_ASSERTION_ERROR=# set to true to open the debugger on assertion errors (set to true in .env.development) +HEXCLAVE_FEATUREBASE_JWT_SECRET=# used for Featurebase SSO, you probably won't have to set this +HEXCLAVE_CHANGELOG_URL=# Used for raw github link to root changelog.md file. diff --git a/apps/dashboard/.env.development b/apps/dashboard/.env.development index f3051b6a3..8189e6966 100644 --- a/apps/dashboard/.env.development +++ b/apps/dashboard/.env.development @@ -1,15 +1,15 @@ -NEXT_PUBLIC_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 -NEXT_PUBLIC_STACK_DOCS_BASE_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}26 -NEXT_PUBLIC_STACK_HOSTED_HANDLER_DOMAIN_SUFFIX=.localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}09 -NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR=false +NEXT_PUBLIC_HEXCLAVE_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +NEXT_PUBLIC_HEXCLAVE_DOCS_BASE_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}26 +NEXT_PUBLIC_HEXCLAVE_HOSTED_HANDLER_DOMAIN_SUFFIX=.localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}09 +NEXT_PUBLIC_HEXCLAVE_IS_LOCAL_EMULATOR=false -NEXT_PUBLIC_STACK_PROJECT_ID=internal -NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only -STACK_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only +NEXT_PUBLIC_HEXCLAVE_PROJECT_ID=internal +NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +HEXCLAVE_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only -NEXT_PUBLIC_STACK_SVIX_SERVER_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}13 -STACK_ARTIFICIAL_DEVELOPMENT_DELAY_MS=50 +NEXT_PUBLIC_HEXCLAVE_SVIX_SERVER_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}13 +HEXCLAVE_ARTIFICIAL_DEVELOPMENT_DELAY_MS=50 -NEXT_PUBLIC_STACK_DEBUGGER_ON_ASSERTION_ERROR=false +NEXT_PUBLIC_HEXCLAVE_DEBUGGER_ON_ASSERTION_ERROR=false -STACK_FEATUREBASE_JWT_SECRET=secret-value +HEXCLAVE_FEATUREBASE_JWT_SECRET=secret-value diff --git a/apps/dashboard/src/lib/env.tsx b/apps/dashboard/src/lib/env.tsx index 7950f8903..91469a5b6 100644 --- a/apps/dashboard/src/lib/env.tsx +++ b/apps/dashboard/src/lib/env.tsx @@ -12,36 +12,36 @@ export function expandHexclavePortPrefix(value?: string | null) { // to the legacy NEXT_PUBLIC_*STACK_* literal. Both operands must stay literal // `process.env.NEXT_PUBLIC_*` references so Next.js can inline them at build time. const _inlineEnvVars = { - NEXT_PUBLIC_STACK_API_URL: process.env.NEXT_PUBLIC_HEXCLAVE_API_URL ?? process.env.NEXT_PUBLIC_STACK_API_URL, - NEXT_PUBLIC_STACK_DASHBOARD_URL: process.env.NEXT_PUBLIC_HEXCLAVE_DASHBOARD_URL ?? process.env.NEXT_PUBLIC_STACK_DASHBOARD_URL, - NEXT_PUBLIC_STACK_SVIX_SERVER_URL: process.env.NEXT_PUBLIC_HEXCLAVE_SVIX_SERVER_URL ?? process.env.NEXT_PUBLIC_STACK_SVIX_SERVER_URL, - NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR: process.env.NEXT_PUBLIC_HEXCLAVE_IS_LOCAL_EMULATOR ?? process.env.NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR, - NEXT_PUBLIC_STACK_IS_REMOTE_DEVELOPMENT_ENVIRONMENT: process.env.NEXT_PUBLIC_HEXCLAVE_IS_REMOTE_DEVELOPMENT_ENVIRONMENT ?? process.env.NEXT_PUBLIC_STACK_IS_REMOTE_DEVELOPMENT_ENVIRONMENT, - NEXT_PUBLIC_STACK_IS_PREVIEW: process.env.NEXT_PUBLIC_HEXCLAVE_IS_PREVIEW ?? process.env.NEXT_PUBLIC_STACK_IS_PREVIEW, + NEXT_PUBLIC_STACK_API_URL: process.env.NEXT_PUBLIC_HEXCLAVE_API_URL || process.env.NEXT_PUBLIC_STACK_API_URL, + NEXT_PUBLIC_STACK_DASHBOARD_URL: process.env.NEXT_PUBLIC_HEXCLAVE_DASHBOARD_URL || process.env.NEXT_PUBLIC_STACK_DASHBOARD_URL, + NEXT_PUBLIC_STACK_SVIX_SERVER_URL: process.env.NEXT_PUBLIC_HEXCLAVE_SVIX_SERVER_URL || process.env.NEXT_PUBLIC_STACK_SVIX_SERVER_URL, + NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR: process.env.NEXT_PUBLIC_HEXCLAVE_IS_LOCAL_EMULATOR || process.env.NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR, + NEXT_PUBLIC_STACK_IS_REMOTE_DEVELOPMENT_ENVIRONMENT: process.env.NEXT_PUBLIC_HEXCLAVE_IS_REMOTE_DEVELOPMENT_ENVIRONMENT || process.env.NEXT_PUBLIC_STACK_IS_REMOTE_DEVELOPMENT_ENVIRONMENT, + NEXT_PUBLIC_STACK_IS_PREVIEW: process.env.NEXT_PUBLIC_HEXCLAVE_IS_PREVIEW || process.env.NEXT_PUBLIC_STACK_IS_PREVIEW, NEXT_PUBLIC_HEXCLAVE_LOCAL_DASHBOARD_PORT: process.env.NEXT_PUBLIC_HEXCLAVE_LOCAL_DASHBOARD_PORT, - NEXT_PUBLIC_STACK_PROJECT_ID: process.env.NEXT_PUBLIC_HEXCLAVE_PROJECT_ID ?? process.env.NEXT_PUBLIC_STACK_PROJECT_ID, - NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY: process.env.NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY ?? process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY, - NEXT_PUBLIC_STACK_URL: process.env.NEXT_PUBLIC_HEXCLAVE_URL ?? process.env.NEXT_PUBLIC_STACK_URL, - NEXT_PUBLIC_STACK_INBUCKET_WEB_URL: process.env.NEXT_PUBLIC_HEXCLAVE_INBUCKET_WEB_URL ?? process.env.NEXT_PUBLIC_STACK_INBUCKET_WEB_URL, - NEXT_PUBLIC_STACK_ENABLE_DEVELOPMENT_FEATURES_PROJECT_IDS: process.env.NEXT_PUBLIC_HEXCLAVE_ENABLE_DEVELOPMENT_FEATURES_PROJECT_IDS ?? process.env.NEXT_PUBLIC_STACK_ENABLE_DEVELOPMENT_FEATURES_PROJECT_IDS, - NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_HEXCLAVE_STRIPE_PUBLISHABLE_KEY ?? process.env.NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY, + NEXT_PUBLIC_STACK_PROJECT_ID: process.env.NEXT_PUBLIC_HEXCLAVE_PROJECT_ID || process.env.NEXT_PUBLIC_STACK_PROJECT_ID, + NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY: process.env.NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY || process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY, + NEXT_PUBLIC_STACK_URL: process.env.NEXT_PUBLIC_HEXCLAVE_URL || process.env.NEXT_PUBLIC_STACK_URL, + NEXT_PUBLIC_STACK_INBUCKET_WEB_URL: process.env.NEXT_PUBLIC_HEXCLAVE_INBUCKET_WEB_URL || process.env.NEXT_PUBLIC_STACK_INBUCKET_WEB_URL, + NEXT_PUBLIC_STACK_ENABLE_DEVELOPMENT_FEATURES_PROJECT_IDS: process.env.NEXT_PUBLIC_HEXCLAVE_ENABLE_DEVELOPMENT_FEATURES_PROJECT_IDS || process.env.NEXT_PUBLIC_STACK_ENABLE_DEVELOPMENT_FEATURES_PROJECT_IDS, + NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_HEXCLAVE_STRIPE_PUBLISHABLE_KEY || process.env.NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY, // Hexclave rebrand: port-prefix var renamed outright (no dual-read). NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX: process.env.NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX, - NEXT_PUBLIC_STACK_DOCS_BASE_URL: process.env.NEXT_PUBLIC_HEXCLAVE_DOCS_BASE_URL ?? process.env.NEXT_PUBLIC_STACK_DOCS_BASE_URL, - NEXT_PUBLIC_STACK_ENABLE_REACT_SCAN_IN_DEVELOPMENT: process.env.NEXT_PUBLIC_HEXCLAVE_ENABLE_REACT_SCAN_IN_DEVELOPMENT ?? process.env.NEXT_PUBLIC_STACK_ENABLE_REACT_SCAN_IN_DEVELOPMENT, + NEXT_PUBLIC_STACK_DOCS_BASE_URL: process.env.NEXT_PUBLIC_HEXCLAVE_DOCS_BASE_URL || process.env.NEXT_PUBLIC_STACK_DOCS_BASE_URL, + NEXT_PUBLIC_STACK_ENABLE_REACT_SCAN_IN_DEVELOPMENT: process.env.NEXT_PUBLIC_HEXCLAVE_ENABLE_REACT_SCAN_IN_DEVELOPMENT || process.env.NEXT_PUBLIC_STACK_ENABLE_REACT_SCAN_IN_DEVELOPMENT, // TODO: NEXT_PUBLIC_BROWSER_STACK_API_URL should be renamed to NEXT_PUBLIC_STACK_BROWSER_API_URL - NEXT_PUBLIC_BROWSER_STACK_API_URL: process.env.NEXT_PUBLIC_BROWSER_HEXCLAVE_API_URL ?? process.env.NEXT_PUBLIC_BROWSER_STACK_API_URL, + NEXT_PUBLIC_BROWSER_STACK_API_URL: process.env.NEXT_PUBLIC_BROWSER_HEXCLAVE_API_URL || process.env.NEXT_PUBLIC_BROWSER_STACK_API_URL, // TODO: NEXT_PUBLIC_SERVER_STACK_API_URL should be renamed to NEXT_PUBLIC_STACK_SERVER_API_URL - NEXT_PUBLIC_SERVER_STACK_API_URL: process.env.NEXT_PUBLIC_SERVER_HEXCLAVE_API_URL ?? process.env.NEXT_PUBLIC_SERVER_STACK_API_URL, + NEXT_PUBLIC_SERVER_STACK_API_URL: process.env.NEXT_PUBLIC_SERVER_HEXCLAVE_API_URL || process.env.NEXT_PUBLIC_SERVER_STACK_API_URL, // TODO: NEXT_PUBLIC_SENTRY_DSN should be renamed to NEXT_PUBLIC_STACK_SENTRY_DSN NEXT_PUBLIC_SENTRY_DSN: process.env.NEXT_PUBLIC_SENTRY_DSN, // TODO: NEXT_PUBLIC_VERSION_ALERTER_SEVERE_ONLY should be renamed to NEXT_PUBLIC_STACK_VERSION_ALERTER_SEVERE_ONLY NEXT_PUBLIC_VERSION_ALERTER_SEVERE_ONLY: process.env.NEXT_PUBLIC_VERSION_ALERTER_SEVERE_ONLY, // TODO: NEXT_PUBLIC_BROWSER_STACK_DASHBOARD_URL should be renamed to NEXT_PUBLIC_STACK_BROWSER_DASHBOARD_URL - NEXT_PUBLIC_BROWSER_STACK_DASHBOARD_URL: process.env.NEXT_PUBLIC_BROWSER_HEXCLAVE_DASHBOARD_URL ?? process.env.NEXT_PUBLIC_BROWSER_STACK_DASHBOARD_URL, + NEXT_PUBLIC_BROWSER_STACK_DASHBOARD_URL: process.env.NEXT_PUBLIC_BROWSER_HEXCLAVE_DASHBOARD_URL || process.env.NEXT_PUBLIC_BROWSER_STACK_DASHBOARD_URL, // TODO: NEXT_PUBLIC_SERVER_STACK_DASHBOARD_URL should be renamed to NEXT_PUBLIC_STACK_SERVER_DASHBOARD_URL - NEXT_PUBLIC_SERVER_STACK_DASHBOARD_URL: process.env.NEXT_PUBLIC_SERVER_HEXCLAVE_DASHBOARD_URL ?? process.env.NEXT_PUBLIC_SERVER_STACK_DASHBOARD_URL, + NEXT_PUBLIC_SERVER_STACK_DASHBOARD_URL: process.env.NEXT_PUBLIC_SERVER_HEXCLAVE_DASHBOARD_URL || process.env.NEXT_PUBLIC_SERVER_STACK_DASHBOARD_URL, // TODO: NEXT_PUBLIC_POSTHOG_KEY should be renamed to NEXT_PUBLIC_STACK_POSTHOG_KEY NEXT_PUBLIC_POSTHOG_KEY: process.env.NEXT_PUBLIC_POSTHOG_KEY, } as const; diff --git a/apps/e2e/.env b/apps/e2e/.env index b24d122a8..076ce61d9 100644 --- a/apps/e2e/.env +++ b/apps/e2e/.env @@ -1,11 +1,11 @@ -STACK_DASHBOARD_BASE_URL= -STACK_BACKEND_BASE_URL= -STACK_MCP_BASE_URL= -STACK_INTERNAL_PROJECT_ID= -STACK_INTERNAL_PROJECT_CLIENT_KEY= -STACK_INTERNAL_PROJECT_SERVER_KEY= -STACK_INTERNAL_PROJECT_ADMIN_KEY= -STACK_TEST_SOURCE_OF_TRUTH= -STACK_DATABASE_CONNECTION_STRING= +HEXCLAVE_DASHBOARD_BASE_URL= +HEXCLAVE_BACKEND_BASE_URL= +HEXCLAVE_MCP_BASE_URL= +HEXCLAVE_INTERNAL_PROJECT_ID= +HEXCLAVE_INTERNAL_PROJECT_CLIENT_KEY= +HEXCLAVE_INTERNAL_PROJECT_SERVER_KEY= +HEXCLAVE_INTERNAL_PROJECT_ADMIN_KEY= +HEXCLAVE_TEST_SOURCE_OF_TRUTH= +HEXCLAVE_DATABASE_CONNECTION_STRING= -STACK_INBUCKET_API_URL= +HEXCLAVE_INBUCKET_API_URL= diff --git a/apps/e2e/.env.development b/apps/e2e/.env.development index 830e2df1a..3d1da47de 100644 --- a/apps/e2e/.env.development +++ b/apps/e2e/.env.development @@ -1,16 +1,16 @@ -STACK_DASHBOARD_BASE_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}01 -STACK_BACKEND_BASE_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 -STACK_MCP_BASE_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}44 -STACK_INTERNAL_PROJECT_ID=internal -STACK_INTERNAL_PROJECT_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only -STACK_INTERNAL_PROJECT_SERVER_KEY=this-secret-server-key-is-for-local-development-only -STACK_INTERNAL_PROJECT_ADMIN_KEY=this-super-secret-admin-key-is-for-local-development-only -NEXT_PUBLIC_STACK_HOSTED_HANDLER_DOMAIN_SUFFIX=.localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}09 -STACK_DATABASE_CONNECTION_STRING=postgres://postgres:PASSWORD-PLACEHOLDER--uqfEC1hmmv@localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}28/stackframe +HEXCLAVE_DASHBOARD_BASE_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}01 +HEXCLAVE_BACKEND_BASE_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +HEXCLAVE_MCP_BASE_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}44 +HEXCLAVE_INTERNAL_PROJECT_ID=internal +HEXCLAVE_INTERNAL_PROJECT_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +HEXCLAVE_INTERNAL_PROJECT_SERVER_KEY=this-secret-server-key-is-for-local-development-only +HEXCLAVE_INTERNAL_PROJECT_ADMIN_KEY=this-super-secret-admin-key-is-for-local-development-only +NEXT_PUBLIC_HEXCLAVE_HOSTED_HANDLER_DOMAIN_SUFFIX=.localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}09 +HEXCLAVE_DATABASE_CONNECTION_STRING=postgres://postgres:PASSWORD-PLACEHOLDER--uqfEC1hmmv@localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}28/stackframe -STACK_INBUCKET_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}05 -STACK_SVIX_SERVER_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}13 +HEXCLAVE_INBUCKET_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}05 +HEXCLAVE_SVIX_SERVER_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}13 -STACK_EMAIL_MONITOR_SECRET_TOKEN=this-secret-token-is-for-local-development-only +HEXCLAVE_EMAIL_MONITOR_SECRET_TOKEN=this-secret-token-is-for-local-development-only CRON_SECRET=mock_cron_secret diff --git a/apps/e2e/tests/backend/endpoints/api/v1/integrations/credential-scanning/revoke.test.ts b/apps/e2e/tests/backend/endpoints/api/v1/integrations/credential-scanning/revoke.test.ts index b70b23e89..d8c6aa9b0 100644 --- a/apps/e2e/tests/backend/endpoints/api/v1/integrations/credential-scanning/revoke.test.ts +++ b/apps/e2e/tests/backend/endpoints/api/v1/integrations/credential-scanning/revoke.test.ts @@ -44,7 +44,7 @@ it("should send email notification to user when revoking an API key through cred }, }); - if (process.env.STACK_TEST_SOURCE_OF_TRUTH === "true") { + if ((process.env.HEXCLAVE_TEST_SOURCE_OF_TRUTH || process.env.STACK_TEST_SOURCE_OF_TRUTH) === "true") { expect(revokeResponse).toMatchInlineSnapshot(` NiceResponse { "status": 404, @@ -180,7 +180,7 @@ it("should send email notification to team members when revoking a team API key }, }); - if (process.env.STACK_TEST_SOURCE_OF_TRUTH === "true") { + if ((process.env.HEXCLAVE_TEST_SOURCE_OF_TRUTH || process.env.STACK_TEST_SOURCE_OF_TRUTH) === "true") { expect(revokeResponse).toMatchInlineSnapshot(` NiceResponse { "status": 404, @@ -353,7 +353,7 @@ it("should handle already revoked API keys gracefully", async ({ expect }: { exp }, }); - if (process.env.STACK_TEST_SOURCE_OF_TRUTH === "true") { + if ((process.env.HEXCLAVE_TEST_SOURCE_OF_TRUTH || process.env.STACK_TEST_SOURCE_OF_TRUTH) === "true") { expect(revokeResponse).toMatchInlineSnapshot(` NiceResponse { "status": 404, diff --git a/apps/e2e/tests/backend/endpoints/api/v1/internal/config-local-emulator.test.ts b/apps/e2e/tests/backend/endpoints/api/v1/internal/config-local-emulator.test.ts index d453cb325..934e9395e 100644 --- a/apps/e2e/tests/backend/endpoints/api/v1/internal/config-local-emulator.test.ts +++ b/apps/e2e/tests/backend/endpoints/api/v1/internal/config-local-emulator.test.ts @@ -5,7 +5,7 @@ import { describe } from "vitest"; import { it } from "../../../../../helpers"; import { backendContext, niceBackendFetch } from "../../../../backend-helpers"; -const isLocalEmulator = process.env.NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR === "true"; +const isLocalEmulator = (process.env.NEXT_PUBLIC_HEXCLAVE_IS_LOCAL_EMULATOR || process.env.NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR) === "true"; const blockedMessage = "cannot be changed in a development environment"; const localEmulatorProjectEndpoint = "/api/v1/internal/local-emulator/project"; diff --git a/apps/e2e/tests/backend/endpoints/api/v1/internal/failed-emails-digest.test.ts b/apps/e2e/tests/backend/endpoints/api/v1/internal/failed-emails-digest.test.ts index 89c824e6a..d63a59115 100644 --- a/apps/e2e/tests/backend/endpoints/api/v1/internal/failed-emails-digest.test.ts +++ b/apps/e2e/tests/backend/endpoints/api/v1/internal/failed-emails-digest.test.ts @@ -168,7 +168,7 @@ describe("with valid credentials", () => { const { response, batches: mockProjectFailedEmails } = await waitForFailedEmailsDigest(2); expect(response.status).toBe(200); - if (process.env.STACK_TEST_SOURCE_OF_TRUTH === "true") { + if ((process.env.HEXCLAVE_TEST_SOURCE_OF_TRUTH || process.env.STACK_TEST_SOURCE_OF_TRUTH) === "true") { expect(mockProjectFailedEmails).toMatchInlineSnapshot(`[]`); } else { expect(mockProjectFailedEmails).toMatchInlineSnapshot(` @@ -460,7 +460,7 @@ describe("with valid credentials", () => { (batch: any) => batch.project_id === projectId ); - if (process.env.STACK_TEST_SOURCE_OF_TRUTH === "true") { + if ((process.env.HEXCLAVE_TEST_SOURCE_OF_TRUTH || process.env.STACK_TEST_SOURCE_OF_TRUTH) === "true") { expect(currentResponses).toMatchInlineSnapshot(`[]`); } else { expect(currentResponses.length).toBe(1); diff --git a/apps/e2e/tests/backend/endpoints/api/v1/internal/feedback.test.ts b/apps/e2e/tests/backend/endpoints/api/v1/internal/feedback.test.ts index 8601d4efe..7674bea80 100644 --- a/apps/e2e/tests/backend/endpoints/api/v1/internal/feedback.test.ts +++ b/apps/e2e/tests/backend/endpoints/api/v1/internal/feedback.test.ts @@ -3,7 +3,7 @@ import { describe } from "vitest"; import { it } from "../../../../../helpers"; import { Auth, backendContext, createMailbox, niceBackendFetch, waitForOutboxEmailWithStatus } from "../../../../backend-helpers"; -const isLocalEmulator = process.env.NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR === "true"; +const isLocalEmulator = (process.env.NEXT_PUBLIC_HEXCLAVE_IS_LOCAL_EMULATOR || process.env.NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR) === "true"; const supportConversationsPath = "/api/v1/internal/dogfood/support/conversations"; describe("POST /api/v1/internal/feedback", () => { diff --git a/apps/e2e/tests/backend/endpoints/api/v1/internal/local-emulator-project.test.ts b/apps/e2e/tests/backend/endpoints/api/v1/internal/local-emulator-project.test.ts index 85c97634e..9688c121c 100644 --- a/apps/e2e/tests/backend/endpoints/api/v1/internal/local-emulator-project.test.ts +++ b/apps/e2e/tests/backend/endpoints/api/v1/internal/local-emulator-project.test.ts @@ -7,7 +7,7 @@ import { backendContext, niceBackendFetch } from "../../../../backend-helpers"; const LOCAL_EMULATOR_PROJECT_ENDPOINT = "/api/v1/internal/local-emulator/project"; const LOCAL_EMULATOR_OWNER_TEAM_ID = "5a0c858b-d9e9-49d4-9943-8ce385d86428"; -const isLocalEmulator = process.env.NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR === "true"; +const isLocalEmulator = (process.env.NEXT_PUBLIC_HEXCLAVE_IS_LOCAL_EMULATOR || process.env.NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR) === "true"; async function createTempConfigFile(): Promise { const filePath = `/tmp/${randomUUID()}/stack.config.ts`; diff --git a/apps/e2e/tests/backend/endpoints/api/v1/internal/transactions.test.ts b/apps/e2e/tests/backend/endpoints/api/v1/internal/transactions.test.ts index ce40b0bac..9779e38fc 100644 --- a/apps/e2e/tests/backend/endpoints/api/v1/internal/transactions.test.ts +++ b/apps/e2e/tests/backend/endpoints/api/v1/internal/transactions.test.ts @@ -72,7 +72,7 @@ async function createPurchaseCodeForCustomer(options: { customerType: "user" | " return code as string; } -const stripeWebhookSecret = process.env.STACK_STRIPE_WEBHOOK_SECRET ?? "mock_stripe_webhook_secret"; +const stripeWebhookSecret = (process.env.HEXCLAVE_STRIPE_WEBHOOK_SECRET || process.env.STACK_STRIPE_WEBHOOK_SECRET) ?? "mock_stripe_webhook_secret"; async function sendStripeWebhook(payload: unknown) { const timestamp = Math.floor(Date.now() / 1000); diff --git a/apps/e2e/tests/general/cli.test.ts b/apps/e2e/tests/general/cli.test.ts index 1065b5da8..911547e27 100644 --- a/apps/e2e/tests/general/cli.test.ts +++ b/apps/e2e/tests/general/cli.test.ts @@ -7,7 +7,7 @@ import { Result } from "@hexclave/shared/dist/utils/results"; import { describe, beforeAll, afterAll } from "vitest"; import { it, niceFetch, STACK_BACKEND_BASE_URL, STACK_INTERNAL_PROJECT_CLIENT_KEY, STACK_INTERNAL_PROJECT_SERVER_KEY, STACK_INTERNAL_PROJECT_ADMIN_KEY } from "../helpers"; -const isLocalEmulator = process.env.NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR === "true"; +const isLocalEmulator = (process.env.NEXT_PUBLIC_HEXCLAVE_IS_LOCAL_EMULATOR || process.env.NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR) === "true"; const CLI_BIN = path.resolve("packages/cli/dist/index.js"); diff --git a/apps/e2e/tests/helpers.ts b/apps/e2e/tests/helpers.ts index 8e2ed554b..851046a5c 100644 --- a/apps/e2e/tests/helpers.ts +++ b/apps/e2e/tests/helpers.ts @@ -241,7 +241,7 @@ export class Mailbox { }; this.waitForMessagesWithSubjectCount = async (subject: string, minCount: number, options?: { noBody?: boolean }) => { - const timeoutMs = Number(process.env.STACK_MAILBOX_WAIT_TIMEOUT_MS ?? 60000); + const timeoutMs = Number((process.env.HEXCLAVE_MAILBOX_WAIT_TIMEOUT_MS || process.env.STACK_MAILBOX_WAIT_TIMEOUT_MS) ?? 60000); const intervalMs = 500; const deadline = Date.now() + timeoutMs; let messages: MailboxMessage[] = []; @@ -324,7 +324,7 @@ export const STACK_MCP_BASE_URL = getEnvVariable("STACK_MCP_BASE_URL"); * fallback port. Always thread this through to SDK constructors instead of * hardcoding `STACK_BACKEND_BASE_URL`. */ -export const SDK_BASE_URL: string | undefined = process.env.STACK_TEST_SDK_FALLBACK +export const SDK_BASE_URL: string | undefined = (process.env.HEXCLAVE_TEST_SDK_FALLBACK || process.env.STACK_TEST_SDK_FALLBACK) ? undefined : STACK_BACKEND_BASE_URL; export const STACK_INTERNAL_PROJECT_ID = getEnvVariable("STACK_INTERNAL_PROJECT_ID"); diff --git a/apps/e2e/tests/js/cross-domain-auth.test.ts b/apps/e2e/tests/js/cross-domain-auth.test.ts index 599ba699a..231db0c7a 100644 --- a/apps/e2e/tests/js/cross-domain-auth.test.ts +++ b/apps/e2e/tests/js/cross-domain-auth.test.ts @@ -31,24 +31,31 @@ function createMockDocument(): Document { } const withHostedDomainSuffix = async (callback: () => Promise) => { - const oldHostedHandlerDomainSuffix = process.env.NEXT_PUBLIC_STACK_HOSTED_HANDLER_DOMAIN_SUFFIX; - const oldHostedHandlerUrlTemplate = process.env.NEXT_PUBLIC_STACK_HOSTED_HANDLER_URL_TEMPLATE; - process.env.NEXT_PUBLIC_STACK_HOSTED_HANDLER_DOMAIN_SUFFIX = ".example-stack-hosted.test"; + // The SDK resolves NEXT_PUBLIC_HEXCLAVE_* before the legacy NEXT_PUBLIC_STACK_* + // names, so override the canonical name and clear both spellings. + const oldHostedHandlerDomainSuffix = process.env.NEXT_PUBLIC_HEXCLAVE_HOSTED_HANDLER_DOMAIN_SUFFIX; + const oldLegacyHostedHandlerDomainSuffix = process.env.NEXT_PUBLIC_STACK_HOSTED_HANDLER_DOMAIN_SUFFIX; + const oldHostedHandlerUrlTemplate = process.env.NEXT_PUBLIC_HEXCLAVE_HOSTED_HANDLER_URL_TEMPLATE; + const oldLegacyHostedHandlerUrlTemplate = process.env.NEXT_PUBLIC_STACK_HOSTED_HANDLER_URL_TEMPLATE; + process.env.NEXT_PUBLIC_HEXCLAVE_HOSTED_HANDLER_DOMAIN_SUFFIX = ".example-stack-hosted.test"; + delete process.env.NEXT_PUBLIC_STACK_HOSTED_HANDLER_DOMAIN_SUFFIX; + delete process.env.NEXT_PUBLIC_HEXCLAVE_HOSTED_HANDLER_URL_TEMPLATE; delete process.env.NEXT_PUBLIC_STACK_HOSTED_HANDLER_URL_TEMPLATE; try { await callback(); } finally { - if (oldHostedHandlerDomainSuffix == null) { - delete process.env.NEXT_PUBLIC_STACK_HOSTED_HANDLER_DOMAIN_SUFFIX; - } else { - process.env.NEXT_PUBLIC_STACK_HOSTED_HANDLER_DOMAIN_SUFFIX = oldHostedHandlerDomainSuffix; - } - if (oldHostedHandlerUrlTemplate == null) { - delete process.env.NEXT_PUBLIC_STACK_HOSTED_HANDLER_URL_TEMPLATE; - } else { - process.env.NEXT_PUBLIC_STACK_HOSTED_HANDLER_URL_TEMPLATE = oldHostedHandlerUrlTemplate; - } + const restore = (name: string, value: string | undefined) => { + if (value == null) { + delete process.env[name]; + } else { + process.env[name] = value; + } + }; + restore("NEXT_PUBLIC_HEXCLAVE_HOSTED_HANDLER_DOMAIN_SUFFIX", oldHostedHandlerDomainSuffix); + restore("NEXT_PUBLIC_STACK_HOSTED_HANDLER_DOMAIN_SUFFIX", oldLegacyHostedHandlerDomainSuffix); + restore("NEXT_PUBLIC_HEXCLAVE_HOSTED_HANDLER_URL_TEMPLATE", oldHostedHandlerUrlTemplate); + restore("NEXT_PUBLIC_STACK_HOSTED_HANDLER_URL_TEMPLATE", oldLegacyHostedHandlerUrlTemplate); } }; diff --git a/apps/hosted-components/.env.development b/apps/hosted-components/.env.development index 5fb462236..e7b611e82 100644 --- a/apps/hosted-components/.env.development +++ b/apps/hosted-components/.env.development @@ -1 +1 @@ -VITE_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +VITE_HEXCLAVE_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 diff --git a/apps/internal-tool/.env b/apps/internal-tool/.env index 8f1d8488d..42c079fb6 100644 --- a/apps/internal-tool/.env +++ b/apps/internal-tool/.env @@ -1,9 +1,9 @@ # Hexclave -NEXT_PUBLIC_STACK_API_URL=REPLACE_ME -NEXT_PUBLIC_STACK_PROJECT_ID=REPLACE_ME -NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=REPLACE_ME -STACK_SECRET_SERVER_KEY=REPLACE_ME -NEXT_PUBLIC_STACK_DASHBOARD_URL=REPLACE_ME +NEXT_PUBLIC_HEXCLAVE_API_URL=REPLACE_ME +NEXT_PUBLIC_HEXCLAVE_PROJECT_ID=REPLACE_ME +NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=REPLACE_ME +HEXCLAVE_SECRET_SERVER_KEY=REPLACE_ME +NEXT_PUBLIC_HEXCLAVE_DASHBOARD_URL=REPLACE_ME # SpacetimeDB NEXT_PUBLIC_SPACETIMEDB_HOST=REPLACE_ME NEXT_PUBLIC_SPACETIMEDB_DB_NAME=REPLACE_ME diff --git a/apps/internal-tool/.env.development b/apps/internal-tool/.env.development index d6897d218..e07b66c32 100644 --- a/apps/internal-tool/.env.development +++ b/apps/internal-tool/.env.development @@ -1,6 +1,6 @@ -NEXT_PUBLIC_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 -NEXT_PUBLIC_STACK_PROJECT_ID=internal -NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only -NEXT_PUBLIC_STACK_DASHBOARD_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}01 +NEXT_PUBLIC_HEXCLAVE_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +NEXT_PUBLIC_HEXCLAVE_PROJECT_ID=internal +NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +NEXT_PUBLIC_HEXCLAVE_DASHBOARD_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}01 NEXT_PUBLIC_SPACETIMEDB_HOST=ws://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}39 NEXT_PUBLIC_SPACETIMEDB_DB_NAME=stack-auth-llm diff --git a/apps/internal-tool/scripts/spacetime-publish.mjs b/apps/internal-tool/scripts/spacetime-publish.mjs index dedcf043a..ef2af02ea 100644 --- a/apps/internal-tool/scripts/spacetime-publish.mjs +++ b/apps/internal-tool/scripts/spacetime-publish.mjs @@ -8,8 +8,8 @@ const target = process.argv[2]; // "local" or "prod" /** HTTP API for 'spacetime publish' (matches docker/dependencies/docker.compose.yaml host port ...39). */ function localPublishServerUrl() { - if (process.env.STACK_SPACETIME_PUBLISH_URL) { - return process.env.STACK_SPACETIME_PUBLISH_URL; + if ((process.env.HEXCLAVE_SPACETIME_PUBLISH_URL || process.env.STACK_SPACETIME_PUBLISH_URL)) { + return (process.env.HEXCLAVE_SPACETIME_PUBLISH_URL || process.env.STACK_SPACETIME_PUBLISH_URL); } const prefix = process.env.NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX ?? "81"; return `http://127.0.0.1:${prefix}39`; @@ -36,7 +36,7 @@ if (!args) { process.exit(1); } -if (target === "prod" && !process.env.STACK_MCP_LOG_TOKEN) { +if (target === "prod" && !(process.env.HEXCLAVE_MCP_LOG_TOKEN || process.env.STACK_MCP_LOG_TOKEN)) { console.error("Error: STACK_MCP_LOG_TOKEN must be set for prod publish"); process.exit(1); } diff --git a/apps/internal-tool/scripts/spacetime-token.mjs b/apps/internal-tool/scripts/spacetime-token.mjs index 51a8c119c..656588b26 100644 --- a/apps/internal-tool/scripts/spacetime-token.mjs +++ b/apps/internal-tool/scripts/spacetime-token.mjs @@ -12,7 +12,7 @@ const PLACEHOLDER = "__SPACETIMEDB_LOG_TOKEN__"; const action = process.argv[2]; if (action === "inject") { - const token = process.env.STACK_MCP_LOG_TOKEN || "change-me"; + const token = (process.env.HEXCLAVE_MCP_LOG_TOKEN || process.env.STACK_MCP_LOG_TOKEN) || "change-me"; if (existsSync(BACKUP)) { console.error("Refusing to inject: backup already exists. Run restore first."); process.exit(1); diff --git a/apps/internal-tool/src/app/app-client.tsx b/apps/internal-tool/src/app/app-client.tsx index bf2d1f997..0cd7852e0 100644 --- a/apps/internal-tool/src/app/app-client.tsx +++ b/apps/internal-tool/src/app/app-client.tsx @@ -26,7 +26,7 @@ export default function App() {

MCP Review Tool

Sign in to the{" "} - + Hexclave Dashboard {" "}first, then reload this page. diff --git a/apps/mcp/.env b/apps/mcp/.env index 2db2ce4b8..f22f12364 100644 --- a/apps/mcp/.env +++ b/apps/mcp/.env @@ -1,3 +1,3 @@ -NEXT_PUBLIC_STACK_API_URL= -NEXT_PUBLIC_SERVER_STACK_API_URL= +NEXT_PUBLIC_HEXCLAVE_API_URL= +NEXT_PUBLIC_SERVER_HEXCLAVE_API_URL= NEXT_PUBLIC_POSTHOG_KEY= diff --git a/apps/mcp/.env.development b/apps/mcp/.env.development index 4e798dfbd..d19763a15 100644 --- a/apps/mcp/.env.development +++ b/apps/mcp/.env.development @@ -1 +1 @@ -NEXT_PUBLIC_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +NEXT_PUBLIC_HEXCLAVE_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 diff --git a/apps/mcp/.env.example b/apps/mcp/.env.example index 46dd3325e..75ee64261 100644 --- a/apps/mcp/.env.example +++ b/apps/mcp/.env.example @@ -1,3 +1,3 @@ -NEXT_PUBLIC_STACK_API_URL=# the base URL of Stack's backend/API. For local development, this is `http://localhost:8102`; for the managed service, this is `https://api.hexclave.com`. -NEXT_PUBLIC_SERVER_STACK_API_URL=# optional server-side override for the backend/API URL. If unset, falls back to NEXT_PUBLIC_STACK_API_URL. +NEXT_PUBLIC_HEXCLAVE_API_URL=# the base URL of Stack's backend/API. For local development, this is `http://localhost:8102`; for the managed service, this is `https://api.hexclave.com`. +NEXT_PUBLIC_SERVER_HEXCLAVE_API_URL=# optional server-side override for the backend/API URL. If unset, falls back to NEXT_PUBLIC_HEXCLAVE_API_URL. NEXT_PUBLIC_POSTHOG_KEY=# optional PostHog project key for analytics. Leave blank to use the default public key. diff --git a/docker/local-emulator/rotate-secrets.sh b/docker/local-emulator/rotate-secrets.sh index c88bb1319..e9d20c85e 100644 --- a/docker/local-emulator/rotate-secrets.sh +++ b/docker/local-emulator/rotate-secrets.sh @@ -22,6 +22,10 @@ set -euo pipefail OUTPUT=/run/stack-auth/rotated-secrets.env WORK_DIR="${STACK_RUNTIME_WORK_DIR:-/app}" +# Hexclave rebrand: the container env may carry the canonical HEXCLAVE_ name +# instead of the legacy STACK_ one this script reads. +STACK_DATABASE_CONNECTION_STRING="${STACK_DATABASE_CONNECTION_STRING:-${HEXCLAVE_DATABASE_CONNECTION_STRING:-}}" + PLACEHOLDER_PCK="00000000000000000000000000000000ffffffffffffffffffffffffffffffff" log() { printf '[rotate-secrets] %s\n' "$*"; } diff --git a/docker/server/.env b/docker/server/.env index 22e29e134..6c8791b58 100644 --- a/docker/server/.env +++ b/docker/server/.env @@ -1,42 +1,42 @@ -NEXT_PUBLIC_STACK_API_URL=# https://your-backend-domain.com -NEXT_PUBLIC_STACK_DASHBOARD_URL=# https://your-dashboard-domain.com, this will be added as a trusted domain by the seed script +NEXT_PUBLIC_HEXCLAVE_API_URL=# https://your-backend-domain.com +NEXT_PUBLIC_HEXCLAVE_DASHBOARD_URL=# https://your-dashboard-domain.com, this will be added as a trusted domain by the seed script -STACK_DATABASE_CONNECTION_STRING=# postgres connection string +HEXCLAVE_DATABASE_CONNECTION_STRING=# postgres connection string -STACK_SERVER_SECRET=# a 32 bytes base64url encoded random string, used for JWT encryption. can be generated with `pnpm generate-keys` +HEXCLAVE_SERVER_SECRET=# a 32 bytes base64url encoded random string, used for JWT encryption. can be generated with `pnpm generate-keys` # seed script settings -STACK_SEED_INTERNAL_PROJECT_SIGN_UP_ENABLED=# true to enable user sign up to the dashboard when seeding -STACK_SEED_INTERNAL_PROJECT_OTP_ENABLED=# true to add OTP auth to the dashboard when seeding -STACK_SEED_INTERNAL_PROJECT_ALLOW_LOCALHOST=# true to allow running dashboard on the localhost, set this to true only in development -STACK_SEED_INTERNAL_PROJECT_OAUTH_PROVIDERS=# list of oauth providers to add to the dashboard when seeding, separated by comma, for example "github,google,facebook" -STACK_SEED_INTERNAL_PROJECT_USER_EMAIL=# default user added to the dashboard -STACK_SEED_INTERNAL_PROJECT_USER_PASSWORD=# default user's password, paired with STACK_SEED_INTERNAL_PROJECT_USER_EMAIL -STACK_SEED_INTERNAL_PROJECT_USER_INTERNAL_ACCESS=# if the default user has access to the internal dashboard project -STACK_SEED_INTERNAL_PROJECT_USER_GITHUB_ID=# add github oauth id to the default user +HEXCLAVE_SEED_INTERNAL_PROJECT_SIGN_UP_ENABLED=# true to enable user sign up to the dashboard when seeding +HEXCLAVE_SEED_INTERNAL_PROJECT_OTP_ENABLED=# true to add OTP auth to the dashboard when seeding +HEXCLAVE_SEED_INTERNAL_PROJECT_ALLOW_LOCALHOST=# true to allow running dashboard on the localhost, set this to true only in development +HEXCLAVE_SEED_INTERNAL_PROJECT_OAUTH_PROVIDERS=# list of oauth providers to add to the dashboard when seeding, separated by comma, for example "github,google,facebook" +HEXCLAVE_SEED_INTERNAL_PROJECT_USER_EMAIL=# default user added to the dashboard +HEXCLAVE_SEED_INTERNAL_PROJECT_USER_PASSWORD=# default user's password, paired with HEXCLAVE_SEED_INTERNAL_PROJECT_USER_EMAIL +HEXCLAVE_SEED_INTERNAL_PROJECT_USER_INTERNAL_ACCESS=# if the default user has access to the internal dashboard project +HEXCLAVE_SEED_INTERNAL_PROJECT_USER_GITHUB_ID=# add github oauth id to the default user # Set these if you want to use any email functionality -STACK_EMAILABLE_API_KEY=disable_email_validation -STACK_EMAIL_HOST= -STACK_EMAIL_PORT= -STACK_EMAIL_USERNAME= -STACK_EMAIL_PASSWORD= -STACK_EMAIL_SENDER= +HEXCLAVE_EMAILABLE_API_KEY=disable_email_validation +HEXCLAVE_EMAIL_HOST= +HEXCLAVE_EMAIL_PORT= +HEXCLAVE_EMAIL_USERNAME= +HEXCLAVE_EMAIL_PASSWORD= +HEXCLAVE_EMAIL_SENDER= # Set these if you want to use webhooks -STACK_SVIX_SERVER_URL=# this is only needed if you self-host the Svix service -NEXT_PUBLIC_STACK_SVIX_SERVER_URL=# this is only needed if you are using docker compose and the external and internal urls are different. This is the external url for the Svix service. -STACK_SVIX_API_KEY= +HEXCLAVE_SVIX_SERVER_URL=# this is only needed if you self-host the Svix service +NEXT_PUBLIC_HEXCLAVE_SVIX_SERVER_URL=# this is only needed if you are using docker compose and the external and internal urls are different. This is the external url for the Svix service. +HEXCLAVE_SVIX_API_KEY= -STACK_OPENROUTER_API_KEY=# enter your OpenRouter API key for AI features +HEXCLAVE_OPENROUTER_API_KEY=# enter your OpenRouter API key for AI features -STACK_SKIP_SEED_SCRIPT=# true to skip the seed script +HEXCLAVE_SKIP_SEED_SCRIPT=# true to skip the seed script -STACK_S3_ENDPOINT= -STACK_S3_REGION= -STACK_S3_ACCESS_KEY_ID= -STACK_S3_SECRET_ACCESS_KEY= -STACK_S3_BUCKET= -STACK_S3_PRIVATE_BUCKET= +HEXCLAVE_S3_ENDPOINT= +HEXCLAVE_S3_REGION= +HEXCLAVE_S3_ACCESS_KEY_ID= +HEXCLAVE_S3_SECRET_ACCESS_KEY= +HEXCLAVE_S3_BUCKET= +HEXCLAVE_S3_PRIVATE_BUCKET= -STACK_FREESTYLE_API_KEY=# enter your freestyle.sh api key +HEXCLAVE_FREESTYLE_API_KEY=# enter your freestyle.sh api key diff --git a/docker/server/.env.example b/docker/server/.env.example index cbba7e67c..db3e36024 100644 --- a/docker/server/.env.example +++ b/docker/server/.env.example @@ -1,20 +1,20 @@ -# IMPORTANT: YOU MUST REGENERATE THE STACK_SERVER_SECRET VALUE BELOW +# IMPORTANT: YOU MUST REGENERATE THE HEXCLAVE_SERVER_SECRET VALUE BELOW -NEXT_PUBLIC_STACK_API_URL=http://localhost:8102 -NEXT_PUBLIC_STACK_DASHBOARD_URL=http://localhost:8101 +NEXT_PUBLIC_HEXCLAVE_API_URL=http://localhost:8102 +NEXT_PUBLIC_HEXCLAVE_DASHBOARD_URL=http://localhost:8101 -STACK_DATABASE_CONNECTION_STRING=postgres://postgres:password@host.docker.internal:8128/stackframe +HEXCLAVE_DATABASE_CONNECTION_STRING=postgres://postgres:password@host.docker.internal:8128/stackframe -STACK_SERVER_SECRET=23-wuNpik0gIW4mruTz25rbIvhuuvZFrLOLtL7J4tyo +HEXCLAVE_SERVER_SECRET=23-wuNpik0gIW4mruTz25rbIvhuuvZFrLOLtL7J4tyo -STACK_SEED_INTERNAL_PROJECT_ALLOW_LOCALHOST=true -STACK_SEED_INTERNAL_PROJECT_SIGN_UP_ENABLED=true +HEXCLAVE_SEED_INTERNAL_PROJECT_ALLOW_LOCALHOST=true +HEXCLAVE_SEED_INTERNAL_PROJECT_SIGN_UP_ENABLED=true -STACK_RUN_MIGRATIONS=true -STACK_RUN_SEED_SCRIPT=true +HEXCLAVE_RUN_MIGRATIONS=true +HEXCLAVE_RUN_SEED_SCRIPT=true -STACK_FREESTYLE_API_KEY= +HEXCLAVE_FREESTYLE_API_KEY= -STACK_CLICKHOUSE_URL=http://host.docker.internal:8133 -STACK_CLICKHOUSE_ADMIN_PASSWORD=password -STACK_CLICKHOUSE_EXTERNAL_PASSWORD=password +HEXCLAVE_CLICKHOUSE_URL=http://host.docker.internal:8133 +HEXCLAVE_CLICKHOUSE_ADMIN_PASSWORD=password +HEXCLAVE_CLICKHOUSE_EXTERNAL_PASSWORD=password diff --git a/docker/server/entrypoint.sh b/docker/server/entrypoint.sh index 8d7653f46..e783a0227 100644 --- a/docker/server/entrypoint.sh +++ b/docker/server/entrypoint.sh @@ -13,6 +13,28 @@ if [ -f /run/stack-auth/rotated-secrets.env ]; then set +a fi +# ============= HEXCLAVE_ ↔ STACK_ ENV ALIASING ============= +# Hexclave rebrand: HEXCLAVE_*-prefixed env vars are canonical, but self-host +# operators (and older compose files) may still set the legacy STACK_* names. +# Node-side code dual-reads both, but this shell script and the sentinel +# substitution below look up vars by one exact name — so mirror every +# HEXCLAVE_*/STACK_* var to its unset twin. Called again right before the +# sentinel scan to pick up vars exported by the sections in between. +mirror_hexclave_stack_env() { + local _name _twin + for _name in $(compgen -e); do + case "$_name" in + *HEXCLAVE_*) _twin=${_name/HEXCLAVE_/STACK_} ;; + *STACK_*) _twin=${_name/STACK_/HEXCLAVE_} ;; + *) continue ;; + esac + if [ -z "${!_twin:-}" ] && [ -n "${!_name:-}" ]; then + export "$_twin=${!_name}" + fi + done +} +mirror_hexclave_stack_env + # ============= FORWARD MOCK OAUTH SERVER ============= # Start socat to forward port 32202 for mock-oauth-server if enabled @@ -45,39 +67,15 @@ if [ -n "${STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY:-}" ]; then export STACK_SUPER_SECRET_ADMIN_KEY=${STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY} fi -# ============= HEXCLAVE ↔ STACK URL ENV MIRROR ============= -# The dashboard bundle inlines BOTH process.env.NEXT_PUBLIC_HEXCLAVE_* and -# process.env.NEXT_PUBLIC_STACK_* references as sentinels (dual-read). At -# runtime the sentinel-replace loop only substitutes a sentinel when the -# corresponding env var is set — but the dashboard's fallback chain -# (`HEXCLAVE_X ?? STACK_X`) treats an unreplaced sentinel as truthy, so it -# would pick the literal sentinel string instead of the real URL whenever -# only one of the two env names is set by the self-host operator. -# Mirror the URL trio HEXCLAVE → STACK and STACK → HEXCLAVE before the -# sentinel-replace runs, so both sentinels resolve to the same real value -# regardless of which name the operator chose. -for _legacy in STACK_API_URL STACK_DASHBOARD_URL STACK_SVIX_SERVER_URL; do - _new=HEXCLAVE_${_legacy#STACK_} - _legacy_full=NEXT_PUBLIC_${_legacy} - _new_full=NEXT_PUBLIC_${_new} - _legacy_val=${!_legacy_full:-} - _new_val=${!_new_full:-} - if [ -n "$_new_val" ] && [ -z "$_legacy_val" ]; then - export "$_legacy_full=$_new_val" - elif [ -n "$_legacy_val" ] && [ -z "$_new_val" ]; then - export "$_new_full=$_legacy_val" - fi -done - export NEXT_PUBLIC_BROWSER_STACK_DASHBOARD_URL=${NEXT_PUBLIC_STACK_DASHBOARD_URL} # Hexclave rebrand: the port-prefix var was renamed outright to # NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX. The dashboard bundle's post-build sentinel # is STACK_ENV_VAR_SENTINEL_NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX, and the sentinel # substitution loop below derives the env var name from the sentinel — so this # MUST export NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX or the sentinel never resolves. -# Accept the legacy NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX as input for back-compat with +# Accept the legacy NEXT_PUBLIC_STACK_PORT_PREFIX as input for back-compat with # existing self-host configs. -export NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX=${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}} +export NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX=${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}} PORT_PREFIX=${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX} export NEXT_PUBLIC_SERVER_STACK_DASHBOARD_URL="http://localhost:${PORT_PREFIX}01" export NEXT_PUBLIC_BROWSER_STACK_API_URL=${NEXT_PUBLIC_STACK_API_URL} @@ -161,6 +159,14 @@ fi # ============= ENV VARS ============= +# Mirror again: the sections above exported more STACK_/HEXCLAVE_ vars (internal +# project keys, NEXT_PUBLIC_STACK_PROJECT_ID, svix fallback). The dashboard +# bundle inlines BOTH process.env.NEXT_PUBLIC_HEXCLAVE_* and +# process.env.NEXT_PUBLIC_STACK_* references as sentinels (dual-read), and the +# fallback chain treats an unreplaced sentinel as truthy — so both spellings +# must resolve to the same real value before the sentinel replacement below. +mirror_hexclave_stack_env + # Create a working directory for our processed files. # Keep this off /tmp so local-emulator config sharing can bind-mount /tmp # without pushing the whole runtime copy step onto the host filesystem. diff --git a/docs/.env b/docs/.env index 2102f16e4..3c5e8e1e8 100644 --- a/docs/.env +++ b/docs/.env @@ -1,6 +1,6 @@ # Basic -NEXT_PUBLIC_STACK_API_URL=# the base URL of Stack's backend/API -NEXT_PUBLIC_STACK_PROJECT_ID=# the project ID to use -NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=# publishable client key for the project -STACK_SECRET_SERVER_KEY=# secret server key for the project -STACK_OPENROUTER_API_KEY=# OpenRouter API key for AI-enabled chat \ No newline at end of file +NEXT_PUBLIC_HEXCLAVE_API_URL=# the base URL of Stack's backend/API +NEXT_PUBLIC_HEXCLAVE_PROJECT_ID=# the project ID to use +NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=# publishable client key for the project +HEXCLAVE_SECRET_SERVER_KEY=# secret server key for the project +HEXCLAVE_OPENROUTER_API_KEY=# OpenRouter API key for AI-enabled chat \ No newline at end of file diff --git a/docs/.env.development b/docs/.env.development index a5e11c9fa..3522244ce 100644 --- a/docs/.env.development +++ b/docs/.env.development @@ -1,7 +1,7 @@ # Contains the credentials for the internal project of Stack's default development environment setup. # Do not use in a production environment, instead replace it with actual values gathered from https://app.stack-auth.com. -NEXT_PUBLIC_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 -NEXT_PUBLIC_STACK_PROJECT_ID=internal -NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only -STACK_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only -STACK_OPENROUTER_API_KEY=your-open-router-api-key-for-ai-enabled-chat +NEXT_PUBLIC_HEXCLAVE_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +NEXT_PUBLIC_HEXCLAVE_PROJECT_ID=internal +NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +HEXCLAVE_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only +HEXCLAVE_OPENROUTER_API_KEY=your-open-router-api-key-for-ai-enabled-chat diff --git a/docs/code-examples/api-keys.ts b/docs/code-examples/api-keys.ts index 540efcef4..c4e198ded 100644 --- a/docs/code-examples/api-keys.ts +++ b/docs/code-examples/api-keys.ts @@ -735,9 +735,9 @@ export async function GET(request: Request) { code: `import { StackServerApp } from "@stackframe/js"; const stackServerApp = new StackServerApp({ - projectId: process.env.STACK_PROJECT_ID, - publishableClientKey: process.env.STACK_PUBLISHABLE_CLIENT_KEY, - secretServerKey: process.env.STACK_SECRET_SERVER_KEY, + projectId: process.env.HEXCLAVE_PROJECT_ID, + publishableClientKey: process.env.HEXCLAVE_PUBLISHABLE_CLIENT_KEY, + secretServerKey: process.env.HEXCLAVE_SECRET_SERVER_KEY, tokenStore: "memory", }); @@ -768,9 +768,9 @@ app.get('/api/protected', async (req, res) => { code: `import { StackServerApp } from "@stackframe/js"; const stackServerApp = new StackServerApp({ - projectId: process.env.STACK_PROJECT_ID, - publishableClientKey: process.env.STACK_PUBLISHABLE_CLIENT_KEY, - secretServerKey: process.env.STACK_SECRET_SERVER_KEY, + projectId: process.env.HEXCLAVE_PROJECT_ID, + publishableClientKey: process.env.HEXCLAVE_PUBLISHABLE_CLIENT_KEY, + secretServerKey: process.env.HEXCLAVE_SECRET_SERVER_KEY, tokenStore: "memory", }); @@ -929,9 +929,9 @@ export async function POST(request: Request) { code: `import { StackServerApp } from "@stackframe/js"; const stackServerApp = new StackServerApp({ - projectId: process.env.STACK_PROJECT_ID, - publishableClientKey: process.env.STACK_PUBLISHABLE_CLIENT_KEY, - secretServerKey: process.env.STACK_SECRET_SERVER_KEY, + projectId: process.env.HEXCLAVE_PROJECT_ID, + publishableClientKey: process.env.HEXCLAVE_PUBLISHABLE_CLIENT_KEY, + secretServerKey: process.env.HEXCLAVE_SECRET_SERVER_KEY, tokenStore: "memory", }); @@ -962,9 +962,9 @@ app.post('/api/team-protected', async (req, res) => { code: `import { StackServerApp } from "@stackframe/js"; const stackServerApp = new StackServerApp({ - projectId: process.env.STACK_PROJECT_ID, - publishableClientKey: process.env.STACK_PUBLISHABLE_CLIENT_KEY, - secretServerKey: process.env.STACK_SECRET_SERVER_KEY, + projectId: process.env.HEXCLAVE_PROJECT_ID, + publishableClientKey: process.env.HEXCLAVE_PUBLISHABLE_CLIENT_KEY, + secretServerKey: process.env.HEXCLAVE_SECRET_SERVER_KEY, tokenStore: "memory", }); diff --git a/docs/code-examples/setup.ts b/docs/code-examples/setup.ts index 8c3277669..567b95e15 100644 --- a/docs/code-examples/setup.ts +++ b/docs/code-examples/setup.ts @@ -187,9 +187,9 @@ export const stackClientApp = new StackClientApp({ code: `import { StackServerApp } from "@stackframe/js"; export const stackServerApp = new StackServerApp({ - projectId: process.env.STACK_PROJECT_ID, - publishableClientKey: process.env.STACK_PUBLISHABLE_CLIENT_KEY, - secretServerKey: process.env.STACK_SECRET_SERVER_KEY, + projectId: process.env.HEXCLAVE_PROJECT_ID, + publishableClientKey: process.env.HEXCLAVE_PUBLISHABLE_CLIENT_KEY, + secretServerKey: process.env.HEXCLAVE_SECRET_SERVER_KEY, tokenStore: "memory", });`, highlightLanguage: 'typescript', @@ -202,8 +202,8 @@ export const stackServerApp = new StackServerApp({ code: `import { StackClientApp } from "@stackframe/js"; export const stackClientApp = new StackClientApp({ - projectId: process.env.STACK_PROJECT_ID, - publishableClientKey: process.env.STACK_PUBLISHABLE_CLIENT_KEY, + projectId: process.env.HEXCLAVE_PROJECT_ID, + publishableClientKey: process.env.HEXCLAVE_PUBLISHABLE_CLIENT_KEY, tokenStore: "cookie", });`, highlightLanguage: 'typescript', @@ -216,9 +216,9 @@ export const stackClientApp = new StackClientApp({ code: `import { StackServerApp } from "@stackframe/js"; export const stackServerApp = new StackServerApp({ - projectId: process.env.STACK_PROJECT_ID, - publishableClientKey: process.env.STACK_PUBLISHABLE_CLIENT_KEY, - secretServerKey: process.env.STACK_SECRET_SERVER_KEY, + projectId: process.env.HEXCLAVE_PROJECT_ID, + publishableClientKey: process.env.HEXCLAVE_PUBLISHABLE_CLIENT_KEY, + secretServerKey: process.env.HEXCLAVE_SECRET_SERVER_KEY, tokenStore: "memory", });`, highlightLanguage: 'javascript', @@ -231,8 +231,8 @@ export const stackServerApp = new StackServerApp({ code: `import { StackClientApp } from "@stackframe/js"; export const stackClientApp = new StackClientApp({ - projectId: process.env.STACK_PROJECT_ID, - publishableClientKey: process.env.STACK_PUBLISHABLE_CLIENT_KEY, + projectId: process.env.HEXCLAVE_PROJECT_ID, + publishableClientKey: process.env.HEXCLAVE_PUBLISHABLE_CLIENT_KEY, tokenStore: "cookie", });`, highlightLanguage: 'javascript', diff --git a/docs/src/components/api/enhanced-api-page.tsx b/docs/src/components/api/enhanced-api-page.tsx index 774bc6c88..e5685018a 100644 --- a/docs/src/components/api/enhanced-api-page.tsx +++ b/docs/src/components/api/enhanced-api-page.tsx @@ -230,7 +230,7 @@ export function EnhancedAPIPage({ document, operations, description }: EnhancedA } // Use local API URL in development, production URL from OpenAPI spec otherwise const defaultBaseUrl = spec?.servers?.[0]?.url || ''; - const localApiUrl = process.env.NEXT_PUBLIC_HEXCLAVE_API_URL ?? process.env.NEXT_PUBLIC_STACK_API_URL; + const localApiUrl = process.env.NEXT_PUBLIC_HEXCLAVE_API_URL || process.env.NEXT_PUBLIC_STACK_API_URL; const baseUrl = localApiUrl ? localApiUrl + '/api/v1' : defaultBaseUrl; let url = baseUrl + path; @@ -439,7 +439,7 @@ function ModernAPIPlayground({ const generateCurlCommand = useCallback(() => { // Use local API URL in development, production URL otherwise const defaultBaseUrl = spec.servers?.[0]?.url || ''; - const localApiUrl = process.env.NEXT_PUBLIC_HEXCLAVE_API_URL ?? process.env.NEXT_PUBLIC_STACK_API_URL; + const localApiUrl = process.env.NEXT_PUBLIC_HEXCLAVE_API_URL || process.env.NEXT_PUBLIC_STACK_API_URL; const baseUrl = localApiUrl ? localApiUrl + '/api/v1' : defaultBaseUrl; @@ -492,7 +492,7 @@ function ModernAPIPlayground({ const generateJavaScriptCode = useCallback(() => { // Use local API URL in development, production URL otherwise const defaultBaseUrl = spec.servers?.[0]?.url || ''; - const localApiUrl = process.env.NEXT_PUBLIC_HEXCLAVE_API_URL ?? process.env.NEXT_PUBLIC_STACK_API_URL; + const localApiUrl = process.env.NEXT_PUBLIC_HEXCLAVE_API_URL || process.env.NEXT_PUBLIC_STACK_API_URL; const baseUrl = localApiUrl ? localApiUrl + '/api/v1' : defaultBaseUrl; @@ -554,7 +554,7 @@ function ModernAPIPlayground({ const generatePythonCode = useCallback(() => { // Use local API URL in development, production URL otherwise const defaultBaseUrl = spec.servers?.[0]?.url || ''; - const localApiUrl = process.env.NEXT_PUBLIC_HEXCLAVE_API_URL ?? process.env.NEXT_PUBLIC_STACK_API_URL; + const localApiUrl = process.env.NEXT_PUBLIC_HEXCLAVE_API_URL || process.env.NEXT_PUBLIC_STACK_API_URL; const baseUrl = localApiUrl ? localApiUrl + '/api/v1' : defaultBaseUrl; diff --git a/docs/src/components/chat/ai-chat.tsx b/docs/src/components/chat/ai-chat.tsx index 5c5456df7..ad7f4879a 100644 --- a/docs/src/components/chat/ai-chat.tsx +++ b/docs/src/components/chat/ai-chat.tsx @@ -351,7 +351,7 @@ export function AIChatDrawer() { const height = isHomePage && isScrolled ? 'h-[calc(100vh-1.5rem)]' : 'h-[calc(100vh-1.5rem)]'; const [input, setInput] = useState(''); - const apiBaseUrl = process.env.NEXT_PUBLIC_HEXCLAVE_API_URL ?? process.env.NEXT_PUBLIC_STACK_API_URL ?? throwErr("NEXT_PUBLIC_HEXCLAVE_API_URL or NEXT_PUBLIC_STACK_API_URL is not set"); + const apiBaseUrl = process.env.NEXT_PUBLIC_HEXCLAVE_API_URL || process.env.NEXT_PUBLIC_STACK_API_URL || throwErr("NEXT_PUBLIC_HEXCLAVE_API_URL or NEXT_PUBLIC_STACK_API_URL is not set"); const { messages, diff --git a/docs/src/stack.ts b/docs/src/stack.ts index e460d7056..9ab59f811 100644 --- a/docs/src/stack.ts +++ b/docs/src/stack.ts @@ -4,10 +4,10 @@ import "server-only"; // Explicitly configure Stack Auth for docs app export const stackServerApp = new StackServerApp({ tokenStore: "nextjs-cookie", - projectId: process.env.NEXT_PUBLIC_HEXCLAVE_PROJECT_ID ?? process.env.NEXT_PUBLIC_STACK_PROJECT_ID, - publishableClientKey: process.env.NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY ?? process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY, - secretServerKey: process.env.HEXCLAVE_SECRET_SERVER_KEY ?? process.env.STACK_SECRET_SERVER_KEY, - baseUrl: process.env.NEXT_PUBLIC_HEXCLAVE_API_URL ?? process.env.NEXT_PUBLIC_STACK_API_URL, + projectId: process.env.NEXT_PUBLIC_HEXCLAVE_PROJECT_ID || process.env.NEXT_PUBLIC_STACK_PROJECT_ID, + publishableClientKey: process.env.NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY || process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY, + secretServerKey: process.env.HEXCLAVE_SECRET_SERVER_KEY || process.env.STACK_SECRET_SERVER_KEY, + baseUrl: process.env.NEXT_PUBLIC_HEXCLAVE_API_URL || process.env.NEXT_PUBLIC_STACK_API_URL, analytics: { replays: { enabled: true, diff --git a/examples/cjs-test/.env.development b/examples/cjs-test/.env.development index 71efa0ca5..0a5589d48 100644 --- a/examples/cjs-test/.env.development +++ b/examples/cjs-test/.env.development @@ -1,6 +1,6 @@ # Contains the credentials for the internal project of Stack's default development environment setup. # Do not use in a production environment, instead replace it with actual values gathered from https://app.hexclave.com. -NEXT_PUBLIC_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 -NEXT_PUBLIC_STACK_PROJECT_ID=internal -NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only -STACK_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only +NEXT_PUBLIC_HEXCLAVE_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +NEXT_PUBLIC_HEXCLAVE_PROJECT_ID=internal +NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +HEXCLAVE_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only diff --git a/examples/convex/.env.development b/examples/convex/.env.development index ce9b6bbba..fe0499d9b 100644 --- a/examples/convex/.env.development +++ b/examples/convex/.env.development @@ -1,9 +1,9 @@ # Contains the credentials for the internal project of Stack's default development environment setup. # Do not use in a production environment, instead replace it with actual values gathered from https://app.hexclave.com. -NEXT_PUBLIC_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 -NEXT_PUBLIC_STACK_PROJECT_ID=internal -NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only -STACK_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only +NEXT_PUBLIC_HEXCLAVE_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +NEXT_PUBLIC_HEXCLAVE_PROJECT_ID=internal +NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +HEXCLAVE_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only CONVEX_DEPLOYMENT=anonymous:anonymous-convex-example NEXT_PUBLIC_CONVEX_URL=http://127.0.0.1:3210 diff --git a/examples/convex/convex/auth.config.ts b/examples/convex/convex/auth.config.ts index 282ef81ca..6cc1c62fb 100644 --- a/examples/convex/convex/auth.config.ts +++ b/examples/convex/convex/auth.config.ts @@ -2,7 +2,7 @@ import { getConvexProvidersConfig } from "@hexclave/next/convex-auth.config"; export default { providers: getConvexProvidersConfig({ - projectId: process.env.NEXT_PUBLIC_STACK_PROJECT_ID!, - baseUrl: process.env.NEXT_PUBLIC_STACK_API_URL, + projectId: (process.env.NEXT_PUBLIC_HEXCLAVE_PROJECT_ID || process.env.NEXT_PUBLIC_STACK_PROJECT_ID)!, + baseUrl: (process.env.NEXT_PUBLIC_HEXCLAVE_API_URL || process.env.NEXT_PUBLIC_STACK_API_URL), }), } diff --git a/examples/demo/.env b/examples/demo/.env index 13af3140c..073e30edd 100644 --- a/examples/demo/.env +++ b/examples/demo/.env @@ -1,3 +1,3 @@ -NEXT_PUBLIC_STACK_API_URL=# enter your stack endpoint here, e.g. http://localhost:8102 -NEXT_PUBLIC_STACK_PROJECT_ID=# enter your stack project id here -NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=# enter your stack publishable client key here +NEXT_PUBLIC_HEXCLAVE_API_URL=# enter your stack endpoint here, e.g. http://localhost:8102 +NEXT_PUBLIC_HEXCLAVE_PROJECT_ID=# enter your stack project id here +NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=# enter your stack publishable client key here diff --git a/examples/demo/.env.development b/examples/demo/.env.development index 749da5f8f..749b2d8c6 100644 --- a/examples/demo/.env.development +++ b/examples/demo/.env.development @@ -1,7 +1,7 @@ # Contains the credentials for the internal project of Stack's default development environment setup. # Do not use in a production environment, instead replace it with actual values gathered from https://app.hexclave.com. -NEXT_PUBLIC_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 -NEXT_PUBLIC_STACK_PROJECT_ID=internal -NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only -STACK_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only -NEXT_PUBLIC_STACK_HOSTED_HANDLER_URL_TEMPLATE=http://{projectId}.localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}09/{hostedPath} +NEXT_PUBLIC_HEXCLAVE_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +NEXT_PUBLIC_HEXCLAVE_PROJECT_ID=internal +NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +HEXCLAVE_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only +NEXT_PUBLIC_HEXCLAVE_HOSTED_HANDLER_URL_TEMPLATE=http://{projectId}.localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}09/{hostedPath} diff --git a/examples/demo/cli-sim.mjs b/examples/demo/cli-sim.mjs index ef4437fbb..2fb7b6d8e 100644 --- a/examples/demo/cli-sim.mjs +++ b/examples/demo/cli-sim.mjs @@ -2,8 +2,8 @@ /** Minimal `stack login` flow for local demos. Usage: `node cli-sim.mjs` */ -const API_URL = process.env.STACK_API_URL || "http://localhost:8102"; -const APP_URL = process.env.STACK_APP_URL || "http://localhost:8103"; +const API_URL = (process.env.HEXCLAVE_API_URL || process.env.STACK_API_URL) || "http://localhost:8102"; +const APP_URL = (process.env.HEXCLAVE_APP_URL || process.env.STACK_APP_URL) || "http://localhost:8103"; const PROJECT_ID = "internal"; const PUBLISHABLE_KEY = "this-publishable-client-key-is-for-local-development-only"; diff --git a/examples/demo/src/app/turnstile-signup/page-client.tsx b/examples/demo/src/app/turnstile-signup/page-client.tsx index 9a60df186..2d619177a 100644 --- a/examples/demo/src/app/turnstile-signup/page-client.tsx +++ b/examples/demo/src/app/turnstile-signup/page-client.tsx @@ -66,8 +66,8 @@ function getDebugInternals(app: ReturnType): { } function getDemoApiUrl(): string { - const baseUrl = process.env.NEXT_PUBLIC_STACK_API_URL - ?? process.env.NEXT_PUBLIC_STACK_URL; + const baseUrl = (process.env.NEXT_PUBLIC_HEXCLAVE_API_URL || process.env.NEXT_PUBLIC_STACK_API_URL) + ?? (process.env.NEXT_PUBLIC_HEXCLAVE_URL || process.env.NEXT_PUBLIC_STACK_URL); if (typeof baseUrl !== "string" || baseUrl.length === 0) { throw new Error("Expected NEXT_PUBLIC_STACK_API_URL to be configured for Turnstile OAuth debug flows"); @@ -301,8 +301,8 @@ export default function TurnstileSignupPageClient() { const signInWithTokens = internals.signInWithTokens; const apiUrl = getDemoApiUrl(); const oauthClientSecret = app[hexclaveAppInternalsSymbol].toClientJson().publishableClientKey - ?? process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY - ?? process.env.STACK_PUBLISHABLE_CLIENT_KEY + ?? (process.env.NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY || process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY) + ?? (process.env.HEXCLAVE_PUBLISHABLE_CLIENT_KEY || process.env.STACK_PUBLISHABLE_CLIENT_KEY) ?? publishableClientKeyNotNecessarySentinel; useEffect(() => { diff --git a/examples/docs-examples/.env b/examples/docs-examples/.env index b86f8d97c..6910c859f 100644 --- a/examples/docs-examples/.env +++ b/examples/docs-examples/.env @@ -1,4 +1,4 @@ -NEXT_PUBLIC_STACK_API_URL=# enter your stack endpoint here, e.g. http://localhost:8102 -NEXT_PUBLIC_STACK_PROJECT_ID=# enter your stack project id here -NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=# enter your stack publishable client key here -STACK_SECRET_SERVER_KEY=# enter your stack secret server key here +NEXT_PUBLIC_HEXCLAVE_API_URL=# enter your stack endpoint here, e.g. http://localhost:8102 +NEXT_PUBLIC_HEXCLAVE_PROJECT_ID=# enter your stack project id here +NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=# enter your stack publishable client key here +HEXCLAVE_SECRET_SERVER_KEY=# enter your stack secret server key here diff --git a/examples/docs-examples/.env.development b/examples/docs-examples/.env.development index 71efa0ca5..0a5589d48 100644 --- a/examples/docs-examples/.env.development +++ b/examples/docs-examples/.env.development @@ -1,6 +1,6 @@ # Contains the credentials for the internal project of Stack's default development environment setup. # Do not use in a production environment, instead replace it with actual values gathered from https://app.hexclave.com. -NEXT_PUBLIC_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 -NEXT_PUBLIC_STACK_PROJECT_ID=internal -NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only -STACK_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only +NEXT_PUBLIC_HEXCLAVE_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +NEXT_PUBLIC_HEXCLAVE_PROJECT_ID=internal +NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +HEXCLAVE_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only diff --git a/examples/e-commerce/.env.development b/examples/e-commerce/.env.development index 71efa0ca5..0a5589d48 100644 --- a/examples/e-commerce/.env.development +++ b/examples/e-commerce/.env.development @@ -1,6 +1,6 @@ # Contains the credentials for the internal project of Stack's default development environment setup. # Do not use in a production environment, instead replace it with actual values gathered from https://app.hexclave.com. -NEXT_PUBLIC_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 -NEXT_PUBLIC_STACK_PROJECT_ID=internal -NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only -STACK_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only +NEXT_PUBLIC_HEXCLAVE_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +NEXT_PUBLIC_HEXCLAVE_PROJECT_ID=internal +NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +HEXCLAVE_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only diff --git a/examples/js-example/.env.development b/examples/js-example/.env.development index 0fc4ae5b8..5a2162e5c 100644 --- a/examples/js-example/.env.development +++ b/examples/js-example/.env.development @@ -1,10 +1,10 @@ # Contains the credentials for the internal project of Stack's default development environment setup. # Do not use in a production environment, instead replace it with actual values gathered from https://app.hexclave.com. -NEXT_PUBLIC_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 -NEXT_PUBLIC_STACK_PROJECT_ID=internal -NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only -STACK_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only +NEXT_PUBLIC_HEXCLAVE_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +NEXT_PUBLIC_HEXCLAVE_PROJECT_ID=internal +NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +HEXCLAVE_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only -VITE_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 -VITE_STACK_PROJECT_ID=internal -VITE_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +VITE_HEXCLAVE_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +VITE_HEXCLAVE_PROJECT_ID=internal +VITE_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only diff --git a/examples/lovable-react-18-example/.env.development b/examples/lovable-react-18-example/.env.development index ebcc0ec8b..a0f926fad 100644 --- a/examples/lovable-react-18-example/.env.development +++ b/examples/lovable-react-18-example/.env.development @@ -1,6 +1,6 @@ # Contains the credentials for the internal project of Stack's default development environment setup. # Do not use in a production environment, instead replace it with actual values gathered from https://app.hexclave.com. -VITE_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 -VITE_STACK_PROJECT_ID=internal -VITE_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +VITE_HEXCLAVE_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +VITE_HEXCLAVE_PROJECT_ID=internal +VITE_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only diff --git a/examples/middleware/.env b/examples/middleware/.env index b86f8d97c..6910c859f 100644 --- a/examples/middleware/.env +++ b/examples/middleware/.env @@ -1,4 +1,4 @@ -NEXT_PUBLIC_STACK_API_URL=# enter your stack endpoint here, e.g. http://localhost:8102 -NEXT_PUBLIC_STACK_PROJECT_ID=# enter your stack project id here -NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=# enter your stack publishable client key here -STACK_SECRET_SERVER_KEY=# enter your stack secret server key here +NEXT_PUBLIC_HEXCLAVE_API_URL=# enter your stack endpoint here, e.g. http://localhost:8102 +NEXT_PUBLIC_HEXCLAVE_PROJECT_ID=# enter your stack project id here +NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=# enter your stack publishable client key here +HEXCLAVE_SECRET_SERVER_KEY=# enter your stack secret server key here diff --git a/examples/middleware/.env.development b/examples/middleware/.env.development index 71efa0ca5..0a5589d48 100644 --- a/examples/middleware/.env.development +++ b/examples/middleware/.env.development @@ -1,6 +1,6 @@ # Contains the credentials for the internal project of Stack's default development environment setup. # Do not use in a production environment, instead replace it with actual values gathered from https://app.hexclave.com. -NEXT_PUBLIC_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 -NEXT_PUBLIC_STACK_PROJECT_ID=internal -NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only -STACK_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only +NEXT_PUBLIC_HEXCLAVE_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +NEXT_PUBLIC_HEXCLAVE_PROJECT_ID=internal +NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +HEXCLAVE_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only diff --git a/examples/react-example/.env.development b/examples/react-example/.env.development index ebcc0ec8b..a0f926fad 100644 --- a/examples/react-example/.env.development +++ b/examples/react-example/.env.development @@ -1,6 +1,6 @@ # Contains the credentials for the internal project of Stack's default development environment setup. # Do not use in a production environment, instead replace it with actual values gathered from https://app.hexclave.com. -VITE_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 -VITE_STACK_PROJECT_ID=internal -VITE_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +VITE_HEXCLAVE_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +VITE_HEXCLAVE_PROJECT_ID=internal +VITE_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only diff --git a/examples/supabase/.env.development b/examples/supabase/.env.development index 05208342a..cb7fd515a 100644 --- a/examples/supabase/.env.development +++ b/examples/supabase/.env.development @@ -4,7 +4,7 @@ SUPABASE_JWT_SECRET=supabase-jwt-secret # Contains the credentials for the internal project of Stack's default development environment setup. # Do not use in a production environment, instead replace it with actual values gathered from https://app.hexclave.com. -NEXT_PUBLIC_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 -NEXT_PUBLIC_STACK_PROJECT_ID=internal -NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only -STACK_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only +NEXT_PUBLIC_HEXCLAVE_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +NEXT_PUBLIC_HEXCLAVE_PROJECT_ID=internal +NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +HEXCLAVE_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only diff --git a/examples/tanstack-start-demo/.env.development b/examples/tanstack-start-demo/.env.development index 12439a472..e7c5770fe 100644 --- a/examples/tanstack-start-demo/.env.development +++ b/examples/tanstack-start-demo/.env.development @@ -1,3 +1,3 @@ -VITE_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 -VITE_STACK_PROJECT_ID=internal -VITE_STACK_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only +VITE_HEXCLAVE_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02 +VITE_HEXCLAVE_PROJECT_ID=internal +VITE_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only diff --git a/packages/cli/src/lib/auth.ts b/packages/cli/src/lib/auth.ts index 5b1c20d3b..03715dd10 100644 --- a/packages/cli/src/lib/auth.ts +++ b/packages/cli/src/lib/auth.ts @@ -52,7 +52,7 @@ function resolveRefreshToken(): string { } function resolveSecretServerKey(): string | null { - return process.env.HEXCLAVE_SECRET_SERVER_KEY ?? process.env.STACK_SECRET_SERVER_KEY ?? null; + return process.env.HEXCLAVE_SECRET_SERVER_KEY || process.env.STACK_SECRET_SERVER_KEY || null; } export function resolveLoginConfig(): LoginConfig { diff --git a/packages/shared/src/utils/env.tsx b/packages/shared/src/utils/env.tsx index 2ee01c58d..900da02fc 100644 --- a/packages/shared/src/utils/env.tsx +++ b/packages/shared/src/utils/env.tsx @@ -51,15 +51,17 @@ export function getEnvVariable(name: string, defaultValue?: string | undefined): } // Hexclave rebrand: prefer the HEXCLAVE_*-prefixed equivalent, fall back to the STACK_* name. + // Treat the empty string as unset — the checked-in .env templates define empty + // HEXCLAVE_* placeholders, which must not shadow a real value under the legacy name. const hexclaveName = getHexclaveEnvVarName(name); - let value = (hexclaveName ? process.env[hexclaveName] : undefined) ?? process.env[name]; + let value = (hexclaveName ? process.env[hexclaveName] : undefined) || process.env[name]; // check the key under the old name if the new name is not found if (!value && ENV_VAR_RENAME[name] as any) { for (const oldName of ENV_VAR_RENAME[name]) { // Hexclave rebrand: also accept the HEXCLAVE_*-prefixed equivalent of each old alias. const hexclaveOldName = getHexclaveEnvVarName(oldName); - value = (hexclaveOldName ? process.env[hexclaveOldName] : undefined) ?? process.env[oldName]; + value = (hexclaveOldName ? process.env[hexclaveOldName] : undefined) || process.env[oldName]; if (value) break; } } diff --git a/packages/template/scripts/generate-env.ts b/packages/template/scripts/generate-env.ts index 666251e8a..022077df2 100644 --- a/packages/template/scripts/generate-env.ts +++ b/packages/template/scripts/generate-env.ts @@ -69,11 +69,14 @@ function generateEnvVarsConstSnippet() { const allVariables = [key, ...(config.deprecatedLegacyNames ?? [])] .flatMap(k => k.startsWith("HEXCLAVE_") ? [k, k.replace("HEXCLAVE_", "STACK_")] : [k]) .flatMap(k => config.allowPublic ? [k, `NEXT_PUBLIC_${k}`, `VITE_${k}`] : [k]); + // Use || (not ??) between candidates: empty-string env vars (e.g. the empty + // HEXCLAVE_* placeholders in checked-in .env templates) must not shadow a + // real value under a legacy STACK_* name further down the chain. getters.push(deindent` get ${key}() { return ${allVariables.map(variableName => deindent` - ((typeof process !== "undefined" ? process.env.${variableName} : undefined) ?? import.meta.env?.${variableName}) - `).join("\n ?? ")} ?? undefined; + ((typeof process !== "undefined" ? process.env.${variableName} : undefined) || import.meta.env?.${variableName}) + `).join("\n || ")} || undefined; }, `); }