diff --git a/.env.example b/.env.example new file mode 100644 index 000000000000..63e5526b5bc8 --- /dev/null +++ b/.env.example @@ -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= \ No newline at end of file diff --git a/.gitignore b/.gitignore index 0328ccfd0574..0cc1e4b6c531 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ .DS_Store .idea *.iml - +.env diff --git a/app/client/.gitignore b/app/client/.gitignore index 0716e41182ed..9336c8d51283 100755 --- a/app/client/.gitignore +++ b/app/client/.gitignore @@ -33,3 +33,5 @@ cypress/screenshots results/ /docker/*.pem +/docker/nginx.conf + diff --git a/app/client/Dockerfile b/app/client/Dockerfile index 73bf2c448096..d758b762ce48 100644 --- a/app/client/Dockerfile +++ b/app/client/Dockerfile @@ -1,7 +1,8 @@ FROM nginx:1.17.9-alpine COPY ./build /var/www/appsmith -RUN ls -al /var/www/appsmith 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"] diff --git a/app/client/docker/nginx-linux.conf b/app/client/docker/nginx-linux.conf deleted file mode 100644 index 9a6cbbab799d..000000000000 --- a/app/client/docker/nginx-linux.conf +++ /dev/null @@ -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; - } -} - diff --git a/app/client/docker/nginx-mac.conf b/app/client/docker/nginx-mac.conf deleted file mode 100644 index f9d3f49378a7..000000000000 --- a/app/client/docker/nginx-mac.conf +++ /dev/null @@ -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; - } -} diff --git a/app/client/docker/start-nginx.sh b/app/client/docker/start-nginx.sh new file mode 100755 index 000000000000..e4b1192492a6 --- /dev/null +++ b/app/client/docker/start-nginx.sh @@ -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;' diff --git a/app/client/docker/templates/nginx-linux.conf.template b/app/client/docker/templates/nginx-linux.conf.template new file mode 100644 index 000000000000..9d1583fc6278 --- /dev/null +++ b/app/client/docker/templates/nginx-linux.conf.template @@ -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; + } +} + diff --git a/app/client/docker/templates/nginx-mac.conf.template b/app/client/docker/templates/nginx-mac.conf.template new file mode 100644 index 000000000000..f51dbf1962e7 --- /dev/null +++ b/app/client/docker/templates/nginx-mac.conf.template @@ -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; + } +} diff --git a/app/client/netlify.toml b/app/client/netlify.toml index 33e87ca64587..195f047eaf13 100644 --- a/app/client/netlify.toml +++ b/app/client/netlify.toml @@ -1,7 +1,18 @@ -[[headers]] - for = "/static/*" - [header.values] - cache-control = "max-age=604800" +[build] + [build.environment] +# REACT_APP_SENTRY_DSN= +# 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.environment] @@ -15,30 +26,18 @@ REACT_APP_BASE_URL = "https://release-api.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.environment] REACT_APP_ENVIRONMENT = "STAGING" 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. + +[[headers]] + for = "/static/*" + [header.values] + cache-control = "max-age=604800" + [[redirects]] from = "/api/*" to = "API_PLACEHOLDER/api/:splat" diff --git a/app/client/package.json b/app/client/package.json index 5647b5ce7a57..43beb91e15e1 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -117,11 +117,11 @@ "start": "REACT_APP_BASE_URL=https://release-api.appsmith.com REACT_APP_ENVIRONMENT=DEVELOPMENT HOST=dev.appsmith.com craco start", "build": "./build.sh", "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:ci": "CYPRESS_BASE_URL=https://dev.appsmith.com cypress/test.sh --env=ci", "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", "test:unit": "$(npm bin)/jest -b --colors" }, diff --git a/app/client/public/index.html b/app/client/public/index.html index d19be4efdacb..d18abb3ac9a0 100755 --- a/app/client/public/index.html +++ b/app/client/public/index.html @@ -43,7 +43,37 @@ } }; registerPageServiceWorker(); - + + diff --git a/app/client/src/api/Api.tsx b/app/client/src/api/Api.tsx index eebf9076b34c..2566056cc88c 100644 --- a/app/client/src/api/Api.tsx +++ b/app/client/src/api/Api.tsx @@ -1,6 +1,5 @@ import _ from "lodash"; import axios, { AxiosInstance, AxiosRequestConfig } from "axios"; -import { getAppsmithConfigs } from "configs"; import { REQUEST_TIMEOUT_MS, API_REQUEST_HEADERS, @@ -9,11 +8,10 @@ import { ActionApiResponse } from "./ActionAPI"; import { AUTH_LOGIN_URL } from "constants/routes"; import { setRouteBeforeLogin } from "utils/storage"; import history from "utils/history"; -const { apiUrl, baseUrl } = getAppsmithConfigs(); //TODO(abhinav): Refactor this to make more composable. export const apiRequestConfig = { - baseURL: baseUrl + apiUrl, + baseURL: "/api/", timeout: REQUEST_TIMEOUT_MS, headers: API_REQUEST_HEADERS, withCredentials: true, diff --git a/app/client/src/components/designSystems/appsmith/help/DocumentationSearch.tsx b/app/client/src/components/designSystems/appsmith/help/DocumentationSearch.tsx index be9001a6c5d9..9c47a6de364e 100644 --- a/app/client/src/components/designSystems/appsmith/help/DocumentationSearch.tsx +++ b/app/client/src/components/designSystems/appsmith/help/DocumentationSearch.tsx @@ -4,17 +4,12 @@ import { InstantSearch, Hits, SearchBox, - // Pagination, Highlight, - // ClearRefinements, - // RefinementList, Configure, PoweredBy, } from "react-instantsearch-dom"; -// import "instantsearch.css/themes/reset.css"; import "instantsearch.css/themes/algolia.css"; -// import "./search.css"; import PropTypes from "prop-types"; import { Icon } from "@blueprintjs/core"; @@ -27,35 +22,10 @@ import styled from "styled-components"; import { HelpIcons } from "icons/HelpIcons"; import { HelpBaseURL } from "constants/HelpConstants"; import { getDefaultRefinement } from "selectors/helpSelectors"; - -const searchClient = algoliasearch( - "AZ2Z9CJSJ0", - "d113611dccb80ac14aaa72a6e3ac6d10", -); - -// 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; -// `; - +import { getAppsmithConfigs } from "configs"; +const { algolia } = getAppsmithConfigs(); +const searchClient = algoliasearch(algolia.apiId, algolia.apiKey); +console.log({ algolia }); const OenLinkIcon = HelpIcons.OPEN_LINK; const DocumentIcon = HelpIcons.DOCUMENT; @@ -63,7 +33,6 @@ const StyledOpenLinkIcon = styled(OenLinkIcon)` position: absolute; right: 14px; top: 1px; - // color: #888; width: 12px; height: 12px; display: none; @@ -80,8 +49,6 @@ const StyledDocumentIcon = styled(DocumentIcon)` position: absolute; `; function Hit(props: any) { - // const dispatch = useDispatch(); - return (
@@ -113,11 +71,6 @@ function Hit(props: any) { color={"#181F24"} >
- - {/*
- - -
*/}
); } @@ -129,8 +82,6 @@ Hit.propTypes = { const Header = styled.div` position: absolute; width: 100%; - // background: #363e44; - // padding-bottom: 20px; border-top-right-radius: 3px; border-top-left-radius: 3px; `; @@ -160,7 +111,6 @@ const SearchContainer = styled.div` margin-top: 86px; height: calc(100% - 86px); overflow: auto; - // border: 1px solid #d0d7dd; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; } @@ -193,8 +143,6 @@ const SearchContainer = styled.div` padding: 5px; border: 0; cursor: pointer; - // border-bottom: 1px solid #d0d7dd; - // box-sizing: border-box; box-shadow: none; } @@ -206,8 +154,6 @@ const SearchContainer = styled.div` } .hit-name { - // margin-bottom: 0.5em; - // font-weight: 500; font-size: 14px; line-height: 16px; color: #e7e9e9; @@ -274,7 +220,8 @@ const StyledPoweredBy = styled(PoweredBy)` export default function DocumentationSearch(props: { hitsPerPage: number }) { const dispatch = useDispatch(); const defaultRefinement = useSelector(getDefaultRefinement); - + console.log({ algolia }); + if (!algolia.enabled) return null; return ( - +

- { - dispatch(setHelpModalVisibility(!helpModalOpen)); - }} - > - - + {algolia.enabled && ( + { + dispatch(setHelpModalVisibility(!helpModalOpen)); + }} + > + + + )} ); } diff --git a/app/client/src/configs/auto.config.ts b/app/client/src/configs/auto.config.ts deleted file mode 100644 index a0a273ad770b..000000000000 --- a/app/client/src/configs/auto.config.ts +++ /dev/null @@ -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; diff --git a/app/client/src/configs/dev.config.ts b/app/client/src/configs/dev.config.ts deleted file mode 100644 index 54970f8785db..000000000000 --- a/app/client/src/configs/dev.config.ts +++ /dev/null @@ -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; diff --git a/app/client/src/configs/index.ts b/app/client/src/configs/index.ts index d21106927cba..5da413d6f8ff 100644 --- a/app/client/src/configs/index.ts +++ b/app/client/src/configs/index.ts @@ -1,31 +1,159 @@ -import prodConfig from "./prod.config"; -import stageConfig from "./stage.config"; -import autoConfig from "./stage.config"; -import devConfig from "./dev.config"; -import { AppsmithUIConfigs } from "./types"; +import { AppsmithUIConfigs, FeatureFlagConfig } from "./types"; +type INJECTED_CONFIGS = { + sentry: string; + hotjar: { + 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 { 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 => { + return { + sentry: process.env.REACT_APP_SENTRY_DSN || "", + hotjar: { + id: process.env.REACT_APP_HOTJAR_HJID || "", + sv: process.env.REACT_APP_HOTJAR_HJSV || "", + }, + enableGoogleOAuth: process.env.REACT_APP_OAUTH2_GOOGLE_CLIENT_ID + ? process.env.REACT_APP_OAUTH2_GOOGLE_CLIENT_ID.length > 0 + : false, + enableGithubOAuth: process.env.REACT_APP_OAUTH2_GITHUB_CLIENT_ID + ? process.env.REACT_APP_OAUTH2_GITHUB_CLIENT_ID.length > 0 + : false, + segment: process.env.REACT_APP_SEGMENT_KEY || "", + optimizely: process.env.REACT_APP_OPTIMIZELY_KEY || "", + enableMixpanel: process.env.REACT_APP_SEGMENT_KEY + ? process.env.REACT_APP_SEGMENT_KEY.length > 0 + : 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 BASE_URL = ""; - switch (process.env.REACT_APP_ENVIRONMENT) { - case "PRODUCTION": - return prodConfig(BASE_URL); - case "STAGING": - return stageConfig(BASE_URL); - case "DEVELOPMENT": - return devConfig(BASE_URL); - case "AUTOMATION": - return autoConfig(BASE_URL); - default: - console.log( - "Unknown environment set: ", - process.env.REACT_APP_ENVIRONMENT, - ); - return devConfig(BASE_URL); - } + 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, + }; }; diff --git a/app/client/src/configs/prod.config.ts b/app/client/src/configs/prod.config.ts deleted file mode 100644 index 9612afd7f4f5..000000000000 --- a/app/client/src/configs/prod.config.ts +++ /dev/null @@ -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; diff --git a/app/client/src/configs/stage.config.ts b/app/client/src/configs/stage.config.ts deleted file mode 100644 index 949da30d0373..000000000000 --- a/app/client/src/configs/stage.config.ts +++ /dev/null @@ -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; diff --git a/app/client/src/configs/types.ts b/app/client/src/configs/types.ts index f65316ab0c81..9c7679e9f1cc 100644 --- a/app/client/src/configs/types.ts +++ b/app/client/src/configs/types.ts @@ -12,9 +12,7 @@ export type HotjarConfig = { type Milliseconds = number; -export enum FeatureFlagsEnum { - LightningMenu = "lightningmenu", -} +export enum FeatureFlagsEnum {} export type FeatureFlags = Record; @@ -28,18 +26,35 @@ export type FeatureFlagConfig = { export type AppsmithUIConfigs = { sentry: { enabled: boolean; - config?: SentryConfig; + apiKey: string; }; hotjar: { enabled: boolean; - config?: HotjarConfig; + id: string; + sv: string; }; - featureFlag: FeatureFlagConfig; segment: { enabled: boolean; - key: string; + apiKey: string; }; - apiUrl: string; - baseUrl: string; + algolia: { + 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; }; diff --git a/app/client/src/constants/SocialLogin.tsx b/app/client/src/constants/SocialLogin.tsx index 40e52ff0fa14..dd99a2763db2 100644 --- a/app/client/src/constants/SocialLogin.tsx +++ b/app/client/src/constants/SocialLogin.tsx @@ -1,8 +1,6 @@ import { GoogleOAuthURL, GithubOAuthURL } from "constants/ApiConstants"; import GithubLogo from "assets/images/Github.png"; import GoogleLogo from "assets/images/Google.png"; -import { getAppsmithConfigs } from "configs"; -const { baseUrl } = getAppsmithConfigs(); export type SocialLoginButtonProps = { url: string; name: string; @@ -10,13 +8,13 @@ export type SocialLoginButtonProps = { }; export const GoogleSocialLoginButtonProps: SocialLoginButtonProps = { - url: baseUrl + GoogleOAuthURL, + url: GoogleOAuthURL, name: "Google", logo: GoogleLogo, }; export const GithubSocialLoginButtonProps: SocialLoginButtonProps = { - url: baseUrl + GithubOAuthURL, + url: GithubOAuthURL, name: "Github", logo: GithubLogo, }; diff --git a/app/client/src/constants/ThirdPartyConstants.tsx b/app/client/src/constants/ThirdPartyConstants.tsx index c6c9bac50e2e..9672955d9077 100644 --- a/app/client/src/constants/ThirdPartyConstants.tsx +++ b/app/client/src/constants/ThirdPartyConstants.tsx @@ -1,14 +1 @@ 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"; diff --git a/app/client/src/pages/Editor/APIEditor/ApiHomeScreen.tsx b/app/client/src/pages/Editor/APIEditor/ApiHomeScreen.tsx index 8fba14ee9a9d..018e9a6844d9 100644 --- a/app/client/src/pages/Editor/APIEditor/ApiHomeScreen.tsx +++ b/app/client/src/pages/Editor/APIEditor/ApiHomeScreen.tsx @@ -49,6 +49,8 @@ import { import { getInitialsAndColorCode } from "utils/AppsmithUtils"; import AnalyticsUtil from "utils/AnalyticsUtil"; import { CURL } from "constants/ApiConstants"; +import { getAppsmithConfigs } from "configs"; +const { enableRapidAPI } = getAppsmithConfigs(); const SearchContainer = styled.div` display: flex; @@ -403,13 +405,13 @@ class ApiHomeScreen extends React.Component { providersTotal, providerCategories, } = this.props; - if (providerCategories.length === 0) { + if (providerCategories.length === 0 && enableRapidAPI) { this.props.fetchProviderCategories(); } - if (importedCollections.length === 0) { + if (importedCollections.length === 0 && enableRapidAPI) { this.props.fetchImportedCollections(); } - if (!providersTotal) { + if (!providersTotal && enableRapidAPI) { this.props.clearProviders(); this.props.change("category", DEFAULT_PROVIDER_OPTION); this.props.fetchProvidersWithCategory({ @@ -423,7 +425,8 @@ class ApiHomeScreen extends React.Component { componentDidUpdate(prevProps: Props) { if ( 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.clearProviders(); @@ -498,96 +501,99 @@ class ApiHomeScreen extends React.Component { const ApiHomepageTopSection = ( - - { - if (e.target.value) { - this.setState({ showSearchResults: true }); - } else { - this.setState({ showSearchResults: false }); - } - }, - }} - placeholder="Search" - /> - -
- {showSearchResults && ( -
- { - this.setState({ showSearchResults: false }); - }} - /> - -
-

{"Providers"}

- {apiOrProviderSearchResults.providers.map( - providerSearchResult => ( - -

- history.push( - getProviderTemplatesURL( - applicationId, - pageId, - providerSearchResult.id + - `/?importTo=${destinationPageId}`, - ), - ) - } - > - {providerSearchResult.imageUrl ? ( - img - ) : ( -

- - { - getInitialsAndColorCode( + {enableRapidAPI && ( + + { + if (e.target.value) { + this.setState({ showSearchResults: true }); + } else { + this.setState({ showSearchResults: false }); + } + }, + }} + placeholder="Search" + /> + + )} + {enableRapidAPI && ( +
+ {showSearchResults && ( +
+ { + this.setState({ showSearchResults: false }); + }} + /> + +
+

{"Providers"}

+ {apiOrProviderSearchResults.providers.map( + providerSearchResult => ( + +

+ history.push( + getProviderTemplatesURL( + applicationId, + pageId, + providerSearchResult.id + + `/?importTo=${destinationPageId}`, + ), + ) + } + > + {providerSearchResult.imageUrl ? ( + img + ) : ( +

-
- )} - - {providerSearchResult.name} - {/* |{" "} {providerSearchResult.noOfApis} APIs */} - -

-
- ), - )} -
-
-
- )} -
- + )[1], + padding: 11, + width: 60, + color: "#fff", + borderRadius: 2, + fontSize: 16, + fontWeight: "bold", + textAlign: "center", + }} + > + + { + getInitialsAndColorCode( + providerSearchResult.name, + )[0] + } + +
+ )} + + {providerSearchResult.name} + {/* |{" "} {providerSearchResult.noOfApis} APIs */} + +

+
+ ), + )} +
+
+
+ )} +
+ )}

{"Import API"}

@@ -624,7 +630,6 @@ class ApiHomeScreen extends React.Component {
- {/* Imported APIs section start */} {/*

{"Imported APIs"}

@@ -664,12 +669,14 @@ class ApiHomeScreen extends React.Component { style={{ overflow: showSearchResults ? "hidden" : "auto" }} className="t--apiHomePage" > - {isSwitchingCategory ? ( + {isSwitchingCategory || !enableRapidAPI ? ( <> {ApiHomepageTopSection} - - - + {enableRapidAPI && isSwitchingCategory && ( + + + + )} ) : ( <> diff --git a/app/client/src/pages/UserAuth/CreatePassword.tsx b/app/client/src/pages/UserAuth/CreatePassword.tsx index fc79f6cb5429..576dec1f0fe9 100644 --- a/app/client/src/pages/UserAuth/CreatePassword.tsx +++ b/app/client/src/pages/UserAuth/CreatePassword.tsx @@ -44,9 +44,8 @@ import { CREATE_PASSWORD_INVALID_TOKEN, CREATE_PASSWORD_RESET_SUCCESS, CREATE_PASSWORD_RESET_SUCCESS_LOGIN_LINK, - PRIVACY_POLICY_LINK, - TERMS_AND_CONDITIONS_LINK, } from "constants/messages"; +import { TncPPLinks } from "./SignUp"; const validate = (values: CreatePasswordFormValues) => { const errors: CreatePasswordFormValues = {}; @@ -176,8 +175,7 @@ export const CreatePassword = (props: CreatePasswordProps) => { {CREATE_PASSWORD_LOGIN_LINK_TEXT} - {PRIVACY_POLICY_LINK} - {TERMS_AND_CONDITIONS_LINK} + ); diff --git a/app/client/src/pages/UserAuth/Login.tsx b/app/client/src/pages/UserAuth/Login.tsx index 9cec17d2819c..15744e4b80fa 100644 --- a/app/client/src/pages/UserAuth/Login.tsx +++ b/app/client/src/pages/UserAuth/Login.tsx @@ -7,7 +7,6 @@ import { LOGIN_FORM_EMAIL_FIELD_NAME, LOGIN_FORM_PASSWORD_FIELD_NAME, } from "constants/forms"; -import { getAppsmithConfigs } from "configs"; import { FORGOT_PASSWORD_URL, SIGN_UP_URL } from "constants/routes"; import { LOGIN_SUBMIT_PATH } from "constants/ApiConstants"; import { @@ -25,8 +24,6 @@ import { LOGIN_PAGE_FORGOT_PASSWORD_TEXT, LOGIN_PAGE_SIGN_UP_LINK_TEXT, LOGIN_PAGE_INVALID_CREDS_ERROR, - PRIVACY_POLICY_LINK, - TERMS_AND_CONDITIONS_LINK, LOGIN_PAGE_INVALID_CREDS_FORGOT_PASSWORD_LINK, FORM_VALIDATION_PASSWORD_RULE, } from "constants/messages"; @@ -49,6 +46,9 @@ import { AuthCardBody, } from "./StyledComponents"; import AnalyticsUtil from "utils/AnalyticsUtil"; +import { getAppsmithConfigs } from "configs"; +import { TncPPLinks } from "./SignUp"; +const { enableGithubOAuth, enableGoogleOAuth } = getAppsmithConfigs(); const validate = (values: LoginFormValues) => { const errors: LoginFormValues = {}; @@ -73,6 +73,10 @@ type LoginFormProps = { emailValue: string } & InjectedFormProps< { emailValue: string } >; +const SocialLoginList: string[] = []; +if (enableGithubOAuth) SocialLoginList.push(SocialLoginTypes.GITHUB); +if (enableGoogleOAuth) SocialLoginList.push(SocialLoginTypes.GOOGLE); + export const Login = (props: LoginFormProps) => { const { error, valid } = props; const location = useLocation(); @@ -88,8 +92,6 @@ export const Login = (props: LoginFormProps) => { forgotPasswordURL += `?email=${props.emailValue}`; } - const { baseUrl, apiUrl } = getAppsmithConfigs(); - return ( {showError && ( @@ -110,10 +112,7 @@ export const Login = (props: LoginFormProps) => {
{LOGIN_PAGE_SUBTITLE}
- + { /> - - + {SocialLoginList.length > 0 && } + {LOGIN_PAGE_SIGN_UP_LINK_TEXT} - {PRIVACY_POLICY_LINK} - {TERMS_AND_CONDITIONS_LINK} +
); diff --git a/app/client/src/pages/UserAuth/ResetPassword.tsx b/app/client/src/pages/UserAuth/ResetPassword.tsx index 15ad2704dc0f..fdab56c68f87 100644 --- a/app/client/src/pages/UserAuth/ResetPassword.tsx +++ b/app/client/src/pages/UserAuth/ResetPassword.tsx @@ -17,7 +17,6 @@ import Button from "components/editorComponents/Button"; import FormGroup from "components/editorComponents/form/FormGroup"; import StyledForm from "components/editorComponents/Form"; import { isEmptyString, isStrongPassword } from "utils/formhelpers"; - import { ResetPasswordFormValues, resetPasswordSubmitHandler } from "./helpers"; import { AuthCardHeader, @@ -43,9 +42,8 @@ import { RESET_PASSWORD_INVALID_TOKEN, RESET_PASSWORD_RESET_SUCCESS, RESET_PASSWORD_RESET_SUCCESS_LOGIN_LINK, - PRIVACY_POLICY_LINK, - TERMS_AND_CONDITIONS_LINK, } from "constants/messages"; +import { TncPPLinks } from "./SignUp"; const validate = (values: ResetPasswordFormValues) => { const errors: ResetPasswordFormValues = {}; @@ -183,8 +181,7 @@ export const ResetPassword = (props: ResetPasswordProps) => { - {PRIVACY_POLICY_LINK} - {TERMS_AND_CONDITIONS_LINK} + ); diff --git a/app/client/src/pages/UserAuth/SignUp.tsx b/app/client/src/pages/UserAuth/SignUp.tsx index 59de7537ccee..d7f2378498db 100644 --- a/app/client/src/pages/UserAuth/SignUp.tsx +++ b/app/client/src/pages/UserAuth/SignUp.tsx @@ -43,6 +43,30 @@ import { isEmail, isStrongPassword, isEmptyString } from "utils/formhelpers"; import { signupFormSubmitHandler, SignupFormValues } from "./helpers"; 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 ( + <> + + {PRIVACY_POLICY_LINK} + + + {TERMS_AND_CONDITIONS_LINK} + + + ); +}; + const validate = (values: SignupFormValues) => { const errors: SignupFormValues = {}; if (!values.password || isEmptyString(values.password)) { @@ -128,20 +152,15 @@ export const SignUp = (props: InjectedFormProps) => { /> - - + {SocialLoginList.length > 0 && } + - + + + {SIGNUP_PAGE_LOGIN_LINK_TEXT} - - {PRIVACY_POLICY_LINK} - {TERMS_AND_CONDITIONS_LINK} - ); }; diff --git a/app/client/src/utils/AppsmithUtils.tsx b/app/client/src/utils/AppsmithUtils.tsx index e89e995559ee..0e1199435c56 100644 --- a/app/client/src/utils/AppsmithUtils.tsx +++ b/app/client/src/utils/AppsmithUtils.tsx @@ -30,19 +30,18 @@ export const appInitializer = () => { const appsmithConfigs = getAppsmithConfigs(); FeatureFlag.initialize(appsmithConfigs.featureFlag); - if (appsmithConfigs.sentry.enabled && appsmithConfigs.sentry.config) { - Sentry.init(appsmithConfigs.sentry.config); + if (appsmithConfigs.sentry.enabled) { + Sentry.init({ dsn: appsmithConfigs.sentry.apiKey }); } - if (appsmithConfigs.hotjar.enabled && appsmithConfigs.hotjar.config) { - const { id, sv } = appsmithConfigs.hotjar.config; + if (appsmithConfigs.hotjar.enabled) { + const { id, sv } = appsmithConfigs.hotjar; AnalyticsUtil.initializeHotjar(id, sv); } if (appsmithConfigs.segment.enabled) { - AnalyticsUtil.initializeSegment(appsmithConfigs.segment.key); + AnalyticsUtil.initializeSegment(appsmithConfigs.segment.apiKey); } log.setLevel(getEnvLogLevel(appsmithConfigs.logLevel)); - // setConfigFeatureFlags(appsmithConfigs.featureFlags); const textFont = new FontFaceObserver("DM Sans"); textFont diff --git a/app/client/src/utils/featureFlags.ts b/app/client/src/utils/featureFlags.ts index 6439c8653baa..cbe379a4032f 100644 --- a/app/client/src/utils/featureFlags.ts +++ b/app/client/src/utils/featureFlags.ts @@ -4,29 +4,31 @@ const optimizelySDK = require("@optimizely/optimizely-sdk"); class FeatureFlag { static isInitialized = false; static remote = undefined; - static initialize(featureFlagConfig: FeatureFlagConfig) { - Object.keys(featureFlagConfig.default).forEach((flag: any) => { - // This is required because otherwise it will reset the values - // every time the application is loaded. We need the application to load - // remote values the second time. - if (localStorage.getItem(flag) === null) { - localStorage.setItem( - flag, - featureFlagConfig.default[flag as FeatureFlagsEnum].toString(), - ); - } - }); - - if (featureFlagConfig.remoteConfig) { - FeatureFlag.remote = optimizelySDK.createInstance({ - sdkKey: featureFlagConfig.remoteConfig.optimizely, - datafileOptions: { - autoUpdate: true, - updateInterval: 600000, // 10 minutes in milliseconds - urlTemplate: window.location.origin + "/f/datafiles/%s.json", - }, + static initialize(featureFlagConfig?: FeatureFlagConfig) { + if (featureFlagConfig) { + Object.keys(featureFlagConfig.default).forEach((flag: any) => { + // This is required because otherwise it will reset the values + // every time the application is loaded. We need the application to load + // remote values the second time. + if (localStorage.getItem(flag) === null) { + localStorage.setItem( + flag, + featureFlagConfig.default[flag as FeatureFlagsEnum].toString(), + ); + } }); - (FeatureFlag.remote as any).onReady().then(onInit); + + if (featureFlagConfig.remoteConfig) { + FeatureFlag.remote = optimizelySDK.createInstance({ + sdkKey: featureFlagConfig.remoteConfig.optimizely, + datafileOptions: { + autoUpdate: true, + updateInterval: 600000, // 10 minutes in milliseconds + urlTemplate: window.location.origin + "/f/datafiles/%s.json", + }, + }); + (FeatureFlag.remote as any).onReady().then(onInit); + } } } diff --git a/app/client/src/utils/hooks/localstorage.tsx b/app/client/src/utils/hooks/localstorage.tsx index 5aa04f2d3474..35775ae90547 100644 --- a/app/client/src/utils/hooks/localstorage.tsx +++ b/app/client/src/utils/hooks/localstorage.tsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import { useState } from "react"; export function useLocalStorage(key: string, initialValue: string) { // State to store our value diff --git a/app/client/src/widgets/ChartWidget.tsx b/app/client/src/widgets/ChartWidget.tsx index 09871441c6c7..e6695f4c38c6 100644 --- a/app/client/src/widgets/ChartWidget.tsx +++ b/app/client/src/widgets/ChartWidget.tsx @@ -1,7 +1,6 @@ import React, { lazy, Suspense } from "react"; import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget"; import { WidgetType } from "constants/WidgetConstants"; -// import ChartComponent from "components/designSystems/appsmith/ChartComponent"; import { WidgetPropertyValidationType } from "utils/ValidationFactory"; import { VALIDATION_TYPES } from "constants/WidgetValidation"; import Skeleton from "components/utils/Skeleton"; diff --git a/app/client/src/widgets/MapWidget.tsx b/app/client/src/widgets/MapWidget.tsx index d0ab75f592ae..53e9086a3d3e 100644 --- a/app/client/src/widgets/MapWidget.tsx +++ b/app/client/src/widgets/MapWidget.tsx @@ -6,7 +6,26 @@ import { WidgetPropertyValidationType } from "utils/ValidationFactory"; import { VALIDATION_TYPES } from "constants/WidgetValidation"; import { EventType } from "constants/ActionConstants"; 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 { static getPropertyValidationMap(): WidgetPropertyValidationType { return { @@ -116,26 +135,46 @@ class MapWidget extends BaseWidget { getPageView() { return ( - { - this.disableDrag(false); - }} - /> + <> + {!google.enabled && ( + +

{"Map Widget disabled"}

+

+ {"Map widget requires a Google Maps "} + + API Key + +

+

{"Refer our Docs to configure API Keys"}

+
+ )} + {google.enabled && ( + { + this.disableDrag(false); + }} + /> + )} + ); } diff --git a/app/client/start-https.sh b/app/client/start-https.sh index 01e8ea1dda50..3f150122e004 100755 --- a/app/client/start-https.sh +++ b/app/client/start-https.sh @@ -11,6 +11,12 @@ if ! docker_loc="$(type -p "docker")" || [[ -z $docker_loc ]]; then exit 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 CERT_FILE=./docker/_wildcard.appsmith.com.pem 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 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)" +vars_to_substitute="$(printf '\$%s,' $(grep -o "^APPSMITH_[A-Z0-9_]\+" ../../.env | xargs))" case "${unameOut}" in Linux*) machine=Linux echo " 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 " nginx is listening on port 443 and forwarding to port 3000 visit https://dev.appsmith.com @@ -42,7 +61,8 @@ case "${unameOut}" in echo " 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 " nginx is listening on port 443 and forwarding to port 3000 visit https://dev.appsmith.com