Files
twenty/packages/twenty-docs/docs/start/self-hosting/self-hosting.mdx
Deepak Kumar dc576d0818 GH-3546 Recaptcha on login form (#4626)
## 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>
2024-04-25 23:52:28 +02:00

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>