mirror of
https://github.com/ever-co/ever-gauzy.git
synced 2026-10-02 01:54:50 +08:00
A re-verification of every draft and published advisory against develop found 9 fully closed and 8
with residuals. This closes the code-fixable ones. Three patterns cover almost all of them:
1. `{ id, ...body }` — the body wins. A path id spread BEFORE the body is overridden by a body `id`,
and save()/create() with an existing PK is an UPDATE of that row: every authorization check ran
against the path id while the write hit the body id. On PUT /user/:id that is account takeover
(a PROFILE_EDIT employee posts {"id":"<SUPER_ADMIN>","hash":"..."}). The id is now pinned LAST in
all 25 controllers/handlers with that shape, UserService.updateProfile pins entity.id = id, and
TenantAwareCrudService.create/save/createMany/saveMany refuse an entity whose id already names a
row of ANOTHER tenant (or a tenant-less row) — the update-through-create endpoints had no other
ownership check. (GHSA-x4mv-fhwj-g3rp, GHSA-gwpq-mmw7-vx85)
2. A client-supplied value decides an authorization branch. The register handler gated "only a
SUPER_ADMIN may register a SUPER_ADMIN" on input.user.role.name, and POST /user had no gate at
all. Both now resolve EVERY role identifier (the flat roleId and the role relation — the relation
wins on persist) from the database in the caller's tenant and fail closed on an id that does not
resolve. (GHSA-hjcg-633x-qq74, GHSA-x4mv-fhwj-g3rp)
3. Only the root row is tenant-scoped. SharedEntity turned caller-supplied shareRules.relations
straight into TypeORM relations on a @Public() token route, so a share of an OWNED Organization
could pivot featureOrganizations -> feature -> featureOrganizations -> tenant -> organizations ->
employees -> user into every tenant. Relations are now validated against entity metadata (each hop
must exist AND target a tenant-scoped entity), depth-bounded, joined rows are scope-filtered,
tenant-less roots are refused, and create/update bodies are whitelisted. (GHSA-cx2q-xmh2-pc38,
GHSA-gpg5-qwjc-8hqh)
Also:
- /invite/accept mass-assignment: AuthService.register strips id/hash/emailVerifiedAt/emailToken/
code/codeExpireAt/refreshToken from input.user, honours createdByUserId only for the authenticated
caller, pins user.tenantId to the trusted tenant; invite accept pins the invited email.
(GHSA-929w-5p4w-cxjp)
- TimeOffStatusHandler used raw repositories with no tenant scope (an admin of tenant A could
approve/deny tenant B's requests); equipment-sharing deleted the request_approval row unscoped, and
its status change went through an update() that deletes and re-inserts — a { status }-only body
replaced the record with a stub. (GHSA-gwpq-mmw7-vx85)
- Hubstaff /refresh-token no longer returns the refresh token. (GHSA-3rqg-gpm9-gx84)
- Upload filters on the endpoints that had none: POST /import (archive allowlist), POST
/ai-chat/attachments and the 5 registry upload routes (script-capable-extension denylist).
(GHSA-p334-cm7f-php5)
- docker-compose defaults NODE_ENV to production so the insecure-secret guard actually fires (compose
`environment:` overrode .env.compose and the image ENV); render blueprints generate their secrets
instead of shipping secretKey/refreshSecretKey/gauzy, and the CORP policy is overridable
(CORP_POLICY) because API and webapp live on two different *.onrender.com sites.
(GHSA-chm8-2ggf-pgjq)
And a functional bug found on the way: POST /ai-chat/attachments was broken on the default LOCAL file
provider. It used Nest's @UploadedFile(), which hands over multer's diskStorage object — no `key` (only
core's @UploadedFileStorage() maps it through provider.mapUploadedFile, where LOCAL derives key from
path) — so the service threw 400 AFTER the bytes were written, leaving an orphan. It now uses the core
decorator, never puts a browser-renderable extension on the stored object name, and deletes the stored
object when the upload is rejected (service) or when sniffFile rejects it (docs chat-capture).
PUT /product-types/:id was likewise a silent 400 for every caller (a DTO instance was passed to
EntityManager.save, which resolves metadata from the constructor); it now saves with an explicit
entity target under the verified id.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
628 lines
18 KiB
Bash
628 lines
18 KiB
Bash
# Docker Compose sample .env file for Production
|
|
|
|
NODE_ENV=production
|
|
|
|
# The name of the application.
|
|
APP_NAME="Gauzy"
|
|
|
|
# The URL for the application logo.
|
|
APP_LOGO="http://localhost:4200/assets/images/logos/logo_Gauzy.png"
|
|
|
|
# The signature or tagline for the application.
|
|
APP_SIGNATURE="Gauzy"
|
|
|
|
# The link to the application.
|
|
APP_LINK="http://localhost:4200"
|
|
|
|
# The URL for email confirmation in the application.
|
|
APP_EMAIL_CONFIRMATION_URL="http://localhost:4200/#/auth/confirm-email"
|
|
|
|
# The URL for magic sign-in in the application.
|
|
APP_MAGIC_SIGN_URL="http://localhost:4200/#/auth/magic-sign-in"
|
|
|
|
# set true if running inside Docker container
|
|
IS_DOCKER=true
|
|
|
|
# API Host
|
|
API_HOST=api
|
|
|
|
# API Port
|
|
API_PORT=3000
|
|
|
|
# WEB UI Host
|
|
WEB_HOST=webapp
|
|
|
|
# WEB UI Port
|
|
WEB_PORT=4200
|
|
|
|
# set true if running as a Demo
|
|
DEMO=false
|
|
|
|
# DO (DIGITALOCEAN), AWS, AZURE, CIVO, CW (COREWEAVE), HEROKU, LINODE, LOCAL, OVH, SCALEWAY, VULTR, etc
|
|
CLOUD_PROVIDER=
|
|
|
|
ALLOW_SUPER_ADMIN_ROLE=true
|
|
|
|
# set to Gauzy API base URL
|
|
API_BASE_URL=http://localhost:3000
|
|
|
|
# set to Gauzy UI base URL
|
|
CLIENT_BASE_URL=http://localhost:4200
|
|
|
|
#set to Website Platform
|
|
PLATFORM_WEBSITE_URL=https://gauzy.co
|
|
PLATFORM_WEBSITE_DOWNLOAD_URL=https://gauzy.co/downloads
|
|
|
|
# DB_ORM: typeorm | mikro-orm
|
|
DB_ORM=typeorm
|
|
|
|
# DB_TYPE: sqlite | postgres | better-sqlite3
|
|
DB_TYPE=postgres
|
|
DB_SYNCHRONIZE=false
|
|
|
|
# PostgreSQL Connection Parameters
|
|
DB_HOST=db
|
|
DB_PORT=5432
|
|
DB_NAME=gauzy
|
|
DB_USER=postgres
|
|
DB_PASS=gauzy_password
|
|
DB_LOGGING=all
|
|
DB_POOL_SIZE=40
|
|
DB_POOL_SIZE_KNEX=10
|
|
DB_CONNECTION_TIMEOUT=5000
|
|
DB_IDLE_TIMEOUT=10000
|
|
DB_SLOW_QUERY_LOGGING_TIMEOUT=10000
|
|
DB_SSL_MODE=false
|
|
# If you want to use SSL and set DB_SSL_MODE=true, set the following environment variable
|
|
# with base64 encoded SSL certificate for DB
|
|
DB_CA_CERT=
|
|
# Configuration for Worker Queue and Scheduler
|
|
WORKER_QUEUE_ENABLED=true
|
|
WORKER_SCHEDULER_ENABLED=true
|
|
WORKER_DEFAULT_QUEUE=gauzy_worker_default_queue
|
|
WORKER_TIMEZONE=UTC
|
|
|
|
# Redis Connection Parameters
|
|
REDIS_ENABLED=true
|
|
REDIS_HOST=
|
|
REDIS_PASSWORD=
|
|
REDIS_PORT=
|
|
REDIS_USER=
|
|
REDIS_TLS=false
|
|
# redis[s]://[[username][:password]@][host][:port][/db-number]
|
|
REDIS_URL=redis://redis:6379
|
|
|
|
# ============================================================================
|
|
# SECURITY: Authentication & session secrets
|
|
# Set each of these to a strong, UNIQUE, random value before deploying, e.g.:
|
|
# openssl rand -hex 64
|
|
# The API refuses to start in production (NODE_ENV=production and DEMO != true)
|
|
# while any of these is empty or left at a well-known default value, because
|
|
# shared/default secrets let anyone forge authentication tokens and sessions.
|
|
#
|
|
# docker-compose now runs the API with NODE_ENV=production by default, so a stack
|
|
# started with these left blank will STOP with an "INSECURE SECRETS" error instead
|
|
# of silently serving on the publicly known defaults. Fill them in (or, for a
|
|
# throwaway local stack only, export NODE_ENV=development or DEMO=true).
|
|
# ============================================================================
|
|
JWT_SECRET=
|
|
EXPRESS_SESSION_SECRET=
|
|
|
|
# JWT Refresh Token Configuration
|
|
JWT_REFRESH_TOKEN_SECRET=
|
|
JWT_REFRESH_TOKEN_EXPIRATION_TIME=86400
|
|
|
|
# Email Verification Config
|
|
JWT_VERIFICATION_TOKEN_SECRET=
|
|
JWT_VERIFICATION_TOKEN_EXPIRATION_TIME=86400
|
|
|
|
# Password Less Authentication Configuration
|
|
MAGIC_CODE_EXPIRATION_TIME=600
|
|
|
|
# Join Request Organization Team Configuration
|
|
TEAM_JOIN_REQUEST_EXPIRATION_TIME=86400
|
|
|
|
# Rate Limiting
|
|
THROTTLE_ENABLED=true
|
|
THROTTLE_TTL=60000 # 1 minute
|
|
THROTTLE_LIMIT=60000
|
|
|
|
# CORS Allowed Origins (comma-separated list of trusted origins)
|
|
# In production, set this to your trusted domains. If not set, all origins (*) are allowed.
|
|
ALLOWED_ORIGINS=http://localhost:4200,http://localhost:3000
|
|
|
|
# Twitter OAuth Configuration
|
|
TWITTER_CLIENT_ID=XXXXXXX
|
|
TWITTER_CLIENT_SECRET=XXXXXXX
|
|
TWITTER_CALLBACK_URL=http://localhost:3000/api/auth/twitter/callback
|
|
|
|
# Google OAuth Configuration
|
|
GOOGLE_CLIENT_ID=XXXXXXX
|
|
GOOGLE_CLIENT_SECRET=XXXXXXX
|
|
GOOGLE_CALLBACK_URL=http://localhost:3000/api/auth/google/callback
|
|
|
|
# Facebook OAuth Configuration
|
|
FACEBOOK_CLIENT_ID=XXXXXXX
|
|
FACEBOOK_CLIENT_SECRET=XXXXXXX
|
|
FACEBOOK_CALLBACK_URL=http://localhost:3000/api/auth/facebook/callback
|
|
FACEBOOK_GRAPH_VERSION=v3.0
|
|
|
|
# Github OAuth App Integration
|
|
GAUZY_GITHUB_OAUTH_CLIENT_ID=XXXXXXX
|
|
GAUZY_GITHUB_OAUTH_CLIENT_SECRET=XXXXXXX
|
|
GAUZY_GITHUB_OAUTH_CALLBACK_URL="http://localhost:3000/api/auth/github/callback"
|
|
|
|
# LinkedIn OAuth Configuration
|
|
LINKEDIN_CLIENT_ID=XXXXXXX
|
|
LINKEDIN_CLIENT_SECRET=XXXXXXX
|
|
LINKEDIN_CALLBACK_URL=http://localhost:3000/api/auth/linkedin/callback
|
|
|
|
# Microsoft OAuth Configuration
|
|
MICROSOFT_GRAPH_API_URL=https://graph.microsoft.com/v1.0
|
|
MICROSOFT_AUTHORIZATION_URL=https://login.microsoftonline.com/common/oauth2/v2.0/authorize
|
|
MICROSOFT_TOKEN_URL=https://login.microsoftonline.com/common/oauth2/v2.0/token
|
|
MICROSOFT_CLIENT_ID=XXXXXXX
|
|
MICROSOFT_CLIENT_SECRET=XXXXXXX
|
|
MICROSOFT_CALLBACK_URL=http://localhost:3000/api/auth/microsoft/callback
|
|
|
|
# Github Apps Integration
|
|
GAUZY_GITHUB_CLIENT_ID=XXXXXXX
|
|
GAUZY_GITHUB_CLIENT_SECRET=XXXXXXX
|
|
|
|
# Zapier Apps Integration
|
|
GAUZY_ZAPIER_CLIENT_ID=XXXXXXXXX
|
|
GAUZY_ZAPIER_CLIENT_SECRET=XXXXXXX
|
|
GAUZY_ZAPIER_REDIRECT_URL=http://localhost:3000/api/integration/zapier/oauth/callback
|
|
GAUZY_ZAPIER_POST_INSTALL_URL="http://localhost:4200/#/pages/integrations/zapier"
|
|
# Comma-separated list of domains allowed for OAuth redirects (security feature)
|
|
GAUZY_ZAPIER_ALLOWED_DOMAINS=gauzy.co,*.gauzy.co,ever.co,*.ever.co,zapier.com,*.zapier.com,localhost
|
|
# Maximum number of OAuth authorization codes to store in memory
|
|
GAUZY_ZAPIER_MAX_AUTH_CODES=1000
|
|
# Number of server instances (affects auth code cleanup behavior)
|
|
GAUZY_ZAPIER_INSTANCE_COUNT=1
|
|
|
|
# Github App Install Integration
|
|
GAUZY_GITHUB_APP_NAME=
|
|
GAUZY_GITHUB_APP_ID=XXXXXXX
|
|
GAUZY_GITHUB_APP_PRIVATE_KEY=
|
|
|
|
# Github Webhook Configuration
|
|
GAUZY_GITHUB_WEBHOOK_URL=http://localhost:3000/api/auth/github/webhook
|
|
GAUZY_GITHUB_WEBHOOK_SECRET=XXXXXXX
|
|
|
|
# Github Redirect URL
|
|
GAUZY_GITHUB_REDIRECT_URL=http://localhost:3000/api/integration/github/callback
|
|
GAUZY_GITHUB_POST_INSTALL_URL="http://localhost:4200/#/pages/integrations/github/setup/installation"
|
|
GAUZY_GITHUB_API_VERSION="2022-11-28"
|
|
|
|
FIVERR_CLIENT_ID=XXXXXXX
|
|
FIVERR_CLIENT_SECRET=XXXXXXX
|
|
|
|
AUTH0_CLIENT_ID=XXXXXXX
|
|
AUTH0_CLIENT_SECRET=XXXXXXX
|
|
AUTH0_DOMAIN=XXXXXXX
|
|
|
|
# Keycloak OAuth
|
|
KEYCLOAK_CLIENT_ID=XXXXXXX
|
|
KEYCLOAK_CLIENT_SECRET=XXXXXXX
|
|
KEYCLOAK_REALM=
|
|
KEYCLOAK_COOKIE_KEY=XXXXXXX
|
|
KEYCLOAK_AUTH_SERVER_URL=https://keycloak.example.com/auth
|
|
KEYCLOAK_CALLBACK_URL=http://localhost:3000/api/auth/keycloak/callback
|
|
|
|
INTEGRATED_HUBSTAFF_USER_PASS=hubstaffPassword
|
|
|
|
# Upwork Integration Config
|
|
UPWORK_API_KEY=XXXXXXX
|
|
UPWORK_API_SECRET=XXXXXXX
|
|
UPWORK_REDIRECT_URL="http://localhost:3000/api/integrations/upwork/callback"
|
|
UPWORK_POST_INSTALL_URL="http://localhost:4200/#/pages/integrations/upwork"
|
|
|
|
# Hubstaff Integration Configuration
|
|
HUBSTAFF_CLIENT_ID=XXXXXXX
|
|
HUBSTAFF_CLIENT_SECRET=XXXXXXX
|
|
HUBSTAFF_REDIRECT_URL="http://localhost:3000/api/integration/hubstaff/callback"
|
|
HUBSTAFF_POST_INSTALL_URL="http://localhost:4200/#/pages/integrations/hubstaff"
|
|
|
|
# Format: https://hook.{region}.make.com/{webhook-id}
|
|
GAUZY_MAKE_WEBHOOK_URL=
|
|
|
|
# Make.com Platforms integration
|
|
GAUZY_MAKE_API_URL="https://hook.us2.make.com/api/v2"
|
|
GAUZY_MAKE_BASE_URL="https://www.make.com"
|
|
GAUZY_MAKE_CLIENT_ID=
|
|
GAUZY_MAKE_CLIENT_SECRET=
|
|
GAUZY_MAKE_REDIRECT_URL="${API_BASE_URL}/api/integration/make-com/oauth/callback"
|
|
GAUZY_MAKE_POST_INSTALL_URL="${CLIENT_BASE_URL}/#/pages/integrations/make"
|
|
GAUZY_MAKE_DEFAULT_SCOPES="offline_access"
|
|
|
|
# ActivePieces platforms integration
|
|
ACTIVEPIECES_BASE_URL="https://cloud.activepieces.com"
|
|
GAUZY_ACTIVEPIECES_API_KEY=
|
|
|
|
#SIM platform integration
|
|
SIM_DEFAULT_BASE_URL="https://www.sim.ai"
|
|
GAUZY_SIM_API_KEY=
|
|
|
|
# File System: LOCAL | S3 | WASABI | CLOUDINARY
|
|
FILE_PROVIDER=LOCAL
|
|
|
|
# AWS Config (optional)
|
|
AWS_ACCESS_KEY_ID=
|
|
AWS_SECRET_ACCESS_KEY=
|
|
AWS_REGION=us-east-1
|
|
AWS_S3_BUCKET=gauzy
|
|
|
|
# WASABI Config (optional)
|
|
WASABI_ACCESS_KEY_ID=
|
|
WASABI_SECRET_ACCESS_KEY=
|
|
WASABI_REGION=us-east-1
|
|
WASABI_SERVICE_URL=https://s3.wasabisys.com
|
|
WASABI_S3_BUCKET=gauzy
|
|
WASABI_S3_FORCE_PATH_STYLE=false
|
|
|
|
# DIGITALOCEAN Spaces Config (optional)
|
|
DIGITALOCEAN_ACCESS_KEY_ID=
|
|
DIGITALOCEAN_SECRET_ACCESS_KEY=
|
|
DIGITALOCEAN_REGION=us-east-1
|
|
DIGITALOCEAN_SERVICE_URL=
|
|
DIGITALOCEAN_CDN_URL=
|
|
DIGITALOCEAN_S3_BUCKET=gauzy
|
|
DIGITALOCEAN_S3_FORCE_PATH_STYLE=false
|
|
|
|
# Cloudinary Config (optional)
|
|
CLOUDINARY_CLOUD_NAME=
|
|
CLOUDINARY_API_KEY=
|
|
CLOUDINARY_API_SECRET=
|
|
CLOUDINARY_API_SECURE=true
|
|
CLOUDINARY_CDN_URL=https://res.cloudinary.com
|
|
|
|
# Gauzy AI Endpoints (optional, do not set unless you subscribed to Gauzy AI)
|
|
GAUZY_AI_GRAPHQL_ENDPOINT=http://localhost:3005/graphql
|
|
GAUZY_AI_REST_ENDPOINT=http://localhost:3005/api
|
|
|
|
# Gauzy AI Key/Secret pair authentication
|
|
GAUZY_AI_API_KEY=
|
|
GAUZY_AI_API_SECRET=
|
|
|
|
# Gauzy Cloud
|
|
GAUZY_CLOUD_ENDPOINT=https://api.gauzy.co
|
|
GAUZY_CLOUD_APP=https://app.gauzy.co
|
|
|
|
# SMTP Mail Config
|
|
MAIL_FROM_ADDRESS=gauzy@ever.co
|
|
MAIL_HOST=smtp.gmail.com
|
|
MAIL_PORT=465
|
|
MAIL_USERNAME=
|
|
MAIL_PASSWORD=
|
|
|
|
# Sentry Client Key
|
|
SENTRY_DSN=https://7cd381188b6f446ca0e69185227b9031@o51327.ingest.sentry.io/4397292
|
|
SENTRY_HTTP_TRACING_ENABLED=false
|
|
SENTRY_POSTGRES_TRACKING_ENABLED=false
|
|
SENTRY_PROFILING_ENABLED=false
|
|
SENTRY_TRACES_SAMPLE_RATE=0.1
|
|
|
|
# PostHog Configuration
|
|
POSTHOG_KEY=
|
|
POSTHOG_HOST=https://app.posthog.com
|
|
POSTHOG_ENABLED=true
|
|
POSTHOG_FLUSH_INTERVAL=10000
|
|
|
|
# Default Currency
|
|
DEFAULT_CURRENCY=USD
|
|
|
|
# Default Country
|
|
DEFAULT_COUNTRY=US
|
|
|
|
# Google Maps API Key
|
|
GOOGLE_MAPS_API_KEY=
|
|
|
|
# Chatwoot SDK Token
|
|
CHATWOOT_SDK_TOKEN=
|
|
|
|
# Restrict Access to Google Place Autocomplete
|
|
GOOGLE_PLACE_AUTOCOMPLETE=false
|
|
|
|
# Nebular CHAT API key for a map message type (which is required by Google Maps)
|
|
CHAT_MESSAGE_GOOGLE_MAP=
|
|
|
|
# Default Latitude and Longitude
|
|
DEFAULT_LATITUDE=
|
|
DEFAULT_LONGITUDE=
|
|
|
|
# Keymetrics settings (optional)
|
|
WEB_CONCURRENCY=1
|
|
WEB_MEMORY=4096
|
|
|
|
# Unleash Configuration for Features management (optional)
|
|
|
|
UNLEASH_APP_NAME=Gauzy
|
|
UNLEASH_API_URL=
|
|
UNLEASH_INSTANCE_ID=
|
|
UNLEASH_REFRESH_INTERVAL=15000
|
|
UNLEASH_METRICS_INTERVAL=60000
|
|
UNLEASH_API_KEY=
|
|
|
|
# Defines feature flags and settings related to user authentication methods.
|
|
FEATURE_EMAIL_PASSWORD_LOGIN=true
|
|
FEATURE_MAGIC_LOGIN=true
|
|
FEATURE_GITHUB_LOGIN=true
|
|
FEATURE_FACEBOOK_LOGIN=true
|
|
FEATURE_GOOGLE_LOGIN=true
|
|
FEATURE_TWITTER_LOGIN=true
|
|
FEATURE_MICROSOFT_LOGIN=true
|
|
FEATURE_LINKEDIN_LOGIN=true
|
|
|
|
# Features Toggles
|
|
|
|
FEATURE_DASHBOARD=true
|
|
FEATURE_TIME_TRACKING=true
|
|
|
|
FEATURE_ESTIMATE=true
|
|
FEATURE_ESTIMATE_RECEIVED=true
|
|
FEATURE_INVOICE=true
|
|
FEATURE_INVOICE_RECURRING=true
|
|
FEATURE_INVOICE_RECEIVED=true
|
|
FEATURE_INCOME=true
|
|
FEATURE_EXPENSE=true
|
|
FEATURE_PAYMENT=true
|
|
|
|
FEATURE_PROPOSAL=true
|
|
FEATURE_PROPOSAL_TEMPLATE=true
|
|
|
|
FEATURE_PIPELINE=true
|
|
FEATURE_PIPELINE_DEAL=true
|
|
|
|
FEATURE_DASHBOARD_TASK=true
|
|
FEATURE_TEAM_TASK=true
|
|
FEATURE_MY_TASK=true
|
|
|
|
FEATURE_JOB=true
|
|
|
|
FEATURE_EMPLOYEES=true
|
|
FEATURE_EMPLOYEE_TIME_ACTIVITY=true
|
|
FEATURE_EMPLOYEE_TIMESHEETS=true
|
|
FEATURE_EMPLOYEE_APPOINTMENT=true
|
|
FEATURE_EMPLOYEE_APPROVAL=true
|
|
FEATURE_EMPLOYEE_APPROVAL_POLICY=true
|
|
FEATURE_EMPLOYEE_LEVEL=true
|
|
FEATURE_EMPLOYEE_POSITION=true
|
|
FEATURE_EMPLOYEE_TIMEOFF=true
|
|
FEATURE_EMPLOYEE_RECURRING_EXPENSE=true
|
|
FEATURE_EMPLOYEE_CANDIDATE=true
|
|
FEATURE_MANAGE_INTERVIEW=true
|
|
FEATURE_MANAGE_INVITE=true
|
|
|
|
FEATURE_ORGANIZATION=true
|
|
FEATURE_ORGANIZATION_EQUIPMENT=true
|
|
FEATURE_ORGANIZATION_INVENTORY=true
|
|
FEATURE_ORGANIZATION_TAG=true
|
|
FEATURE_ORGANIZATION_VENDOR=true
|
|
FEATURE_ORGANIZATION_PROJECT=true
|
|
FEATURE_ORGANIZATION_DEPARTMENT=true
|
|
FEATURE_ORGANIZATION_TEAM=true
|
|
FEATURE_ORGANIZATION_DOCUMENT=true
|
|
FEATURE_ORGANIZATION_EMPLOYMENT_TYPE=true
|
|
FEATURE_ORGANIZATION_RECURRING_EXPENSE=true
|
|
FEATURE_ORGANIZATION_HELP_CENTER=true
|
|
|
|
FEATURE_CONTACT=true
|
|
|
|
FEATURE_GOAL=true
|
|
FEATURE_GOAL_REPORT=true
|
|
FEATURE_GOAL_SETTING=true
|
|
|
|
FEATURE_REPORT=true
|
|
|
|
FEATURE_USER=true
|
|
FEATURE_ORGANIZATIONS=true
|
|
FEATURE_APP_INTEGRATION=true
|
|
|
|
FEATURE_SETTING=true
|
|
FEATURE_EMAIL_HISTORY=true
|
|
FEATURE_EMAIL_TEMPLATE=true
|
|
FEATURE_IMPORT_EXPORT=true
|
|
FEATURE_FILE_STORAGE=true
|
|
FEATURE_PAYMENT_GATEWAY=true
|
|
FEATURE_SMS_GATEWAY=true
|
|
FEATURE_SMTP=true
|
|
FEATURE_ROLES_PERMISSION=true
|
|
|
|
# Email Verification
|
|
FEATURE_EMAIL_VERIFICATION=false
|
|
|
|
# Set the environment variable to enable/disable the global stats endpoint
|
|
FEATURE_OPEN_STATS=false
|
|
|
|
# GitHub App Integration
|
|
GITHUB_INTEGRATION_APP_ID=
|
|
GITHUB_INTEGRATION_CLIENT_ID=
|
|
GITHUB_INTEGRATION_CLIENT_SECRET=
|
|
GITHUB_INTEGRATION_PRIVATE_KEY=
|
|
GITHUB_INTEGRATION_WEBHOOK_SECRET=
|
|
|
|
# HubStaff Integration
|
|
HUBSTAFF_CLIENT_ID=
|
|
HUBSTAFF_CLIENT_SECRET=
|
|
HUBSTAFF_PERSONAL_ACCESS_TOKEN=
|
|
|
|
# Jitsu Browser Configuration
|
|
JITSU_BROWSER_URL=
|
|
JITSU_BROWSER_WRITE_KEY=
|
|
|
|
# Jitsu Server Configuration
|
|
JITSU_SERVER_URL=
|
|
JITSU_SERVER_WRITE_KEY=
|
|
JITSU_SERVER_DEBUG=
|
|
JITSU_SERVER_ECHO_EVENTS=
|
|
|
|
# Tracing Configuration
|
|
OTEL_ENABLED=false
|
|
OTEL_PROVIDER=zipkin
|
|
OTEL_SERVICE_NAME=
|
|
OTEL_EXPORTER_OTLP_PROTOCOL=
|
|
OTEL_EXPORTER_OTLP_HEADERS=
|
|
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=
|
|
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=
|
|
OTEL_EXPORTER_OTLP_ENDPOINT=
|
|
ASPECTO_API_KEY=
|
|
HONEYCOMB_API_KEY=
|
|
HONEYCOMB_ENABLE_LOCAL_VISUALIZATIONS=
|
|
|
|
# Platform Logo resource URL (SVG is Recommended)
|
|
PLATFORM_LOGO='assets/images/logos/logo_Gauzy.svg'
|
|
|
|
# Desktop App 512x512 icon
|
|
GAUZY_DESKTOP_LOGO_512X512='assets/icons/icon_512x512.png'
|
|
|
|
# Platform Privacy URL
|
|
PLATFORM_PRIVACY_URL='https://gauzy.co/privacy'
|
|
|
|
# Platform terms of Services URL
|
|
PLATFORM_TOS_URL='https://gauzy.co/tos'
|
|
|
|
# Platform no internet logo
|
|
NO_INTERNET_LOGO='assets/images/logos/logo_Gauzy.svg'
|
|
|
|
# Company Information
|
|
COMPANY_NAME='Ever Co. LTD'
|
|
COMPANY_LINK='https://ever.co'
|
|
COMPANY_SITE_NAME='Gauzy'
|
|
COMPANY_SITE_LINK='https://gauzy.co'
|
|
COMPANY_GITHUB_LINK='https://github.com/ever-co'
|
|
COMPANY_GITLAB_LINK='https://gitlab.com/ever-co'
|
|
COMPANY_FACEBOOK_LINK='https://www.facebook.com/gauzyplatform'
|
|
COMPANY_TWITTER_LINK='https://twitter.com/gauzyplatform'
|
|
COMPANY_IN_LINK='https://www.linkedin.com/company/everhq'
|
|
|
|
# Desktop download links
|
|
DESKTOP_APP_DOWNLOAD_LINK_APPLE='https://gauzy.co/downloads#desktop/apple'
|
|
DESKTOP_APP_DOWNLOAD_LINK_WINDOWS='https://gauzy.co/downloads#desktop/windows'
|
|
DESKTOP_APP_DOWNLOAD_LINK_LINUX='https://gauzy.co/downloads#desktop/linux'
|
|
MOBILE_APP_DOWNLOAD_LINK='https://gauzy.co/downloads#mobile'
|
|
EXTENSION_DOWNLOAD_LINK='https://gauzy.co/downloads#extensions'
|
|
|
|
# Desktop Timer Application Configuration
|
|
PROJECT_REPO='https://github.com/ever-co/ever-gauzy.git'
|
|
|
|
DESKTOP_TIMER_APP_NAME='gauzy-desktop-timer'
|
|
DESKTOP_TIMER_APP_DESCRIPTION='Gauzy Desktop Timer'
|
|
DESKTOP_TIMER_APP_ID='com.ever.gauzydesktoptimer'
|
|
DESKTOP_TIMER_APP_REPO_NAME='ever-gauzy-desktop-timer'
|
|
DESKTOP_TIMER_APP_REPO_OWNER='ever-co'
|
|
DESKTOP_TIMER_APP_WELCOME_TITLE=
|
|
DESKTOP_TIMER_APP_WELCOME_CONTENT=
|
|
DESKTOP_TIMER_APP_PROTOCOL='gauzy-timer'
|
|
|
|
# Desktop Application Configuration
|
|
DESKTOP_APP_NAME='gauzy-desktop'
|
|
DESKTOP_APP_DESCRIPTION='Gauzy Desktop'
|
|
DESKTOP_APP_ID='com.ever.gauzydesktop'
|
|
DESKTOP_APP_REPO_NAME='ever-gauzy-desktop'
|
|
DESKTOP_APP_REPO_OWNER='ever-co'
|
|
DESKTOP_APP_WELCOME_TITLE=
|
|
DESKTOP_APP_WELCOME_CONTENT=
|
|
DESKTOP_APP_PROTOCOL='gauzy-desktop'
|
|
|
|
# Desktop Server Application Configuration
|
|
DESKTOP_SERVER_APP_NAME='gauzy-server'
|
|
DESKTOP_SERVER_APP_DESCRIPTION='Gauzy Server'
|
|
DESKTOP_SERVER_APP_ID='com.ever.gauzyserver'
|
|
DESKTOP_SERVER_APP_REPO_NAME='ever-gauzy-server'
|
|
DESKTOP_SERVER_APP_REPO_OWNER='ever-co'
|
|
DESKTOP_SERVER_APP_WELCOME_TITLE=
|
|
DESKTOP_SERVER_APP_WELCOME_CONTENT=
|
|
DESKTOP_SERVER_APP_PROTOCOL='gauzy-server'
|
|
|
|
# Desktop API Server Application Configuration
|
|
DESKTOP_API_SERVER_APP_NAME='gauzy-api-server'
|
|
DESKTOP_API_SERVER_APP_DESCRIPTION='Gauzy API Server'
|
|
DESKTOP_API_SERVER_APP_ID='com.ever.gauzyapiserver'
|
|
DESKTOP_API_SERVER_APP_REPO_NAME='ever-gauzy-api-server'
|
|
DESKTOP_API_SERVER_APP_REPO_OWNER='ever-co'
|
|
DESKTOP_API_SERVER_APP_WELCOME_TITLE=
|
|
DESKTOP_API_SERVER_APP_WELCOME_CONTENT=
|
|
DESKTOP_API_SERVER_APP_PROTOCOL='gauzy-api-server'
|
|
|
|
#AGENT
|
|
AGENT_APP_PROTOCOL='gauzy-agent'
|
|
|
|
REGISTER_URL='https://app.gauzy.co/#/auth/register'
|
|
FORGOT_PASSWORD_URL='https://app.gauzy.co/#/auth/request-password'
|
|
|
|
# I18N Translation Files URL
|
|
I18N_FILES_URL=
|
|
|
|
# MCP Server Configuration
|
|
API_TIMEOUT=30000
|
|
GAUZY_MCP_DEBUG=false
|
|
MCP_APP_ID=co.gauzy.mcp-server
|
|
MCP_APP_NAME="Gauzy MCP Server"
|
|
GAUZY_AUTO_LOGIN=false
|
|
GAUZY_AUTH_EMAIL=your-email@example.com
|
|
GAUZY_AUTH_PASSWORD=your-secure-password
|
|
|
|
# MCP Transport Configuration
|
|
# Options: stdio | http | websocket
|
|
MCP_TRANSPORT=stdio
|
|
MCP_SERVER_MODE=stdio
|
|
|
|
# HTTP Transport Settings
|
|
MCP_AUTH_BASE_URL=https://mcpauth.gauzy.co
|
|
MCP_AUTH_PORT=3003
|
|
MCP_HTTP_PORT=3001
|
|
MCP_HTTP_HOST=0.0.0.0
|
|
MCP_CORS_ORIGIN=http://localhost:3000,http://localhost:4200,http://127.0.0.1:3000,http://127.0.0.1:4200
|
|
MCP_CORS_CREDENTIALS=true
|
|
|
|
# Session Management
|
|
MCP_AUTH_SESSION_SECRET=your-secure-session-secret
|
|
MCP_SESSION_ENABLED=true
|
|
MCP_SESSION_COOKIE_NAME=mcp-session-id
|
|
MCP_SESSION_TTL=1800000
|
|
MCP_TRUSTED_PROXIES=loopback,linklocal,uniquelocal
|
|
|
|
# WebSocket Transport Settings
|
|
MCP_WS_PATH="/sse" # Realtime endpoint path (WS server behind /sse by default)
|
|
MCP_WS_PORT=3002
|
|
MCP_WS_HOST=0.0.0.0
|
|
MCP_WS_COMPRESSION=true
|
|
MCP_WS_PER_MESSAGE_DEFLATE=true
|
|
MCP_WS_TLS=false
|
|
MCP_WS_KEY_PATH=path/to/your/certs/key.pem
|
|
MCP_WS_CERT_PATH=path/to/your/certs/cert.pem
|
|
MCP_WS_MAX_PAYLOAD=16777216
|
|
MCP_WS_ALLOWED_ORIGINS=https://mcp.gauzy.co,https://auth.gauzy.co
|
|
MCP_WS_SESSION_COOKIE_NAME=mcp-ws-session-id
|
|
MCP_WS_SESSION_ENABLED=true
|
|
MCP_WS_TRUSTED_PROXIES=loopback,linklocal,uniquelocal
|
|
|
|
# OAuth 2.0 Authorization Configuration (Production)
|
|
MCP_AUTH_ENABLED=true
|
|
MCP_AUTH_REQUIRED_SCOPES=mcp.read,mcp.write,mcp.admin
|
|
MCP_AUTH_RESOURCE_URI=https://mcp.gauzy.co
|
|
|
|
# JWT validation for production (using RS256 with public key)
|
|
MCP_AUTH_JWT_ALGORITHMS=RS256
|
|
MCP_AUTH_JWT_AUDIENCE=https://mcp.gauzy.co
|
|
MCP_AUTH_JWT_ISSUER=https://auth.gauzy.co
|
|
|
|
# Option 1: Use JWKS URI for dynamic key discovery (recommended)
|
|
MCP_AUTH_JWT_JWKS_URI=https://auth.gauzy.co/.well-known/jwks.json
|
|
|
|
# Production authorization server configuration
|
|
MCP_AUTH_SERVERS=[{"issuer":"https://auth.gauzy.co","authorizationEndpoint":"https://auth.gauzy.co/oauth2/authorize","tokenEndpoint":"https://auth.gauzy.co/oauth2/token","registrationEndpoint":"https://auth.gauzy.co/oauth2/register","introspectionEndpoint":"https://auth.gauzy.co/oauth2/introspect","grantTypesSupported":["authorization_code","refresh_token","client_credentials"],"responseTypesSupported":["code"],"scopesSupported":["mcp.read","mcp.write","mcp.admin","openid","profile","email"],"codeChallengeMethodsSupported":["S256"]}]
|
|
|
|
# Alternative: Token introspection for opaque tokens
|
|
# MCP_AUTH_INTROSPECTION_ENDPOINT=https://auth.gauzy.co/oauth2/introspect
|
|
# MCP_AUTH_INTROSPECTION_CLIENT_ID=gauzy-mcp-server
|
|
# MCP_AUTH_INTROSPECTION_CLIENT_SECRET=secure-client-secret
|
|
|
|
# Cache settings for performance
|
|
MCP_AUTH_TOKEN_CACHE_TTL="600" # 10 minutes
|
|
MCP_AUTH_METADATA_CACHE_TTL="3600" # 1 hour
|
|
|
|
# Optional metadata URLs
|
|
MCP_POLICY_URI=https://gauzy.co/privacy
|