Use injected configuration from Nginx at runtime instead of build time (#30)

* Use envsubst and nginx templates to generate nginx configs which can substitute environment variables and inject into the index.html file

* Fix path in dockerfile. Add .gitignore and .env.example files. Fix nginx-linux template.

* Add all environment variables. Add prefix to all environment variables. Update scripts to attempt to substitute all environment variables with the prefix

* Setup dockerfile to execute a bash script. use env.example for fetching environment variables in development

* Toggle features based on injected configs. Fix nginx template substitution script.

* Update env.example file

* Remove debug code from start-nginx.sh

* Fix nginx config templates by adding quotes by default. Fix sed regex to include numerals. Toggle social login buttons on Login page based on the config.

* Update rapid api environment variable name. Toggle oauth buttons based on config in SignUp page. Update .env.example to be a union of server and client environment variables

* Adding a Map disabled message on Map widget

* Adding links to Privacy policy and TNC

* Use REACT_APP_ env variables with higher priority over injected config variables for toggling features

* Update netlify.toml by commenting out the build environment variables

* Remove env variables not required by the client

* Remove start-storybook entry from package.json

* Fix netlify.toml. Fallback algolia configs

* Add contexts to netlify.toml for successful deploys. Swith to using APPSMITH_MARKETPLACE_URL as the toggle for RapidAPI feature on the client. Remove comments in nginx config templates. Fix template used in dockerfile.

Co-authored-by: Satbir Singh <apple@apples-MacBook-Pro.local>
Co-authored-by: Satbir Singh <satbir121@gmail.com>
This commit is contained in:
Abhinav Jha 2020-07-07 15:52:17 +05:30 committed by GitHub
parent d85376b90c
commit 94b28311c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 822 additions and 630 deletions

50
.env.example Normal file
View File

@ -0,0 +1,50 @@
# Rename this to .env
# Note: Please donot include quotes (double or single) in the values
# Sentry
APPSMITH_SENTRY_DSN=
# Hotjar
APPSMITH_HOTJAR_HJID=
APPSMITH_HOTJAR_HJSV=
# Google OAuth
APPSMITH_OAUTH2_GOOGLE_CLIENT_ID=
APPSMITH_OAUTH2_GOOGLE_CLIENT_SECRET=
# Github OAuth
APPSMITH_OAUTH2_GITHUB_CLIENT_ID=
APPSMITH_OAUTH2_GITHUB_CLIENT_SECRET=
# Segment
APPSMITH_SEGMENT_KEY=
# RapidAPI
APPSMITH_RAPID_API_KEY_VALUE=
APPSMITH_MARKETPLACE_URL=
# Optimizely
APPSMITH_OPTIMIZELY_KEY=
# Algolia Search (Docs)
APPSMITH_ALGOLIA_API_ID=
APPSMITH_ALGOLIA_API_KEY=
APPSMITH_ALGOLIA_SEARCH_INDEX_NAME=
#Client log level (debug | error)
APPSMITH_CLIENT_LOG_LEVEL=
# GOOGLE client API KEY
APPSMITH_GOOGLE_MAPS_API_KEY=
# Email server
APPSMITH_MAIL_ENABLED=
APPSMITH_MAIL_HOST=
APPSMITH_MAIL_PORT=
APPSMITH_MAIL_USERNAME=
APPSMITH_MAIL_PASSWORD=
# Email server feature toggles
# true | false values
APPSMITH_MAIL_SMTP_AUTH=
APPSMITH_MAIL_SMTP_TLS_ENABLED=

2
.gitignore vendored
View File

@ -1,4 +1,4 @@
.DS_Store .DS_Store
.idea .idea
*.iml *.iml
.env

View File

@ -33,3 +33,5 @@ cypress/screenshots
results/ results/
/docker/*.pem /docker/*.pem
/docker/nginx.conf

View File

@ -1,7 +1,8 @@
FROM nginx:1.17.9-alpine FROM nginx:1.17.9-alpine
COPY ./build /var/www/appsmith COPY ./build /var/www/appsmith
RUN ls -al /var/www/appsmith
EXPOSE 80 EXPOSE 80
CMD ["nginx", "-g", "daemon off;"] COPY ./docker/templates/nginx-linux.conf.template /nginx.conf.template
COPY ./docker/start-nginx.sh /start-nginx.sh
CMD ["/start-nginx.sh"]

View File

@ -1,88 +0,0 @@
#### TODO: Please change the backend endpoint from release-api.appsmith.com --> https://release-api.appsmith.com when merged into release
server {
listen 80;
server_name dev.appsmith.com;
client_max_body_size 10m;
gzip on;
gzip_proxied any;
proxy_ssl_server_name on;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
location / {
proxy_pass http://localhost:3000;
}
location /f {
proxy_pass https://cdn.optimizely.com/;
}
location /api {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
location /oauth2 {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
location /login {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
}
server {
listen 443 ssl http2;
server_name dev.appsmith.com;
ssl_certificate /etc/certificate/dev.appsmith.com.pem;
ssl_certificate_key /etc/certificate/dev.appsmith.com-key.pem;
# include /etc/letsencrypt/options-ssl-nginx.conf;
# ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
gzip on;
proxy_ssl_server_name on;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
location / {
proxy_pass http://localhost:3000;
}
location /f {
proxy_pass https://cdn.optimizely.com/;
}
location /api {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
location /oauth2 {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
location /login {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
}

View File

@ -1,87 +0,0 @@
#### TODO: Please change the backend endpoint from release-api.appsmith.com --> https://release-api.appsmith.com when merged into release
server {
listen 80;
server_name dev.appsmith.com;
client_max_body_size 10m;
gzip on;
gzip_proxied any;
proxy_ssl_server_name on;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
location / {
proxy_pass http://host.docker.internal:3000;
}
location /f {
proxy_pass https://cdn.optimizely.com/;
}
location /api {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
location /oauth2 {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
location /login {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
}
server {
listen 443 ssl http2;
server_name dev.appsmith.com;
ssl_certificate /etc/certificate/dev.appsmith.com.pem;
ssl_certificate_key /etc/certificate/dev.appsmith.com-key.pem;
# include /etc/letsencrypt/options-ssl-nginx.conf;
# ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
gzip on;
proxy_ssl_server_name on;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
location / {
proxy_pass http://host.docker.internal:3000;
}
location /f {
proxy_pass https://cdn.optimizely.com/;
}
location /api {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
location /oauth2 {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
location /login {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
}

View File

@ -0,0 +1,4 @@
#!/bin/sh
set -ue
cat /nginx.conf.template | envsubst "$(printf '$%s,' $(env | grep -Eo '^APPSMITH_[A-Z0-9_]+'))" | sed -e 's|\${\(APPSMITH_[A-Z0-9_]*\)}||g' | tee /etc/nginx/conf.d/app.conf
exec nginx -g 'daemon off;'

View File

@ -0,0 +1,121 @@
server {
listen 80;
server_name dev.appsmith.com;
client_max_body_size 10m;
gzip on;
gzip_proxied any;
proxy_ssl_server_name on;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Accept-Encoding "";
sub_filter_once off;
location / {
proxy_pass http://localhost:3000;
sub_filter __APPSMITH_SENTRY_DSN__ '${APPSMITH_SENTRY_DSN}';
sub_filter __APPSMITH_APPSMITH_HOTJAR_HJID__ '${APPSMITH_HOTJAR_HJID}';
sub_filter __APPSMITH_HOTJAR_HJSV__ '${APPSMITH_HOTJAR_HJSV}';
sub_filter __APPSMITH_OAUTH2_GOOGLE_CLIENT_ID__ '${APPSMITH_OAUTH2_GOOGLE_CLIENT_ID}';
sub_filter __APPSMITH_OAUTH2_GITHUB_CLIENT_ID__ '${APPSMITH_OAUTH2_GITHUB_CLIENT_ID}';
sub_filter __APPSMITH_MARKETPLACE_URL__ '${APPSMITH_MARKETPLACE_URL}';
sub_filter __APPSMITH_SEGMENT_KEY__ '${APPSMITH_SEGMENT_KEY}';
sub_filter __APPSMITH_OPTIMIZELY_KEY__ '${APPSMITH_OPTIMIZELY_KEY}';
sub_filter __APPSMITH_ALGOLIA_API_ID__ '${APPSMITH_ALGOLIA_API_ID}';
sub_filter __APPSMITH_ALGOLIA_SEARCH_INDEX_NAME__ '${APPSMITH_ALGOLIA_SEARCH_INDEX_NAME}';
sub_filter __APPSMITH_ALGOLIA_API_KEY__ '${APPSMITH_ALGOLIA_API_KEY}';
sub_filter __APPSMITH_CLIENT_LOG_LEVEL__ '${APPSMITH_CLIENT_LOG_LEVEL}';
sub_filter __APPSMITH_GOOGLE_MAPS_API_KEY__ '${APPSMITH_GOOGLE_MAPS_API_KEY}';
sub_filter __APPSMITH_TNC_PP__ '${APPSMITH_TNC_PP}';
}
location /f {
proxy_pass https://cdn.optimizely.com/;
}
location /api {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
location /oauth2 {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
location /login {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
}
server {
listen 443 ssl http2;
server_name dev.appsmith.com;
ssl_certificate /etc/certificate/dev.appsmith.com.pem;
ssl_certificate_key /etc/certificate/dev.appsmith.com-key.pem;
# include /etc/letsencrypt/options-ssl-nginx.conf;
# ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
gzip on;
proxy_ssl_server_name on;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Accept-Encoding "";
sub_filter_once off;
location / {
proxy_pass http://localhost:3000;
sub_filter __APPSMITH_SENTRY_DSN__ '${APPSMITH_SENTRY_DSN}';
sub_filter __APPSMITH_HOTJAR_HJID__ '${APPSMITH_HOTJAR_HJID}';
sub_filter __APPSMITH_HOTJAR_HJSV__ '${APPSMITH_HOTJAR_HJSV}';
sub_filter __APPSMITH_OAUTH2_GOOGLE_CLIENT_ID__ '${APPSMITH_OAUTH2_GOOGLE_CLIENT_ID}';
sub_filter __APPSMITH_OAUTH2_GITHUB_CLIENT_ID__ '${APPSMITH_OAUTH2_GITHUB_CLIENT_ID}';
sub_filter __APPSMITH_MARKETPLACE_URL__ '${APPSMITH_MARKETPLACE_URL}';
sub_filter __APPSMITH_SEGMENT_KEY__ '${APPSMITH_SEGMENT_KEY}';
sub_filter __APPSMITH_OPTIMIZELY_KEY__ '${APPSMITH_OPTIMIZELY_KEY}';
sub_filter __APPSMITH_ALGOLIA_API_ID__ '${APPSMITH_ALGOLIA_API_ID}';
sub_filter __APPSMITH_ALGOLIA_SEARCH_INDEX_NAME__ '${APPSMITH_ALGOLIA_SEARCH_INDEX_NAME}';
sub_filter __APPSMITH_ALGOLIA_API_KEY__ '${APPSMITH_ALGOLIA_API_KEY}';
sub_filter __APPSMITH_CLIENT_LOG_LEVEL__ '${APPSMITH_CLIENT_LOG_LEVEL}';
sub_filter __APPSMITH_GOOGLE_MAPS_API_KEY__ '${APPSMITH_GOOGLE_MAPS_API_KEY}';
sub_filter __APPSMITH_TNC_PP__ '${APPSMITH_TNC_PP}';
}
location /f {
proxy_pass https://cdn.optimizely.com/;
}
location /api {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
location /oauth2 {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
location /login {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
}

View File

@ -0,0 +1,123 @@
server {
listen 80;
server_name dev.appsmith.com;
client_max_body_size 10m;
gzip on;
gzip_proxied any;
proxy_ssl_server_name on;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Accept-Encoding "";
index index.html index.htm;
sub_filter_once off;
location / {
proxy_pass http://host.docker.internal:3000;
sub_filter __APPSMITH_SENTRY_DSN__ '${APPSMITH_SENTRY_DSN}';
sub_filter __APPSMITH_HOTJAR_HJID__ '${APPSMITH_HOTJAR_HJID}';
sub_filter __APPSMITH_HOTJAR_HJSV__ '${APPSMITH_HOTJAR_HJSV}';
sub_filter __APPSMITH_OAUTH2_GOOGLE_CLIENT_ID__ '${APPSMITH_OAUTH2_GOOGLE_CLIENT_ID}';
sub_filter __APPSMITH_OAUTH2_GITHUB_CLIENT_ID__ '${APPSMITH_OAUTH2_GITHUB_CLIENT_ID}';
sub_filter __APPSMITH_MARKETPLACE_URL__ '${APPSMITH_MARKETPLACE_URL}';
sub_filter __APPSMITH_SEGMENT_KEY__ '${APPSMITH_SEGMENT_KEY}';
sub_filter __APPSMITH_OPTIMIZELY_KEY__ '${APPSMITH_OPTIMIZELY_KEY}';
sub_filter __APPSMITH_ALGOLIA_API_ID__ '${APPSMITH_ALGOLIA_API_ID}';
sub_filter __APPSMITH_ALGOLIA_SEARCH_INDEX_NAME__ '${APPSMITH_ALGOLIA_SEARCH_INDEX_NAME}';
sub_filter __APPSMITH_ALGOLIA_API_KEY__ '${APPSMITH_ALGOLIA_API_KEY}';
sub_filter __APPSMITH_CLIENT_LOG_LEVEL__ '${APPSMITH_CLIENT_LOG_LEVEL}';
sub_filter __APPSMITH_GOOGLE_MAPS_API_KEY__ '${APPSMITH_GOOGLE_MAPS_API_KEY}';
sub_filter __APPSMITH_TNC_PP__ '${APPSMITH_TNC_PP}';
}
location /f {
proxy_pass https://cdn.optimizely.com/;
}
location /api {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
location /oauth2 {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
location /login {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
}
server {
listen 443 ssl http2;
server_name dev.appsmith.com;
ssl_certificate /etc/certificate/dev.appsmith.com.pem;
ssl_certificate_key /etc/certificate/dev.appsmith.com-key.pem;
# include /etc/letsencrypt/options-ssl-nginx.conf;
# ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
gzip on;
proxy_ssl_server_name on;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Accept-Encoding "";
index index.html index.htm;
sub_filter_once off;
location / {
proxy_pass http://host.docker.internal:3000;
sub_filter __APPSMITH_SENTRY_DSN__ '${APPSMITH_SENTRY_DSN}';
sub_filter __APPSMITH_HOTJAR_HJID__ '${APPSMITH_HOTJAR_HJID}';
sub_filter __APPSMITH_HOTJAR_HJSV__ '${APPSMITH_HOTJAR_HJSV}';
sub_filter __APPSMITH_OAUTH2_GOOGLE_CLIENT_ID__ '${APPSMITH_OAUTH2_GOOGLE_CLIENT_ID}';
sub_filter __APPSMITH_OAUTH2_GITHUB_CLIENT_ID__ '${APPSMITH_OAUTH2_GITHUB_CLIENT_ID}';
sub_filter __APPSMITH_MARKETPLACE_URL__ '${APPSMITH_MARKETPLACE_URL}';
sub_filter __APPSMITH_SEGMENT_KEY__ '${APPSMITH_SEGMENT_KEY}';
sub_filter __APPSMITH_OPTIMIZELY_KEY__ '${APPSMITH_OPTIMIZELY_KEY}';
sub_filter __APPSMITH_ALGOLIA_API_ID__ '${APPSMITH_ALGOLIA_API_ID}';
sub_filter __APPSMITH_ALGOLIA_SEARCH_INDEX_NAME__ '${APPSMITH_ALGOLIA_SEARCH_INDEX_NAME}';
sub_filter __APPSMITH_ALGOLIA_API_KEY__ '${APPSMITH_ALGOLIA_API_KEY}';
sub_filter __APPSMITH_CLIENT_LOG_LEVEL__ '${APPSMITH_CLIENT_LOG_LEVEL}';
sub_filter __APPSMITH_GOOGLE_MAPS_API_KEY__ '${APPSMITH_GOOGLE_MAPS_API_KEY}';
sub_filter __APPSMITH_TNC_PP__ '${APPSMITH_TNC_PP}';
}
location /f {
proxy_pass https://cdn.optimizely.com/;
}
location /api {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
location /oauth2 {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
location /login {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_pass https://release-api.appsmith.com;
}
}

View File

@ -1,7 +1,18 @@
[[headers]] [build]
for = "/static/*" [build.environment]
[header.values] # REACT_APP_SENTRY_DSN=
cache-control = "max-age=604800" # REACT_APP_HOTJAR_HJID=
# REACT_APP_HOTJAR_HJSV=
# REACT_APP_OAUTH2_GOOGLE_CLIENT_ID=
# REACT_APP_OAUTH2_GITHUB_CLIENT_ID=
# REACT_APP_SEGMENT_KEY=
# REACT_APP_MARKETPLACE_URL=
# REACT_APP_OPTIMIZELY_KEY=
# REACT_APP_ALGOLIA_API_ID=
# REACT_APP_ALGOLIA_API_KEY=
# REACT_APP_ALGOLIA_SEARCH_INDEX_NAME=
REACT_APP_CLIENT_LOG_LEVEL="debug"
# REACT_APP_GOOGLE_MAPS_API_KEY=
[context.production] [context.production]
[context.production.environment] [context.production.environment]
@ -15,30 +26,18 @@
REACT_APP_BASE_URL = "https://release-api.appsmith.com" REACT_APP_BASE_URL = "https://release-api.appsmith.com"
APP_HOST = "release.app.appsmith.com" APP_HOST = "release.app.appsmith.com"
[context.develop]
[context.develop.environment]
REACT_APP_ENVIRONMENT = "DEVELOPMENT"
REACT_APP_BASE_URL = "https://release-api.appsmith.com"
APP_HOST = "develop.app.appsmith.com"
[context.a]
[context.a.environment]
REACT_APP_ENVIRONMENT = "STAGING"
REACT_APP_BASE_URL = "https://release-api.appsmith.com"
APP_HOST = "a.app.appsmith.com"
[context.b]
[context.b.environment]
REACT_APP_ENVIRONMENT = "STAGING"
REACT_APP_BASE_URL = "https://release-api.appsmith.com"
APP_HOST = "b.app.appsmith.com"
[context.deploy-preview] [context.deploy-preview]
[context.deploy-preview.environment] [context.deploy-preview.environment]
REACT_APP_ENVIRONMENT = "STAGING" REACT_APP_ENVIRONMENT = "STAGING"
REACT_APP_BASE_URL = "https://release-api.appsmith.com" REACT_APP_BASE_URL = "https://release-api.appsmith.com"
# Not adding an APP_HOST here because the URL is dynamic in nature and cannot be determined. # Not adding an APP_HOST here because the URL is dynamic in nature and cannot be determined.
[[headers]]
for = "/static/*"
[header.values]
cache-control = "max-age=604800"
[[redirects]] [[redirects]]
from = "/api/*" from = "/api/*"
to = "API_PLACEHOLDER/api/:splat" to = "API_PLACEHOLDER/api/:splat"

View File

@ -117,11 +117,11 @@
"start": "REACT_APP_BASE_URL=https://release-api.appsmith.com REACT_APP_ENVIRONMENT=DEVELOPMENT HOST=dev.appsmith.com craco start", "start": "REACT_APP_BASE_URL=https://release-api.appsmith.com REACT_APP_ENVIRONMENT=DEVELOPMENT HOST=dev.appsmith.com craco start",
"build": "./build.sh", "build": "./build.sh",
"build-local": "craco --max-old-space-size=4096 build --config craco.build.config.js", "build-local": "craco --max-old-space-size=4096 build --config craco.build.config.js",
"build-staging": "REACT_APP_BASE_URL=https://release-api.appsmith.com REACT_APP_ENVIRONMENT=STAGING craco --max-old-space-size=4096 build --config craco.build.config.js", "build-staging": " REACT_APP_ENVIRONMENT=STAGING craco --max-old-space-size=4096 build --config craco.build.config.js",
"test": "CYPRESS_BASE_URL=https://dev.appsmith.com cypress/test.sh", "test": "CYPRESS_BASE_URL=https://dev.appsmith.com cypress/test.sh",
"test:ci": "CYPRESS_BASE_URL=https://dev.appsmith.com cypress/test.sh --env=ci", "test:ci": "CYPRESS_BASE_URL=https://dev.appsmith.com cypress/test.sh --env=ci",
"eject": "react-scripts eject", "eject": "react-scripts eject",
"start-prod": "REACT_APP_BASE_URL=https://api.appsmith.com REACT_APP_ENVIRONMENT=PRODUCTION craco start", "start-prod": "REACT_APP_ENVIRONMENT=PRODUCTION craco start",
"cytest": "REACT_APP_TESTING=TESTING REACT_APP_ENVIRONMENT=DEVELOPMENT craco start & ./node_modules/.bin/cypress open", "cytest": "REACT_APP_TESTING=TESTING REACT_APP_ENVIRONMENT=DEVELOPMENT craco start & ./node_modules/.bin/cypress open",
"test:unit": "$(npm bin)/jest -b --colors" "test:unit": "$(npm bin)/jest -b --colors"
}, },

View File

@ -43,7 +43,37 @@
} }
}; };
registerPageServiceWorker(); registerPageServiceWorker();
</script>
<script type="text/javascript">
const parseConfig = (config) => {
if(config.indexOf("__") === 0 || config.indexOf("$") === 0)
return "";
return config.trim();
}
const LOG_LEVELS = ["debug", "error"];
const CONFIG_LOG_LEVEL_INDEX = LOG_LEVELS.indexOf(parseConfig("__APPSMITH_CLIENT_LOG_LEVEL__"));
window.SENTRY_CONFIG = parseConfig("__APPSMITH_SENTRY_DSN__");
window.APPSMITH_FEATURE_CONFIGS = {
sentry: parseConfig("__APPSMITH_SENTRY_DSN__"),
hotjar: {
id: parseConfig("__APPSMITH_HOTJAR_HJID__"),
sv: parseConfig("__APPSMITH_HOTJAR_HJSV__"),
},
enableGoogleOAuth: parseConfig("__APPSMITH_OAUTH2_GOOGLE_CLIENT_ID__").length > 0,
enableGithubOAuth: parseConfig("__APPSMITH_OAUTH2_GITHUB_CLIENT_ID__").length > 0,
enableRapidAPI: parseConfig("__APPSMITH_MARKETPLACE_URL__").length > 0,
segment: parseConfig("__APPSMITH_SEGMENT_KEY__"),
optimizely: parseConfig("__APPSMITH_OPTIMIZELY_KEY__"),
enableMixpanel: parseConfig("__APPSMITH_SEGMENT_KEY__").length > 0,
algolia: {
apiId: parseConfig("__APPSMITH_ALGOLIA_API_ID__"),
apiKey: parseConfig("__APPSMITH_ALGOLIA_API_KEY__"),
indexName: parseConfig("__APPSMITH_ALGOLIA_SEARCH_INDEX_NAME__"),
},
logLevel: CONFIG_LOG_LEVEL_INDEX > -1 ? LOG_LEVELS[CONFIG_LOG_LEVEL_INDEX] : LOG_LEVELS[1],
google: parseConfig("__APPSMITH_GOOGLE_MAPS_API_KEY__"),
enableTNCPP: parseConfig("__APPSMITH_TNC_PP__").length > 0
};
</script> </script>
<script rel="prefetch" type="text/javascript" src="/shims/realms-shim.umd.min.js"></script> <script rel="prefetch" type="text/javascript" src="/shims/realms-shim.umd.min.js"></script>
</body> </body>

View File

@ -1,6 +1,5 @@
import _ from "lodash"; import _ from "lodash";
import axios, { AxiosInstance, AxiosRequestConfig } from "axios"; import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
import { getAppsmithConfigs } from "configs";
import { import {
REQUEST_TIMEOUT_MS, REQUEST_TIMEOUT_MS,
API_REQUEST_HEADERS, API_REQUEST_HEADERS,
@ -9,11 +8,10 @@ import { ActionApiResponse } from "./ActionAPI";
import { AUTH_LOGIN_URL } from "constants/routes"; import { AUTH_LOGIN_URL } from "constants/routes";
import { setRouteBeforeLogin } from "utils/storage"; import { setRouteBeforeLogin } from "utils/storage";
import history from "utils/history"; import history from "utils/history";
const { apiUrl, baseUrl } = getAppsmithConfigs();
//TODO(abhinav): Refactor this to make more composable. //TODO(abhinav): Refactor this to make more composable.
export const apiRequestConfig = { export const apiRequestConfig = {
baseURL: baseUrl + apiUrl, baseURL: "/api/",
timeout: REQUEST_TIMEOUT_MS, timeout: REQUEST_TIMEOUT_MS,
headers: API_REQUEST_HEADERS, headers: API_REQUEST_HEADERS,
withCredentials: true, withCredentials: true,

View File

@ -4,17 +4,12 @@ import {
InstantSearch, InstantSearch,
Hits, Hits,
SearchBox, SearchBox,
// Pagination,
Highlight, Highlight,
// ClearRefinements,
// RefinementList,
Configure, Configure,
PoweredBy, PoweredBy,
} from "react-instantsearch-dom"; } from "react-instantsearch-dom";
// import "instantsearch.css/themes/reset.css";
import "instantsearch.css/themes/algolia.css"; import "instantsearch.css/themes/algolia.css";
// import "./search.css";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { Icon } from "@blueprintjs/core"; import { Icon } from "@blueprintjs/core";
@ -27,35 +22,10 @@ import styled from "styled-components";
import { HelpIcons } from "icons/HelpIcons"; import { HelpIcons } from "icons/HelpIcons";
import { HelpBaseURL } from "constants/HelpConstants"; import { HelpBaseURL } from "constants/HelpConstants";
import { getDefaultRefinement } from "selectors/helpSelectors"; import { getDefaultRefinement } from "selectors/helpSelectors";
import { getAppsmithConfigs } from "configs";
const searchClient = algoliasearch( const { algolia } = getAppsmithConfigs();
"AZ2Z9CJSJ0", const searchClient = algoliasearch(algolia.apiId, algolia.apiKey);
"d113611dccb80ac14aaa72a6e3ac6d10", console.log({ algolia });
);
// const StyledBack = styled(Button)`
// position: absolute;
// top: 36px;
// left: 5px;
// z-index: 26;
// `;
// const StyledAnchor = styled.a`
// position: absolute;
// right: 24px;
// top: 40px;
// z-index: 26;
// `;
// const headerHeight = 91;
// const OpenIcon = styled(Icon)`
// position: absolute;
// right: 0;
// top: 3px;
// color: #888;
// `;
const OenLinkIcon = HelpIcons.OPEN_LINK; const OenLinkIcon = HelpIcons.OPEN_LINK;
const DocumentIcon = HelpIcons.DOCUMENT; const DocumentIcon = HelpIcons.DOCUMENT;
@ -63,7 +33,6 @@ const StyledOpenLinkIcon = styled(OenLinkIcon)`
position: absolute; position: absolute;
right: 14px; right: 14px;
top: 1px; top: 1px;
// color: #888;
width: 12px; width: 12px;
height: 12px; height: 12px;
display: none; display: none;
@ -80,8 +49,6 @@ const StyledDocumentIcon = styled(DocumentIcon)`
position: absolute; position: absolute;
`; `;
function Hit(props: any) { function Hit(props: any) {
// const dispatch = useDispatch();
return ( return (
<div <div
className="t--docHit" className="t--docHit"
@ -90,15 +57,6 @@ function Hit(props: any) {
(props.hit.path as string).replace("master", HelpBaseURL), (props.hit.path as string).replace("master", HelpBaseURL),
"_blank", "_blank",
); );
// console.log(props);
// dispatch(
// setHelpUrl(
// (props.hit.path as string).replace(
// "master",
// HelpBaseURL,
// ),
// ),
// );
}} }}
> >
<div className="hit-name t--docHitTitle"> <div className="hit-name t--docHitTitle">
@ -113,11 +71,6 @@ function Hit(props: any) {
color={"#181F24"} color={"#181F24"}
></StyledOpenLinkIcon> ></StyledOpenLinkIcon>
</div> </div>
{/* <div className="hit-description t--docHitDesc">
<Highlight attribute="description" hit={props.hit} />
<Highlight attribute="document" hit={props.hit} />
</div> */}
</div> </div>
); );
} }
@ -129,8 +82,6 @@ Hit.propTypes = {
const Header = styled.div` const Header = styled.div`
position: absolute; position: absolute;
width: 100%; width: 100%;
// background: #363e44;
// padding-bottom: 20px;
border-top-right-radius: 3px; border-top-right-radius: 3px;
border-top-left-radius: 3px; border-top-left-radius: 3px;
`; `;
@ -160,7 +111,6 @@ const SearchContainer = styled.div`
margin-top: 86px; margin-top: 86px;
height: calc(100% - 86px); height: calc(100% - 86px);
overflow: auto; overflow: auto;
// border: 1px solid #d0d7dd;
border-bottom-left-radius: 3px; border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px; border-bottom-right-radius: 3px;
} }
@ -193,8 +143,6 @@ const SearchContainer = styled.div`
padding: 5px; padding: 5px;
border: 0; border: 0;
cursor: pointer; cursor: pointer;
// border-bottom: 1px solid #d0d7dd;
// box-sizing: border-box;
box-shadow: none; box-shadow: none;
} }
@ -206,8 +154,6 @@ const SearchContainer = styled.div`
} }
.hit-name { .hit-name {
// margin-bottom: 0.5em;
// font-weight: 500;
font-size: 14px; font-size: 14px;
line-height: 16px; line-height: 16px;
color: #e7e9e9; color: #e7e9e9;
@ -274,7 +220,8 @@ const StyledPoweredBy = styled(PoweredBy)`
export default function DocumentationSearch(props: { hitsPerPage: number }) { export default function DocumentationSearch(props: { hitsPerPage: number }) {
const dispatch = useDispatch(); const dispatch = useDispatch();
const defaultRefinement = useSelector(getDefaultRefinement); const defaultRefinement = useSelector(getDefaultRefinement);
console.log({ algolia });
if (!algolia.enabled) return null;
return ( return (
<SearchContainer className="ais-InstantSearch t--docSearchModal"> <SearchContainer className="ais-InstantSearch t--docSearchModal">
<Icon <Icon
@ -301,7 +248,10 @@ export default function DocumentationSearch(props: { hitsPerPage: number }) {
overflow: "auto", overflow: "auto",
}} }}
> >
<InstantSearch indexName="test_appsmith" searchClient={searchClient}> <InstantSearch
indexName={algolia.indexName}
searchClient={searchClient}
>
<Configure hitsPerPage={props.hitsPerPage} /> <Configure hitsPerPage={props.hitsPerPage} />
<Header> <Header>
<h3 <h3
@ -316,7 +266,6 @@ export default function DocumentationSearch(props: { hitsPerPage: number }) {
style={{ style={{
textAlign: "center", textAlign: "center",
color: "white", color: "white",
// zIndex: 55,
position: "relative", position: "relative",
fontWeight: 500, fontWeight: 500,
fontSize: "14px", fontSize: "14px",

View File

@ -16,7 +16,8 @@ import { theme } from "constants/DefaultTheme";
import ModalComponent from "components/designSystems/blueprint/ModalComponent"; import ModalComponent from "components/designSystems/blueprint/ModalComponent";
import { LayersContext } from "constants/Layers"; import { LayersContext } from "constants/Layers";
import { HelpIcons } from "icons/HelpIcons"; import { HelpIcons } from "icons/HelpIcons";
import { getAppsmithConfigs } from "configs";
const { algolia } = getAppsmithConfigs();
const HelpButton = styled.div<{ const HelpButton = styled.div<{
highlight: boolean; highlight: boolean;
layer: number; layer: number;
@ -35,7 +36,6 @@ const HelpButton = styled.div<{
border: 0; border: 0;
cursor: pointer; cursor: pointer;
font-size: 20px; font-size: 20px;
// box-shadow: 2px 4px 5px #888888;
svg { svg {
width: 25px; width: 25px;
@ -77,6 +77,7 @@ export function HelpModal() {
> >
<DocumentationSearch hitsPerPage={5} /> <DocumentationSearch hitsPerPage={5} />
</ModalComponent> </ModalComponent>
{algolia.enabled && (
<HelpButton <HelpButton
className="t--helpGlobalButton" className="t--helpGlobalButton"
highlight={!helpModalOpen} highlight={!helpModalOpen}
@ -87,6 +88,7 @@ export function HelpModal() {
> >
<HelpIcon /> <HelpIcon />
</HelpButton> </HelpButton>
)}
</> </>
); );
} }

View File

@ -1,20 +0,0 @@
import { AppsmithUIConfigs } from "./types";
import stageConfig from "./stage.config";
const autoConfig = (baseUrl: string): AppsmithUIConfigs => ({
...stageConfig(baseUrl),
segment: {
enabled: false,
key: "NZALSCjsaxOIyprzITLz2yZwFzQynGt1",
},
featureFlag: {
// remoteConfig: {
// optimizely: "PVDSYRhBhvUVY3tN6mkV1s",
// },
default: {
lightningmenu: false,
},
},
});
export default autoConfig;

View File

@ -1,29 +0,0 @@
import { SENTRY_STAGE_CONFIG } from "constants/ThirdPartyConstants";
import { AppsmithUIConfigs } from "./types";
const devConfig = (baseUrl: string): AppsmithUIConfigs => ({
sentry: {
enabled: false,
config: SENTRY_STAGE_CONFIG,
},
hotjar: {
enabled: false,
},
segment: {
enabled: false,
key: "NZALSCjsaxOIyprzITLz2yZwFzQynGt1",
},
featureFlag: {
remoteConfig: {
optimizely: "PVDSYRhBhvUVY3tN6mkV1s",
},
default: {
lightningmenu: true,
},
},
apiUrl: "/api/",
baseUrl,
logLevel: "debug",
});
export default devConfig;

View File

@ -1,31 +1,159 @@
import prodConfig from "./prod.config"; import { AppsmithUIConfigs, FeatureFlagConfig } from "./types";
import stageConfig from "./stage.config"; type INJECTED_CONFIGS = {
import autoConfig from "./stage.config"; sentry: string;
import devConfig from "./dev.config"; hotjar: {
import { AppsmithUIConfigs } from "./types"; id: string;
sv: string;
};
enableGoogleOAuth: boolean;
enableGithubOAuth: boolean;
enableRapidAPI: boolean;
segment: string;
optimizely: string;
enableMixpanel: boolean;
google: string;
enableTNCPP: boolean;
algolia: {
apiId: string;
apiKey: string;
indexName: string;
};
logLevel: "debug" | "error";
};
declare global { declare global {
interface Window { interface Window {
BASE_URL: string; APPSMITH_FEATURE_CONFIGS: INJECTED_CONFIGS;
} }
} }
// TODO(Abhinav): See if this is called so many times, that we may need memoization. const getConfigsFromEnvVars = (): INJECTED_CONFIGS => {
export const getAppsmithConfigs = (): AppsmithUIConfigs => { return {
const BASE_URL = ""; sentry: process.env.REACT_APP_SENTRY_DSN || "",
switch (process.env.REACT_APP_ENVIRONMENT) { hotjar: {
case "PRODUCTION": id: process.env.REACT_APP_HOTJAR_HJID || "",
return prodConfig(BASE_URL); sv: process.env.REACT_APP_HOTJAR_HJSV || "",
case "STAGING": },
return stageConfig(BASE_URL); enableGoogleOAuth: process.env.REACT_APP_OAUTH2_GOOGLE_CLIENT_ID
case "DEVELOPMENT": ? process.env.REACT_APP_OAUTH2_GOOGLE_CLIENT_ID.length > 0
return devConfig(BASE_URL); : false,
case "AUTOMATION": enableGithubOAuth: process.env.REACT_APP_OAUTH2_GITHUB_CLIENT_ID
return autoConfig(BASE_URL); ? process.env.REACT_APP_OAUTH2_GITHUB_CLIENT_ID.length > 0
default: : false,
console.log( segment: process.env.REACT_APP_SEGMENT_KEY || "",
"Unknown environment set: ", optimizely: process.env.REACT_APP_OPTIMIZELY_KEY || "",
process.env.REACT_APP_ENVIRONMENT, enableMixpanel: process.env.REACT_APP_SEGMENT_KEY
); ? process.env.REACT_APP_SEGMENT_KEY.length > 0
return devConfig(BASE_URL); : false,
} algolia: {
apiId: process.env.REACT_APP_ALGOLIA_API_ID || "",
apiKey: process.env.REACT_APP_ALGOLIA_API_KEY || "",
indexName: process.env.REACT_APP_ALGOLIA_SEARCH_INDEX_NAME || "",
},
logLevel:
(process.env.REACT_APP_CLIENT_LOG_LEVEL as
| "debug"
| "error"
| undefined) || "debug",
google: process.env.REACT_APP_GOOGLE_MAPS_API_KEY || "",
enableTNCPP: process.env.REACT_APP_TNC_PP
? process.env.REACT_APP_TNC_PP.length > 0
: false,
enableRapidAPI: process.env.REACT_APP_MARKETPLACE_URL
? process.env.REACT_APP_MARKETPLACE_URL.length > 0
: false,
};
};
const getConfig = (fromENV: string, fromWindow: string) => {
if (fromENV.length > 0) return { enabled: true, value: fromENV };
else if (fromWindow.length > 0) return { enabled: true, value: fromWindow };
return { enabled: false, value: "" };
};
// TODO(Abhinav): See if this is called so many times, that we may need some form of memoization.
export const getAppsmithConfigs = (): AppsmithUIConfigs => {
const { APPSMITH_FEATURE_CONFIGS } = window;
const ENV_CONFIG = getConfigsFromEnvVars();
const getFeatureFlags = (
optimizelyApiKey: string,
): FeatureFlagConfig | undefined => {
if (optimizelyApiKey.length > 0) {
return {
remoteConfig: {
optimizely: optimizelyApiKey,
},
default: {},
};
}
return;
};
const sentry = getConfig(ENV_CONFIG.sentry, APPSMITH_FEATURE_CONFIGS.sentry);
const segment = getConfig(
ENV_CONFIG.segment,
APPSMITH_FEATURE_CONFIGS.segment,
);
const google = getConfig(ENV_CONFIG.google, APPSMITH_FEATURE_CONFIGS.google);
// As the following shows, the config variables can be set using a combination
// of env variables and injected configs
const hotjarId = getConfig(
ENV_CONFIG.hotjar.id,
APPSMITH_FEATURE_CONFIGS.hotjar.id,
);
const hotjarSV = getConfig(
ENV_CONFIG.hotjar.sv,
APPSMITH_FEATURE_CONFIGS.hotjar.sv,
);
const algoliaAPIID = getConfig(
ENV_CONFIG.algolia.apiId,
APPSMITH_FEATURE_CONFIGS.algolia.apiKey,
);
const algoliaAPIKey = getConfig(
ENV_CONFIG.algolia.apiKey,
APPSMITH_FEATURE_CONFIGS.algolia.apiKey,
);
const algoliaIndex = getConfig(
ENV_CONFIG.algolia.indexName,
APPSMITH_FEATURE_CONFIGS.algolia.indexName,
);
return {
sentry: { enabled: sentry.enabled, apiKey: sentry.value },
hotjar: {
enabled: hotjarId.enabled && hotjarSV.enabled,
id: hotjarId.value,
sv: hotjarSV.value, //parse as int?
},
segment: {
enabled: segment.enabled,
apiKey: segment.value,
},
algolia: {
enabled: true,
apiId: algoliaAPIID.value || "AZ2Z9CJSJ0",
apiKey: algoliaAPIKey.value || "d113611dccb80ac14aaa72a6e3ac6d10",
indexName: algoliaIndex.value || "test_appsmith",
},
google: {
enabled: google.enabled,
apiKey: google.value,
},
enableRapidAPI:
ENV_CONFIG.enableRapidAPI || APPSMITH_FEATURE_CONFIGS.enableRapidAPI,
enableGithubOAuth:
ENV_CONFIG.enableGithubOAuth ||
APPSMITH_FEATURE_CONFIGS.enableGithubOAuth,
enableGoogleOAuth:
ENV_CONFIG.enableGoogleOAuth ||
APPSMITH_FEATURE_CONFIGS.enableGoogleOAuth,
enableMixpanel:
ENV_CONFIG.enableMixpanel || APPSMITH_FEATURE_CONFIGS.enableMixpanel,
featureFlag: getFeatureFlags(
ENV_CONFIG.optimizely || APPSMITH_FEATURE_CONFIGS.optimizely,
),
logLevel: ENV_CONFIG.logLevel || APPSMITH_FEATURE_CONFIGS.logLevel,
enableTNCPP: ENV_CONFIG.enableTNCPP || APPSMITH_FEATURE_CONFIGS.enableTNCPP,
};
}; };

View File

@ -1,37 +0,0 @@
import {
SENTRY_PROD_CONFIG,
HOTJAR_PROD_HJID,
HOTJAR_PROD_HJSV,
} from "constants/ThirdPartyConstants";
import { AppsmithUIConfigs } from "./types";
export const prodConfig = (baseUrl: string): AppsmithUIConfigs => ({
sentry: {
enabled: true,
config: SENTRY_PROD_CONFIG,
},
hotjar: {
enabled: true,
config: {
id: HOTJAR_PROD_HJID,
sv: HOTJAR_PROD_HJSV,
},
},
segment: {
enabled: true,
key: "O7rsLdWq7fhJI9rYsj1eatGAjuULTmfP",
},
apiUrl: "/api/",
baseUrl,
logLevel: "error",
featureFlag: {
remoteConfig: {
optimizely: "Jq3K2kVdvuvxecHyHbVYcj",
},
default: {
lightningmenu: false,
},
},
});
export default prodConfig;

View File

@ -1,29 +0,0 @@
import { SENTRY_STAGE_CONFIG } from "constants/ThirdPartyConstants";
import { AppsmithUIConfigs } from "./types";
const stageConfig = (baseUrl: string): AppsmithUIConfigs => ({
sentry: {
enabled: true,
config: SENTRY_STAGE_CONFIG,
},
hotjar: {
enabled: false,
},
segment: {
enabled: true,
key: "NZALSCjsaxOIyprzITLz2yZwFzQynGt1",
},
featureFlag: {
remoteConfig: {
optimizely: "2qP3XSwgM9pHYTEYbtbAQx",
},
default: {
lightningmenu: true,
},
},
apiUrl: "/api/",
baseUrl,
logLevel: "info",
});
export default stageConfig;

View File

@ -12,9 +12,7 @@ export type HotjarConfig = {
type Milliseconds = number; type Milliseconds = number;
export enum FeatureFlagsEnum { export enum FeatureFlagsEnum {}
LightningMenu = "lightningmenu",
}
export type FeatureFlags = Record<FeatureFlagsEnum, boolean>; export type FeatureFlags = Record<FeatureFlagsEnum, boolean>;
@ -28,18 +26,35 @@ export type FeatureFlagConfig = {
export type AppsmithUIConfigs = { export type AppsmithUIConfigs = {
sentry: { sentry: {
enabled: boolean; enabled: boolean;
config?: SentryConfig; apiKey: string;
}; };
hotjar: { hotjar: {
enabled: boolean; enabled: boolean;
config?: HotjarConfig; id: string;
sv: string;
}; };
featureFlag: FeatureFlagConfig;
segment: { segment: {
enabled: boolean; enabled: boolean;
key: string; apiKey: string;
}; };
apiUrl: string; algolia: {
baseUrl: string; enabled: boolean;
apiId: string;
apiKey: string;
indexName: string;
};
google: {
enabled: boolean;
apiKey: string;
};
enableRapidAPI: boolean;
enableGoogleOAuth: boolean;
enableGithubOAuth: boolean;
enableMixpanel: boolean;
enableTNCPP: boolean;
featureFlag?: FeatureFlagConfig;
logLevel: LogLevelDesc; logLevel: LogLevelDesc;
}; };

View File

@ -1,8 +1,6 @@
import { GoogleOAuthURL, GithubOAuthURL } from "constants/ApiConstants"; import { GoogleOAuthURL, GithubOAuthURL } from "constants/ApiConstants";
import GithubLogo from "assets/images/Github.png"; import GithubLogo from "assets/images/Github.png";
import GoogleLogo from "assets/images/Google.png"; import GoogleLogo from "assets/images/Google.png";
import { getAppsmithConfigs } from "configs";
const { baseUrl } = getAppsmithConfigs();
export type SocialLoginButtonProps = { export type SocialLoginButtonProps = {
url: string; url: string;
name: string; name: string;
@ -10,13 +8,13 @@ export type SocialLoginButtonProps = {
}; };
export const GoogleSocialLoginButtonProps: SocialLoginButtonProps = { export const GoogleSocialLoginButtonProps: SocialLoginButtonProps = {
url: baseUrl + GoogleOAuthURL, url: GoogleOAuthURL,
name: "Google", name: "Google",
logo: GoogleLogo, logo: GoogleLogo,
}; };
export const GithubSocialLoginButtonProps: SocialLoginButtonProps = { export const GithubSocialLoginButtonProps: SocialLoginButtonProps = {
url: baseUrl + GithubOAuthURL, url: GithubOAuthURL,
name: "Github", name: "Github",
logo: GithubLogo, logo: GithubLogo,
}; };

View File

@ -1,14 +1 @@
export type ENVIRONMENT = "PRODUCTION" | "STAGING" | "LOCAL"; export type ENVIRONMENT = "PRODUCTION" | "STAGING" | "LOCAL";
export const SENTRY_PROD_CONFIG = {
dsn: "https://a63362b692d64edeb175741f1f80b091@sentry.io/1546547",
environment: "Production",
release: process.env.REACT_APP_SENTRY_RELEASE,
};
export const SENTRY_STAGE_CONFIG = {
dsn: "https://26e99889a7f14b418a66cb2deafeb40c@sentry.io/4113637",
environment: "Staging",
release: process.env.REACT_APP_SENTRY_RELEASE,
};
export const HOTJAR_PROD_HJID = "1465835";
export const HOTJAR_PROD_HJSV = "6";

View File

@ -49,6 +49,8 @@ import {
import { getInitialsAndColorCode } from "utils/AppsmithUtils"; import { getInitialsAndColorCode } from "utils/AppsmithUtils";
import AnalyticsUtil from "utils/AnalyticsUtil"; import AnalyticsUtil from "utils/AnalyticsUtil";
import { CURL } from "constants/ApiConstants"; import { CURL } from "constants/ApiConstants";
import { getAppsmithConfigs } from "configs";
const { enableRapidAPI } = getAppsmithConfigs();
const SearchContainer = styled.div` const SearchContainer = styled.div`
display: flex; display: flex;
@ -403,13 +405,13 @@ class ApiHomeScreen extends React.Component<Props, ApiHomeScreenState> {
providersTotal, providersTotal,
providerCategories, providerCategories,
} = this.props; } = this.props;
if (providerCategories.length === 0) { if (providerCategories.length === 0 && enableRapidAPI) {
this.props.fetchProviderCategories(); this.props.fetchProviderCategories();
} }
if (importedCollections.length === 0) { if (importedCollections.length === 0 && enableRapidAPI) {
this.props.fetchImportedCollections(); this.props.fetchImportedCollections();
} }
if (!providersTotal) { if (!providersTotal && enableRapidAPI) {
this.props.clearProviders(); this.props.clearProviders();
this.props.change("category", DEFAULT_PROVIDER_OPTION); this.props.change("category", DEFAULT_PROVIDER_OPTION);
this.props.fetchProvidersWithCategory({ this.props.fetchProvidersWithCategory({
@ -423,7 +425,8 @@ class ApiHomeScreen extends React.Component<Props, ApiHomeScreenState> {
componentDidUpdate(prevProps: Props) { componentDidUpdate(prevProps: Props) {
if ( if (
prevProps.currentCategory !== this.props.currentCategory && prevProps.currentCategory !== this.props.currentCategory &&
this.props.currentCategory !== this.props.previouslySetCategory this.props.currentCategory !== this.props.previouslySetCategory &&
enableRapidAPI
) { ) {
this.props.setCurrentCategory(this.props.currentCategory); this.props.setCurrentCategory(this.props.currentCategory);
this.props.clearProviders(); this.props.clearProviders();
@ -498,6 +501,7 @@ class ApiHomeScreen extends React.Component<Props, ApiHomeScreenState> {
const ApiHomepageTopSection = ( const ApiHomepageTopSection = (
<React.Fragment> <React.Fragment>
{enableRapidAPI && (
<SearchContainer> <SearchContainer>
<SearchBar <SearchBar
icon="search" icon="search"
@ -514,6 +518,8 @@ class ApiHomeScreen extends React.Component<Props, ApiHomeScreenState> {
placeholder="Search" placeholder="Search"
/> />
</SearchContainer> </SearchContainer>
)}
{enableRapidAPI && (
<div> <div>
{showSearchResults && ( {showSearchResults && (
<div className="searchResultsContainer"> <div className="searchResultsContainer">
@ -587,7 +593,7 @@ class ApiHomeScreen extends React.Component<Props, ApiHomeScreenState> {
</div> </div>
)} )}
</div> </div>
)}
<StyledContainer> <StyledContainer>
<p className="sectionHeadings">{"Import API"}</p> <p className="sectionHeadings">{"Import API"}</p>
<ApiCard> <ApiCard>
@ -624,7 +630,6 @@ class ApiHomeScreen extends React.Component<Props, ApiHomeScreenState> {
</Link> </Link>
</ApiCard> </ApiCard>
</StyledContainer> </StyledContainer>
{/* Imported APIs section start */} {/* Imported APIs section start */}
{/* <StyledContainer> {/* <StyledContainer>
<p className="sectionHeadings">{"Imported APIs"}</p> <p className="sectionHeadings">{"Imported APIs"}</p>
@ -664,12 +669,14 @@ class ApiHomeScreen extends React.Component<Props, ApiHomeScreenState> {
style={{ overflow: showSearchResults ? "hidden" : "auto" }} style={{ overflow: showSearchResults ? "hidden" : "auto" }}
className="t--apiHomePage" className="t--apiHomePage"
> >
{isSwitchingCategory ? ( {isSwitchingCategory || !enableRapidAPI ? (
<> <>
{ApiHomepageTopSection} {ApiHomepageTopSection}
{enableRapidAPI && isSwitchingCategory && (
<PageLoadingContainer> <PageLoadingContainer>
<Spinner size={30} /> <Spinner size={30} />
</PageLoadingContainer> </PageLoadingContainer>
)}
</> </>
) : ( ) : (
<> <>

View File

@ -44,9 +44,8 @@ import {
CREATE_PASSWORD_INVALID_TOKEN, CREATE_PASSWORD_INVALID_TOKEN,
CREATE_PASSWORD_RESET_SUCCESS, CREATE_PASSWORD_RESET_SUCCESS,
CREATE_PASSWORD_RESET_SUCCESS_LOGIN_LINK, CREATE_PASSWORD_RESET_SUCCESS_LOGIN_LINK,
PRIVACY_POLICY_LINK,
TERMS_AND_CONDITIONS_LINK,
} from "constants/messages"; } from "constants/messages";
import { TncPPLinks } from "./SignUp";
const validate = (values: CreatePasswordFormValues) => { const validate = (values: CreatePasswordFormValues) => {
const errors: CreatePasswordFormValues = {}; const errors: CreatePasswordFormValues = {};
@ -176,8 +175,7 @@ export const CreatePassword = (props: CreatePasswordProps) => {
{CREATE_PASSWORD_LOGIN_LINK_TEXT} {CREATE_PASSWORD_LOGIN_LINK_TEXT}
</AuthCardNavLink> </AuthCardNavLink>
<AuthCardFooter> <AuthCardFooter>
<Link to="#">{PRIVACY_POLICY_LINK}</Link> <TncPPLinks></TncPPLinks>
<Link to="#">{TERMS_AND_CONDITIONS_LINK}</Link>
</AuthCardFooter> </AuthCardFooter>
</AuthCardContainer> </AuthCardContainer>
); );

View File

@ -7,7 +7,6 @@ import {
LOGIN_FORM_EMAIL_FIELD_NAME, LOGIN_FORM_EMAIL_FIELD_NAME,
LOGIN_FORM_PASSWORD_FIELD_NAME, LOGIN_FORM_PASSWORD_FIELD_NAME,
} from "constants/forms"; } from "constants/forms";
import { getAppsmithConfigs } from "configs";
import { FORGOT_PASSWORD_URL, SIGN_UP_URL } from "constants/routes"; import { FORGOT_PASSWORD_URL, SIGN_UP_URL } from "constants/routes";
import { LOGIN_SUBMIT_PATH } from "constants/ApiConstants"; import { LOGIN_SUBMIT_PATH } from "constants/ApiConstants";
import { import {
@ -25,8 +24,6 @@ import {
LOGIN_PAGE_FORGOT_PASSWORD_TEXT, LOGIN_PAGE_FORGOT_PASSWORD_TEXT,
LOGIN_PAGE_SIGN_UP_LINK_TEXT, LOGIN_PAGE_SIGN_UP_LINK_TEXT,
LOGIN_PAGE_INVALID_CREDS_ERROR, LOGIN_PAGE_INVALID_CREDS_ERROR,
PRIVACY_POLICY_LINK,
TERMS_AND_CONDITIONS_LINK,
LOGIN_PAGE_INVALID_CREDS_FORGOT_PASSWORD_LINK, LOGIN_PAGE_INVALID_CREDS_FORGOT_PASSWORD_LINK,
FORM_VALIDATION_PASSWORD_RULE, FORM_VALIDATION_PASSWORD_RULE,
} from "constants/messages"; } from "constants/messages";
@ -49,6 +46,9 @@ import {
AuthCardBody, AuthCardBody,
} from "./StyledComponents"; } from "./StyledComponents";
import AnalyticsUtil from "utils/AnalyticsUtil"; import AnalyticsUtil from "utils/AnalyticsUtil";
import { getAppsmithConfigs } from "configs";
import { TncPPLinks } from "./SignUp";
const { enableGithubOAuth, enableGoogleOAuth } = getAppsmithConfigs();
const validate = (values: LoginFormValues) => { const validate = (values: LoginFormValues) => {
const errors: LoginFormValues = {}; const errors: LoginFormValues = {};
@ -73,6 +73,10 @@ type LoginFormProps = { emailValue: string } & InjectedFormProps<
{ emailValue: string } { emailValue: string }
>; >;
const SocialLoginList: string[] = [];
if (enableGithubOAuth) SocialLoginList.push(SocialLoginTypes.GITHUB);
if (enableGoogleOAuth) SocialLoginList.push(SocialLoginTypes.GOOGLE);
export const Login = (props: LoginFormProps) => { export const Login = (props: LoginFormProps) => {
const { error, valid } = props; const { error, valid } = props;
const location = useLocation(); const location = useLocation();
@ -88,8 +92,6 @@ export const Login = (props: LoginFormProps) => {
forgotPasswordURL += `?email=${props.emailValue}`; forgotPasswordURL += `?email=${props.emailValue}`;
} }
const { baseUrl, apiUrl } = getAppsmithConfigs();
return ( return (
<AuthCardContainer> <AuthCardContainer>
{showError && ( {showError && (
@ -110,10 +112,7 @@ export const Login = (props: LoginFormProps) => {
<h5>{LOGIN_PAGE_SUBTITLE}</h5> <h5>{LOGIN_PAGE_SUBTITLE}</h5>
</AuthCardHeader> </AuthCardHeader>
<AuthCardBody> <AuthCardBody>
<SpacedSubmitForm <SpacedSubmitForm method="POST" action={"/api/v1/" + LOGIN_SUBMIT_PATH}>
method="POST"
action={baseUrl + apiUrl + "v1/" + LOGIN_SUBMIT_PATH}
>
<FormGroup <FormGroup
intent={error ? "danger" : "none"} intent={error ? "danger" : "none"}
label={LOGIN_PAGE_EMAIL_INPUT_LABEL} label={LOGIN_PAGE_EMAIL_INPUT_LABEL}
@ -152,18 +151,14 @@ export const Login = (props: LoginFormProps) => {
/> />
</FormActions> </FormActions>
</SpacedSubmitForm> </SpacedSubmitForm>
<Divider /> {SocialLoginList.length > 0 && <Divider />}
<ThirdPartyAuth <ThirdPartyAuth type={"SIGNIN"} logins={SocialLoginList} />
type={"SIGNIN"}
logins={[SocialLoginTypes.GOOGLE, SocialLoginTypes.GITHUB]}
/>
</AuthCardBody> </AuthCardBody>
<AuthCardNavLink to={SIGN_UP_URL}> <AuthCardNavLink to={SIGN_UP_URL}>
{LOGIN_PAGE_SIGN_UP_LINK_TEXT} {LOGIN_PAGE_SIGN_UP_LINK_TEXT}
</AuthCardNavLink> </AuthCardNavLink>
<AuthCardFooter> <AuthCardFooter>
<Link to="#">{PRIVACY_POLICY_LINK}</Link> <TncPPLinks></TncPPLinks>
<Link to="#">{TERMS_AND_CONDITIONS_LINK}</Link>
</AuthCardFooter> </AuthCardFooter>
</AuthCardContainer> </AuthCardContainer>
); );

View File

@ -17,7 +17,6 @@ import Button from "components/editorComponents/Button";
import FormGroup from "components/editorComponents/form/FormGroup"; import FormGroup from "components/editorComponents/form/FormGroup";
import StyledForm from "components/editorComponents/Form"; import StyledForm from "components/editorComponents/Form";
import { isEmptyString, isStrongPassword } from "utils/formhelpers"; import { isEmptyString, isStrongPassword } from "utils/formhelpers";
import { ResetPasswordFormValues, resetPasswordSubmitHandler } from "./helpers"; import { ResetPasswordFormValues, resetPasswordSubmitHandler } from "./helpers";
import { import {
AuthCardHeader, AuthCardHeader,
@ -43,9 +42,8 @@ import {
RESET_PASSWORD_INVALID_TOKEN, RESET_PASSWORD_INVALID_TOKEN,
RESET_PASSWORD_RESET_SUCCESS, RESET_PASSWORD_RESET_SUCCESS,
RESET_PASSWORD_RESET_SUCCESS_LOGIN_LINK, RESET_PASSWORD_RESET_SUCCESS_LOGIN_LINK,
PRIVACY_POLICY_LINK,
TERMS_AND_CONDITIONS_LINK,
} from "constants/messages"; } from "constants/messages";
import { TncPPLinks } from "./SignUp";
const validate = (values: ResetPasswordFormValues) => { const validate = (values: ResetPasswordFormValues) => {
const errors: ResetPasswordFormValues = {}; const errors: ResetPasswordFormValues = {};
@ -183,8 +181,7 @@ export const ResetPassword = (props: ResetPasswordProps) => {
<Icon icon="arrow-right" intent="primary" /> <Icon icon="arrow-right" intent="primary" />
</AuthCardNavLink> </AuthCardNavLink>
<AuthCardFooter> <AuthCardFooter>
<Link to="#">{PRIVACY_POLICY_LINK}</Link> <TncPPLinks></TncPPLinks>
<Link to="#">{TERMS_AND_CONDITIONS_LINK}</Link>
</AuthCardFooter> </AuthCardFooter>
</AuthCardContainer> </AuthCardContainer>
); );

View File

@ -43,6 +43,30 @@ import { isEmail, isStrongPassword, isEmptyString } from "utils/formhelpers";
import { signupFormSubmitHandler, SignupFormValues } from "./helpers"; import { signupFormSubmitHandler, SignupFormValues } from "./helpers";
import AnalyticsUtil from "utils/AnalyticsUtil"; import AnalyticsUtil from "utils/AnalyticsUtil";
import { getAppsmithConfigs } from "configs";
const {
enableGithubOAuth,
enableGoogleOAuth,
enableTNCPP,
} = getAppsmithConfigs();
const SocialLoginList: string[] = [];
if (enableGithubOAuth) SocialLoginList.push(SocialLoginTypes.GITHUB);
if (enableGoogleOAuth) SocialLoginList.push(SocialLoginTypes.GOOGLE);
export const TncPPLinks = () => {
if (!enableTNCPP) return null;
return (
<>
<Link target="_blank" to="/privacy-policy.html">
{PRIVACY_POLICY_LINK}
</Link>
<Link target="_blank" to="/terms-and-conditions.html">
{TERMS_AND_CONDITIONS_LINK}
</Link>
</>
);
};
const validate = (values: SignupFormValues) => { const validate = (values: SignupFormValues) => {
const errors: SignupFormValues = {}; const errors: SignupFormValues = {};
if (!values.password || isEmptyString(values.password)) { if (!values.password || isEmptyString(values.password)) {
@ -128,20 +152,15 @@ export const SignUp = (props: InjectedFormProps<SignupFormValues>) => {
/> />
</FormActions> </FormActions>
</SpacedForm> </SpacedForm>
<Divider /> {SocialLoginList.length > 0 && <Divider />}
<ThirdPartyAuth <ThirdPartyAuth type={"SIGNUP"} logins={SocialLoginList} />
logins={[SocialLoginTypes.GOOGLE, SocialLoginTypes.GITHUB]}
type={"SIGNUP"}
/>
</AuthCardBody> </AuthCardBody>
<AuthCardFooter>
<TncPPLinks></TncPPLinks>
</AuthCardFooter>
<AuthCardNavLink to={AUTH_LOGIN_URL}> <AuthCardNavLink to={AUTH_LOGIN_URL}>
{SIGNUP_PAGE_LOGIN_LINK_TEXT} {SIGNUP_PAGE_LOGIN_LINK_TEXT}
</AuthCardNavLink> </AuthCardNavLink>
<AuthCardFooter>
<Link to="#">{PRIVACY_POLICY_LINK}</Link>
<Link to="#">{TERMS_AND_CONDITIONS_LINK}</Link>
</AuthCardFooter>
</AuthCardContainer> </AuthCardContainer>
); );
}; };

View File

@ -30,19 +30,18 @@ export const appInitializer = () => {
const appsmithConfigs = getAppsmithConfigs(); const appsmithConfigs = getAppsmithConfigs();
FeatureFlag.initialize(appsmithConfigs.featureFlag); FeatureFlag.initialize(appsmithConfigs.featureFlag);
if (appsmithConfigs.sentry.enabled && appsmithConfigs.sentry.config) { if (appsmithConfigs.sentry.enabled) {
Sentry.init(appsmithConfigs.sentry.config); Sentry.init({ dsn: appsmithConfigs.sentry.apiKey });
} }
if (appsmithConfigs.hotjar.enabled && appsmithConfigs.hotjar.config) { if (appsmithConfigs.hotjar.enabled) {
const { id, sv } = appsmithConfigs.hotjar.config; const { id, sv } = appsmithConfigs.hotjar;
AnalyticsUtil.initializeHotjar(id, sv); AnalyticsUtil.initializeHotjar(id, sv);
} }
if (appsmithConfigs.segment.enabled) { if (appsmithConfigs.segment.enabled) {
AnalyticsUtil.initializeSegment(appsmithConfigs.segment.key); AnalyticsUtil.initializeSegment(appsmithConfigs.segment.apiKey);
} }
log.setLevel(getEnvLogLevel(appsmithConfigs.logLevel)); log.setLevel(getEnvLogLevel(appsmithConfigs.logLevel));
// setConfigFeatureFlags(appsmithConfigs.featureFlags);
const textFont = new FontFaceObserver("DM Sans"); const textFont = new FontFaceObserver("DM Sans");
textFont textFont

View File

@ -4,7 +4,8 @@ const optimizelySDK = require("@optimizely/optimizely-sdk");
class FeatureFlag { class FeatureFlag {
static isInitialized = false; static isInitialized = false;
static remote = undefined; static remote = undefined;
static initialize(featureFlagConfig: FeatureFlagConfig) { static initialize(featureFlagConfig?: FeatureFlagConfig) {
if (featureFlagConfig) {
Object.keys(featureFlagConfig.default).forEach((flag: any) => { Object.keys(featureFlagConfig.default).forEach((flag: any) => {
// This is required because otherwise it will reset the values // This is required because otherwise it will reset the values
// every time the application is loaded. We need the application to load // every time the application is loaded. We need the application to load
@ -29,6 +30,7 @@ class FeatureFlag {
(FeatureFlag.remote as any).onReady().then(onInit); (FeatureFlag.remote as any).onReady().then(onInit);
} }
} }
}
static identify(userData: any) { static identify(userData: any) {
if (FeatureFlag.remote) { if (FeatureFlag.remote) {

View File

@ -1,4 +1,4 @@
import React, { useState } from "react"; import { useState } from "react";
export function useLocalStorage(key: string, initialValue: string) { export function useLocalStorage(key: string, initialValue: string) {
// State to store our value // State to store our value

View File

@ -1,7 +1,6 @@
import React, { lazy, Suspense } from "react"; import React, { lazy, Suspense } from "react";
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget"; import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
import { WidgetType } from "constants/WidgetConstants"; import { WidgetType } from "constants/WidgetConstants";
// import ChartComponent from "components/designSystems/appsmith/ChartComponent";
import { WidgetPropertyValidationType } from "utils/ValidationFactory"; import { WidgetPropertyValidationType } from "utils/ValidationFactory";
import { VALIDATION_TYPES } from "constants/WidgetValidation"; import { VALIDATION_TYPES } from "constants/WidgetValidation";
import Skeleton from "components/utils/Skeleton"; import Skeleton from "components/utils/Skeleton";

View File

@ -6,7 +6,26 @@ import { WidgetPropertyValidationType } from "utils/ValidationFactory";
import { VALIDATION_TYPES } from "constants/WidgetValidation"; import { VALIDATION_TYPES } from "constants/WidgetValidation";
import { EventType } from "constants/ActionConstants"; import { EventType } from "constants/ActionConstants";
import { TriggerPropertiesMap } from "utils/WidgetFactory"; import { TriggerPropertiesMap } from "utils/WidgetFactory";
import { getAppsmithConfigs } from "configs";
import styled from "styled-components";
const { google } = getAppsmithConfigs();
const DisabledContainer = styled.div`
background-color: white;
height: 100%;
text-align: center;
display: flex;
flex-direction: column;
h1 {
margin-top: 15%;
margin-bottom: 10%;
color: #7c7c7c;
}
p {
color: #0a0b0e;
}
`;
class MapWidget extends BaseWidget<MapWidgetProps, WidgetState> { class MapWidget extends BaseWidget<MapWidgetProps, WidgetState> {
static getPropertyValidationMap(): WidgetPropertyValidationType { static getPropertyValidationMap(): WidgetPropertyValidationType {
return { return {
@ -116,6 +135,24 @@ class MapWidget extends BaseWidget<MapWidgetProps, WidgetState> {
getPageView() { getPageView() {
return ( return (
<>
{!google.enabled && (
<DisabledContainer>
<h1>{"Map Widget disabled"}</h1>
<p>
{"Map widget requires a Google Maps "}
<a
target="_blank"
rel="noopener noreferrer"
href="https://developers.google.com/maps/documentation/javascript/get-api-key"
>
API Key
</a>
</p>
<p>{"Refer our Docs to configure API Keys"}</p>
</DisabledContainer>
)}
{google.enabled && (
<MapComponent <MapComponent
widgetId={this.props.widgetId} widgetId={this.props.widgetId}
isVisible={this.props.isVisible} isVisible={this.props.isVisible}
@ -136,6 +173,8 @@ class MapWidget extends BaseWidget<MapWidgetProps, WidgetState> {
this.disableDrag(false); this.disableDrag(false);
}} }}
/> />
)}
</>
); );
} }

View File

@ -11,6 +11,12 @@ if ! docker_loc="$(type -p "docker")" || [[ -z $docker_loc ]]; then
exit exit
fi fi
if ! envsubst_loc="$(type -p "envsubst")" || [[ -z $envsubst_loc ]]; then
echo "Could not find envsubst: If you're on a mac; brew install gettext"
exit
fi
KEY_FILE=./docker/_wildcard.appsmith.com-key.pem KEY_FILE=./docker/_wildcard.appsmith.com-key.pem
CERT_FILE=./docker/_wildcard.appsmith.com.pem CERT_FILE=./docker/_wildcard.appsmith.com.pem
if ! test -f "$KEY_FILE" || ! test -f "$CERT_FILE"; then if ! test -f "$KEY_FILE" || ! test -f "$CERT_FILE"; then
@ -26,13 +32,26 @@ if ! test -f "$KEY_FILE" || ! test -f "$CERT_FILE"; then
exit exit
fi fi
ENV_FILE=../../.env
if ! test -f "$ENV_FILE"; then
echo "
Please populate the .env at the root of the project and run again
Or add the environment variables defined in .env.example to the environment
-- to enable features
"
else
export $(grep -v '^[[:space:]]*#' ${ENV_FILE} | xargs)
fi
unameOut="$(uname -s)" unameOut="$(uname -s)"
vars_to_substitute="$(printf '\$%s,' $(grep -o "^APPSMITH_[A-Z0-9_]\+" ../../.env | xargs))"
case "${unameOut}" in case "${unameOut}" in
Linux*) machine=Linux Linux*) machine=Linux
echo " echo "
Starting nginx for Linux... Starting nginx for Linux...
" "
sudo docker run --network host --name wildcard-nginx -d -p 80:80 -p 443:443 -v `pwd`/docker/nginx-linux.conf:/etc/nginx/conf.d/app.conf -v `pwd`/docker/_wildcard.appsmith.com.pem:/etc/certificate/dev.appsmith.com.pem -v `pwd`/docker/_wildcard.appsmith.com-key.pem:/etc/certificate/dev.appsmith.com-key.pem nginx:latest \ cat ./docker/templates/nginx-linux.conf.template | envsubst ${vars_to_substitute} | sed -e 's|\${\(APPSMITH_[A-Z0-9_]*\)}||g' > ./docker/nginx.conf &&
sudo docker run --network host --name wildcard-nginx -d -p 80:80 -p 443:443 -v `pwd`/docker/nginx.conf:/etc/nginx/conf.d/app.conf -v `pwd`/docker/_wildcard.appsmith.com.pem:/etc/certificate/dev.appsmith.com.pem -v `pwd`/docker/_wildcard.appsmith.com-key.pem:/etc/certificate/dev.appsmith.com-key.pem nginx:latest \
&& echo " && echo "
nginx is listening on port 443 and forwarding to port 3000 nginx is listening on port 443 and forwarding to port 3000
visit https://dev.appsmith.com visit https://dev.appsmith.com
@ -42,7 +61,8 @@ case "${unameOut}" in
echo " echo "
Starting nginx for MacOS... Starting nginx for MacOS...
" "
docker run --name wildcard-nginx -d -p 80:80 -p 443:443 -v `pwd`/docker/nginx-mac.conf:/etc/nginx/conf.d/app.conf -v `pwd`/docker/_wildcard.appsmith.com.pem:/etc/certificate/dev.appsmith.com.pem -v `pwd`/docker/_wildcard.appsmith.com-key.pem:/etc/certificate/dev.appsmith.com-key.pem nginx:latest \ cat ./docker/templates/nginx-mac.conf.template | envsubst ${vars_to_substitute} | sed -e 's|\${\(APPSMITH_[A-Z0-9_]*\)}||g' > ./docker/nginx.conf &&
docker run --name wildcard-nginx -d -p 80:80 -p 443:443 -v `pwd`/docker/nginx.conf:/etc/nginx/conf.d/app.conf -v `pwd`/docker/_wildcard.appsmith.com.pem:/etc/certificate/dev.appsmith.com.pem -v `pwd`/docker/_wildcard.appsmith.com-key.pem:/etc/certificate/dev.appsmith.com-key.pem nginx:latest \
&& echo " && echo "
nginx is listening on port 443 and forwarding to port 3000 nginx is listening on port 443 and forwarding to port 3000
visit https://dev.appsmith.com visit https://dev.appsmith.com