## Description This PR adds recaptcha on login form. One can add any one of three recaptcha vendor - 1. Google Recaptcha - https://developers.google.com/recaptcha/docs/v3#programmatically_invoke_the_challenge 2. HCaptcha - https://docs.hcaptcha.com/invisible#programmatically-invoke-the-challenge 3. Turnstile - https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/#execution-modes ### Issue - #3546 ### Environment variables - 1. `CAPTCHA_DRIVER` - `google-recaptcha` | `hcaptcha` | `turnstile` 2. `CAPTCHA_SITE_KEY` - site key 3. `CAPTCHA_SECRET_KEY` - secret key ### Engineering choices 1. If some of the above env variable provided, then, backend generates an error - <img width="990" alt="image" src="https://github.com/twentyhq/twenty/assets/60139930/9fb00fab-9261-4ff3-b23e-2c2e06f1bf89"> Please note that login/signup form will keep working as expected. 2. I'm using a Captcha guard that intercepts the request. If "captchaToken" is present in the body and all env is set, then, the captcha token is verified by backend through the service. 3. One can use this guard on any resolver to protect it by the captcha. 4. On frontend, two hooks `useGenerateCaptchaToken` and `useInsertCaptchaScript` is created. `useInsertCaptchaScript` adds the respective captcha JS script on frontend. `useGenerateCaptchaToken` returns a function that one can use to trigger captcha token generation programatically. This allows one to generate token keeping recaptcha invisible. ### Note This PR contains some changes in unrelated files like indentation, spacing, inverted comma etc. I ran "yarn nx fmt:fix twenty-front" and "yarn nx lint twenty-front -- --fix". ### Screenshots <img width="869" alt="image" src="https://github.com/twentyhq/twenty/assets/60139930/a75f5677-9b66-47f7-9730-4ec916073f8c"> --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com> Co-authored-by: Charles Bochet <charles@twenty.com>
211 lines
8.2 KiB
Plaintext
211 lines
8.2 KiB
Plaintext
---
|
|
title: Self-Hosting
|
|
sidebar_position: 1
|
|
sidebar_custom_props:
|
|
icon: TbServer
|
|
---
|
|
|
|
|
|
import DocCardList from '@theme/DocCardList';
|
|
|
|
import OptionTable from '@site/src/theme/OptionTable'
|
|
import Tabs from '@theme/Tabs';
|
|
import TabItem from '@theme/TabItem';
|
|
|
|
|
|
# Setup Server
|
|
|
|
<DocCardList/>
|
|
|
|
# Setup Environment Variables
|
|
|
|
## Frontend
|
|
|
|
<OptionTable options={[
|
|
['REACT_APP_SERVER_BASE_URL', 'http://localhost:3000', 'Url of backend server'],
|
|
['GENERATE_SOURCEMAP', 'false', 'Generate source maps for debugging'],
|
|
['CHROMATIC_PROJECT_TOKEN', '', 'Chromatic token used for CI'],
|
|
]}></OptionTable>
|
|
|
|
|
|
## Backend
|
|
|
|
### Config
|
|
|
|
<OptionTable options={[
|
|
['PG_DATABASE_URL', 'postgres://user:pw@localhost:5432/default?connection_limit=1', 'Database connection'],
|
|
['PG_SSL_ALLOW_SELF_SIGNED', 'false', 'Allow self signed certificates'],
|
|
['REDIS_HOST', '127.0.0.1', 'Redis connection host'],
|
|
['REDIS_PORT', '6379', 'Redis connection port'],
|
|
['FRONT_BASE_URL', 'http://localhost:3001', 'Url to the hosted frontend'],
|
|
['SERVER_URL', 'http://localhost:3000', 'Url to the hosted server'],
|
|
['PORT', '3000', 'Port'],
|
|
['CACHE_STORAGE_TYPE', 'memory', 'Cache type (memory, redis...)'],
|
|
['CACHE_STORAGE_TTL', '3600 * 24 * 7', 'Cache TTL in seconds']
|
|
]}></OptionTable>
|
|
|
|
### Security
|
|
|
|
<OptionTable options={[
|
|
['API_RATE_LIMITING_TTL', '100', 'API rate limiting time window'],
|
|
['API_RATE_LIMITING_LIMIT', '200', 'API rate limiting max requests'],
|
|
]}></OptionTable>
|
|
### Tokens
|
|
|
|
<OptionTable options={[
|
|
['ACCESS_TOKEN_SECRET', '<random>', 'Secret used for the access tokens'],
|
|
['ACCESS_TOKEN_EXPIRES_IN', '30m', 'Access token expiration time'],
|
|
['LOGIN_TOKEN_SECRET', '<random>', 'Secret used for the login tokens'],
|
|
['LOGIN_TOKEN_EXPIRES_IN', '15m', 'Login token expiration time'],
|
|
['REFRESH_TOKEN_SECRET', '<random>', 'Secret used for the refresh tokens'],
|
|
['REFRESH_TOKEN_EXPIRES_IN', '90d', 'Refresh token expiration time'],
|
|
['REFRESH_TOKEN_COOL_DOWN', '1m', 'Refresh token cooldown'],
|
|
['FILE_TOKEN_SECRET', '<random>', 'Secret used for the file tokens'],
|
|
['FILE_TOKEN_EXPIRES_IN', '1d', 'File token expiration time'],
|
|
['API_TOKEN_EXPIRES_IN', '1000y', 'Api token expiration time'],
|
|
]}></OptionTable>
|
|
|
|
### Auth
|
|
|
|
<OptionTable options={[
|
|
['MESSAGING_PROVIDER_GMAIL_ENABLED', 'false', 'Enable Gmail API connection'],
|
|
['CALENDAR_PROVIDER_GMAIL_ENABLED', 'false', 'Enable Google Calendar API connection'],
|
|
['AUTH_GOOGLE_APIS_CALLBACK_URL', '', 'Google APIs auth callback'],
|
|
['AUTH_PASSWORD_ENABLED', 'false', 'Enable Email/Password login'],
|
|
['AUTH_GOOGLE_ENABLED', 'false', 'Enable Google SSO login'],
|
|
['AUTH_GOOGLE_CLIENT_ID', '', 'Google client ID'],
|
|
['AUTH_GOOGLE_CLIENT_SECRET', '', 'Google client secret'],
|
|
['AUTH_GOOGLE_CALLBACK_URL', '', 'Google auth callback'],
|
|
['AUTH_MICROSOFT_ENABLED', 'false', 'Enable Microsoft SSO login'],
|
|
['AUTH_MICROSOFT_CLIENT_ID', '', 'Microsoft client ID'],
|
|
['AUTH_MICROSOFT_TENANT_ID', '', 'Microsoft tenant ID'],
|
|
['AUTH_MICROSOFT_CLIENT_SECRET', '', 'Microsoft client secret'],
|
|
['AUTH_MICROSOFT_CALLBACK_URL', '', 'Microsoft auth callback'],
|
|
['FRONT_AUTH_CALLBACK_URL', 'http://localhost:3001/verify ', 'Callback used for Login page'],
|
|
['IS_SIGN_UP_DISABLED', 'false', 'Disable sign-up'],
|
|
['PASSWORD_RESET_TOKEN_EXPIRES_IN', '5m', 'Password reset token expiration time'],
|
|
]}></OptionTable>
|
|
|
|
### Email
|
|
|
|
<OptionTable options={[
|
|
['EMAIL_FROM_ADDRESS', 'contact@yourdomain.com', 'Global email From: header used to send emails'],
|
|
['EMAIL_FROM_NAME', 'John from YourDomain', 'Global name From: header used to send emails'],
|
|
['EMAIL_SYSTEM_ADDRESS', 'system@yourdomain.com', 'Email address used as a destination to send internal system notification'],
|
|
['EMAIL_DRIVER', 'logger', "Email driver: 'logger' (to log emails in console) or 'smtp'"],
|
|
['EMAIL_SMTP_HOST', '', 'Email Smtp Host'],
|
|
['EMAIL_SMTP_PORT', '', 'Email Smtp Port'],
|
|
['EMAIL_SMTP_USER', '', 'Email Smtp User'],
|
|
['EMAIL_SMTP_PASSWORD', '', 'Email Smtp Password'],
|
|
]}></OptionTable>
|
|
|
|
#### Email SMTP Server configuration examples
|
|
|
|
<Tabs>
|
|
|
|
<TabItem value="Gmail" label="Gmail" default>
|
|
|
|
You will need to provision an [App Password](https://support.google.com/accounts/answer/185833).
|
|
- EMAIL_SMTP_HOST=smtp.gmail.com
|
|
- EMAIL_SERVER_PORT=465
|
|
- EMAIL_SERVER_USER=gmail_email_address
|
|
- EMAIL_SERVER_PASSWORD='gmail_app_password'
|
|
|
|
</TabItem>
|
|
|
|
<TabItem value="Office365" label="Office365">
|
|
|
|
Keep in mind that if you have 2FA enabled, you will need to provision an [App Password](https://support.microsoft.com/en-us/account-billing/manage-app-passwords-for-two-step-verification-d6dc8c6d-4bf7-4851-ad95-6d07799387e9).
|
|
- EMAIL_SMTP_HOST=smtp.office365.com
|
|
- EMAIL_SERVER_PORT=587
|
|
- EMAIL_SERVER_USER=office365_email_address
|
|
- EMAIL_SERVER_PASSWORD='office365_password'
|
|
|
|
</TabItem>
|
|
|
|
<TabItem value="Smtp4dev" label="Smtp4dev">
|
|
|
|
**smtp4dev** is a fake SMTP email server for development and testing.
|
|
- Run the smtp4dev image: `docker run --rm -it -p 8090:80 -p 2525:25 rnwood/smtp4dev`
|
|
- Access the smtp4dev ui here: [http://localhost:8090](http://localhost:8090)
|
|
- Set the following env variables:
|
|
- EMAIL_SERVER_HOST=localhost
|
|
- EMAIL_SERVER_PORT=2525
|
|
|
|
</TabItem>
|
|
|
|
</Tabs>
|
|
|
|
### Storage
|
|
|
|
<OptionTable options={[
|
|
['STORAGE_TYPE', 'local', "Storage driver: 'local' or 's3'"],
|
|
['STORAGE_S3_REGION', '', 'Storage Region'],
|
|
['STORAGE_S3_NAME', '', 'Bucket Name'],
|
|
['STORAGE_S3_ENDPOINT', '', 'Use if a different Endpoint is needed (for example Google)'],
|
|
['STORAGE_LOCAL_PATH', '.local-storage', 'data path (local storage)'],
|
|
]}></OptionTable>
|
|
|
|
### Message Queue
|
|
|
|
<OptionTable options={[
|
|
['MESSAGE_QUEUE_TYPE', 'pg-boss', "Queue driver: 'pg-boss' or 'bull-mq'"],
|
|
]}></OptionTable>
|
|
|
|
### Logging
|
|
|
|
<OptionTable options={[
|
|
['LOGGER_DRIVER', 'console', "The logging driver can be: 'console' or 'sentry'"],
|
|
['LOGGER_IS_BUFFER_ENABLED', 'true', 'Buffer the logs before sending them to the logging driver'],
|
|
['LOG_LEVELS', 'error,warn', "The loglevels which are logged to the logging driver. Can include: 'log', 'warn', 'error'"],
|
|
['EXCEPTION_HANDLER_DRIVER', 'sentry', "The exception handler driver can be: 'console' or 'sentry'"],
|
|
['SENTRY_ENVIRONMENT', 'main', 'The sentry environment used if sentry logging driver is selected'],
|
|
['SENTRY_RELEASE', 'latest', 'The sentry release used if sentry logging driver is selected'],
|
|
['SENTRY_DSN', 'https://xxx@xxx.ingest.sentry.io/xxx', 'The sentry logging endpoint used if sentry logging driver is selected'],
|
|
['SENTRY_FRONT_DSN', 'https://xxx@xxx.ingest.sentry.io/xxx', 'The sentry logging endpoint used by the frontend if sentry logging driver is selected'],
|
|
]}></OptionTable>
|
|
|
|
|
|
### Data enrichment and AI
|
|
|
|
<OptionTable options={[
|
|
['OPENROUTER_API_KEY', '', "The API key for openrouter.ai, an abstraction layer over models from Mistral, OpenAI and more"]
|
|
]}></OptionTable>
|
|
|
|
|
|
### Support Chat
|
|
|
|
<OptionTable options={[
|
|
['SUPPORT_DRIVER', 'front', "Support driver ('front' or 'none')"],
|
|
['SUPPORT_FRONT_HMAC_KEY', '<secret>', 'Suport chat key'],
|
|
['SUPPORT_FRONT_CHAT_ID', '<id>', 'Support chat id'],
|
|
]}></OptionTable>
|
|
|
|
### Telemetry
|
|
|
|
<OptionTable options={[
|
|
['TELEMETRY_ENABLED', 'true', 'Change this if you want to disable telemetry'],
|
|
['TELEMETRY_ANONYMIZATION_ENABLED', 'true', 'Telemetry is anonymized by default, you probably don\'t want to change this'],
|
|
]}></OptionTable>
|
|
|
|
### Debug / Development
|
|
|
|
<OptionTable options={[
|
|
['DEBUG_MODE', 'true', 'Activate debug mode'],
|
|
['SIGN_IN_PREFILLED', 'true', 'Prefill the Signin form for usage in a demo or dev environment'],
|
|
]}></OptionTable>
|
|
|
|
### Workspace Cleaning
|
|
|
|
<OptionTable options={[
|
|
['WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION', '', 'Number of inactive days before sending workspace deleting warning email'],
|
|
['WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION', '', 'Number of inactive days before deleting workspace'],
|
|
]}></OptionTable>
|
|
|
|
### Captcha
|
|
|
|
<OptionTable options={[
|
|
['CAPTCHA_DRIVER', '', "The captcha driver can be 'google-recaptcha' or 'turnstile'"],
|
|
['CAPTCHA_SITE_KEY', '', 'The captcha site key'],
|
|
['CAPTCHA_SECRET_KEY', '', 'The captcha secret key'],
|
|
]}></OptionTable> |