mirror of
https://github.com/civitai/civitai.git
synced 2026-09-20 22:08:18 +08:00
2048057ca2
Two textual conflicts, and three that only the test run found. `TryItForm.tsx` was a directory-rename artifact: this branch moved `src/components/Moderator/` into `@civitai/mod-utils`, so git placed main's new file in the moved location. Kept main's path, which is what `src/pages/moderator/api.tsx` imports. `check-writable.mjs` is theirs plus this branch's two extra rules. Main tightened three convention ledgers while this branch added code that violates them. None conflicted textually: - `image.controller.ts` imported `request-ip` directly. The ledger holds one entry and names `client-ip.ts` the sanctioned home for the library fallback, so a second entry is not the escape hatch. Switched to the attribution derivation, `resolveClientIpOrNull` — which changes which address lands on the spoke's image-moderation audit row. - The same file forwarded the spoke's `.message` at a 4xx without `cause`, blinding `isDriverAuthoredMessage` to the chain. - `remove-placement.ts` hand-rolled what `handleEndpointError` already does. - `moderator-endpoint.test.ts` mocked `~/server/redis/client` itself instead of declaring behaviour on the canonical mock. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
213 lines
7.1 KiB
Plaintext
213 lines
7.1 KiB
Plaintext
# Since .env is gitignored, you can use .env-example to build a new `.env` file when you clone the repo.
|
|
# Keep this file up-to-date when you add new variables to `.env`.
|
|
# This file will be committed to version control, so make sure not to have any secrets in it.
|
|
# If you are cloning this repo, create a copy of this file named `.env` and populate it with your secrets.
|
|
# When adding additional env variables, the schema in /env/schema.mjs should be updated accordingly
|
|
# The default values for Prisma, Redis, S3, and Email are set to work with the docker-compose setup
|
|
|
|
# Database
|
|
DATABASE_SSL=false
|
|
DATABASE_URL=postgresql://postgres:postgres@localhost:15432/civitai
|
|
DATABASE_REPLICA_URL=postgresql://postgres:postgres@localhost:15432/civitai
|
|
|
|
NOTIFICATION_DB_URL=postgresql://postgres:postgres@localhost:15434/postgres
|
|
NOTIFICATION_DB_REPLICA_URL=postgresql://postgres:postgres@localhost:15434/postgres
|
|
|
|
DATAPACKET_DATABASE_RO_URL=postgresql://postgres:postgres@localhost:15435/postgres
|
|
|
|
# Redis
|
|
REDIS_URL=redis://:redis@localhost:6379
|
|
REDIS_SYS_URL=redis://:redis@localhost:6378
|
|
# Optional: switch the `system` redis client to Sentinel mode. When set, REDIS_SYS_URL
|
|
# is still parsed for credentials but the connection is established via Sentinel.
|
|
# REDIS_SYS_SENTINELS=localhost:26379,localhost:26380,localhost:26381
|
|
# REDIS_SYS_SENTINEL_NAME=sysmaster # production uses "sysmaster"; match the master group your Sentinel CR declares
|
|
|
|
# Logging
|
|
LOGGING=prisma:error,prisma:warn,seed-metrics-search
|
|
|
|
# Next Auth
|
|
NEXTAUTH_SECRET=thisisnotasecret
|
|
NEXTAUTH_URL=http://localhost:3000
|
|
|
|
# Next Auth Discord Provider
|
|
DISCORD_CLIENT_ID=
|
|
DISCORD_CLIENT_SECRET=
|
|
|
|
# Next Auth GitHub Provider
|
|
GITHUB_CLIENT_ID=
|
|
GITHUB_CLIENT_SECRET=
|
|
|
|
# Next Auth Google Provider
|
|
GOOGLE_CLIENT_ID=
|
|
GOOGLE_CLIENT_SECRET=
|
|
|
|
# Next Auth Reddit Provider
|
|
REDDIT_CLIENT_ID=
|
|
REDDIT_CLIENT_SECRET=
|
|
|
|
# Integrations
|
|
DISCORD_BOT_TOKEN=
|
|
DISCORD_GUILD_ID=
|
|
DISCORD_WEBHOOK_MOD_ALERTS=
|
|
|
|
# File uploading
|
|
S3_UPLOAD_KEY=REFER_TO_README
|
|
S3_UPLOAD_SECRET=REFER_TO_README
|
|
S3_UPLOAD_BUCKET=modelshare
|
|
S3_UPLOAD_REGION=us-east-1
|
|
S3_UPLOAD_ENDPOINT=http://127.0.0.1:9000
|
|
|
|
# Image uploading
|
|
S3_IMAGE_UPLOAD_KEY=
|
|
S3_IMAGE_UPLOAD_SECRET=
|
|
S3_IMAGE_UPLOAD_BUCKET=images
|
|
S3_IMAGE_UPLOAD_REGION=us-east-1
|
|
S3_IMAGE_UPLOAD_ENDPOINT=http://127.0.0.1:9000
|
|
S3_IMAGE_CACHE_BUCKET=cache
|
|
S3_IMAGE_UPLOAD_OVERRIDE=
|
|
|
|
# Client env vars
|
|
NEXT_PUBLIC_IMAGE_LOCATION=http://localhost:3000
|
|
NEXT_PUBLIC_CIVITAI_LINK=http://localhost:3000
|
|
NEXT_PUBLIC_UI_HOMEPAGE_IMAGES=false
|
|
|
|
# Clickhouse
|
|
CLICKHOUSE_HOST=http://localhost:18123
|
|
CLICKHOUSE_USERNAME=default
|
|
CLICKHOUSE_PASSWORD=
|
|
CLICKHOUSE_TRACKER_URL=http://localhost:3000
|
|
|
|
# Email
|
|
EMAIL_HOST=localhost
|
|
EMAIL_PORT=1025
|
|
EMAIL_USER=
|
|
EMAIL_PASS=
|
|
EMAIL_FROM=
|
|
|
|
# Endpoint Protection
|
|
JOB_TOKEN=thisisnotatoken
|
|
WEBHOOK_TOKEN=thisisnotatoken
|
|
# Base URL of the standalone moderator app (apps/moderator). Migrated /moderator/* routes redirect here
|
|
# via the moderator catchall page. Defaults to https://moderator.civitai.com if unset.
|
|
MODERATOR_APP_URL=https://moderator.civitai.com
|
|
|
|
# Site Configuration
|
|
UNAUTHENTICATED_DOWNLOAD=true
|
|
UNAUTHENTICATED_LIST_NSFW=false
|
|
SHOW_SFW_IN_NSFW=false
|
|
MAINTENANCE_MODE=false
|
|
RATE_LIMITING=true
|
|
TRPC_ORIGINS=
|
|
|
|
# Security
|
|
SCANNING_ENDPOINT=http://scan-me.civitai.com/enqueue
|
|
SCANNING_TOKEN=thisisnotatoken
|
|
|
|
# Delivery worker
|
|
DELIVERY_WORKER_ENDPOINT=https://delivery-worker.civitai.com/download
|
|
DELIVERY_WORKER_TOKEN=thisisnotatoken
|
|
|
|
# Payments
|
|
PADDLE_SECRET_KEY=thisisnotasecret
|
|
PADDLE_WEBHOOK_SECRET=thisisnotasecret
|
|
NEXT_PUBLIC_PADDLE_TOKEN=thisisnotatoken
|
|
NEXT_PUBLIC_DEFAULT_PAYMENT_PROVIDER=Paddle
|
|
|
|
# Features
|
|
FEATURE_FLAG_EARLY_ACCESS_MODEL=public
|
|
|
|
# MeiliSearch
|
|
SEARCH_HOST=http://localhost:7700
|
|
SEARCH_API_KEY=meilisearch
|
|
NEXT_PUBLIC_SEARCH_HOST=http://localhost:7700
|
|
NEXT_PUBLIC_SEARCH_CLIENT_KEY=meilisearch
|
|
|
|
METRICS_SEARCH_HOST=http://localhost:7700
|
|
METRICS_SEARCH_API_KEY=meilisearch
|
|
|
|
# Debounce window (ms) for flushing model-metric-affected ids into the model
|
|
# search-index update queue. Widening it collapses more of a hot model's repeated
|
|
# metric changes into a single reindex (cost: metric/popularity staleness lags by
|
|
# up to the window). Fail-soft: a bad value falls back to the 45m default. Requires
|
|
# a restart/rollout to take effect. Default 45m.
|
|
# SEARCH_INDEX_MODEL_METRIC_FLUSH_INTERVAL_MS=2700000
|
|
|
|
# Per-call Meilisearch timeout in ms. Calls wrapped via withMeili() fail fast
|
|
# with MeiliCallTimeoutError once exceeded, instead of hanging until Traefik's
|
|
# 30s router timeout fires.
|
|
MEILI_CALL_TIMEOUT_MS=2500
|
|
# Per-pod cap on in-flight Meilisearch calls wrapped via withMeili(). Excess
|
|
# calls fail fast with MeiliCallTimeoutError instead of queueing forever.
|
|
MEILI_CALL_CONCURRENCY=50
|
|
|
|
# Per-backend circuit breaker. If MEILI_CIRCUIT_TRIP_THRESHOLD wrapped-call
|
|
# timeouts accumulate within MEILI_CIRCUIT_WINDOW_SECONDS on a backend, the
|
|
# circuit OPENs and all calls fail at 0ms for MEILI_CIRCUIT_COOLDOWN_SECONDS,
|
|
# then HALF_OPEN issues a single trial request. healthProbe is excluded.
|
|
MEILI_CIRCUIT_TRIP_THRESHOLD=10
|
|
MEILI_CIRCUIT_WINDOW_SECONDS=30
|
|
MEILI_CIRCUIT_COOLDOWN_SECONDS=30
|
|
|
|
# BaseURL
|
|
NEXT_PUBLIC_BASE_URL=http://localhost:3000
|
|
|
|
# Recaptcha
|
|
RECAPTCHA_PROJECT_ID=aSampleKey
|
|
NEXT_PUBLIC_RECAPTCHA_KEY=aSampleKey
|
|
|
|
# CF Turnstile
|
|
NEXT_PUBLIC_CLOUDFLARE_TURNSTILE_SITEKEY=1x00000000000000000000BB
|
|
CLOUDFLARE_TURNSTILE_SECRET=1x0000000000000000000000000000000AA
|
|
|
|
NEXT_PUBLIC_CF_INVISIBLE_TURNSTILE_SITEKEY=1x00000000000000000000BB
|
|
CF_INVISIBLE_TURNSTILE_SECRET=1x0000000000000000000000000000000AA
|
|
|
|
NEXT_PUBLIC_CF_MANAGED_TURNSTILE_SITEKEY=1x00000000000000000000AA
|
|
CF_MANAGED_TURNSTILE_SECRET=1x0000000000000000000000000000000AA
|
|
|
|
ORCHESTRATOR_ENDPOINT=http://localhost
|
|
ORCHESTRATOR_ACCESS_TOKEN=asdf
|
|
|
|
BUZZ_ENDPOINT=http://localhost
|
|
SIGNALS_ENDPOINT=http://localhost
|
|
NEXT_PUBLIC_SIGNALS_ENDPOINT=http://localhost
|
|
|
|
NOW_PAYMENTS_API_URL=http://localhost
|
|
NOW_PAYMENTS_API_KEY=key
|
|
NOW_PAYMENTS_IPN_KEY=key
|
|
|
|
COINBASE_API_URL=http://localhost
|
|
COINBASE_API_KEY=key
|
|
COINBASE_WEBHOOK_SECRET=secret
|
|
|
|
EMERCHANTPAY_WPF_URL=
|
|
EMERCHANTPAY_USERNAME=
|
|
EMERCHANTPAY_PASSWORD=
|
|
|
|
# Shopify merch store — Blue Buzz reward loop
|
|
# SHOPIFY_SHOP_DOMAIN = the *.myshopify.com admin domain (e.g. ff1592-5.myshopify.com)
|
|
SHOPIFY_SHOP_DOMAIN=
|
|
SHOPIFY_WEBHOOK_SECRET=
|
|
# Admin auth: client_credentials grant (preferred). Set ADMIN_TOKEN instead only for a static token.
|
|
SHOPIFY_CLIENT_ID=
|
|
SHOPIFY_CLIENT_SECRET=
|
|
SHOPIFY_ADMIN_TOKEN=
|
|
|
|
FLIPT_URL=""
|
|
FLIPT_FETCHER_SECRET=placeholder
|
|
|
|
IMAGE_SCANNER_NEW=false
|
|
|
|
# App Blocks — per-app generation spend/velocity ABSOLUTE CEILINGS (incident knobs).
|
|
# 🔴 These are UPPER BOUNDS, not the limit an app receives. Each app's actual
|
|
# ceilings come from its server-owned `spendTier` (+ any moderator per-app
|
|
# override); these clamp the tier table AND any override from above, so setting
|
|
# one TIGHTENS every app and can never loosen one. Unset = no extra clamp.
|
|
# Formerly BLOCK_APP_SPEND_CAP_BUZZ_PER_DAY / BLOCK_APP_SPEND_VELOCITY_MAX_GENS —
|
|
# those names are DEPRECATED but still honoured (with a startup warning).
|
|
# BLOCK_APP_SPEND_ABSOLUTE_MAX_BUZZ_PER_DAY=
|
|
# BLOCK_APP_SPEND_ABSOLUTE_MAX_GENS_PER_WINDOW=
|
|
# Window (seconds) the gens-per-window ceiling is measured over. Default 60.
|
|
# BLOCK_APP_SPEND_VELOCITY_WINDOW_SECONDS=
|