feat: Add config to disable the form login (#10153)

* updated login/signup pages to use form login disabled config

* added env var config
This commit is contained in:
Pranav Kanade 2022-01-05 10:26:42 +05:30 committed by GitHub
parent c7e2d5a2bb
commit 7861ce6915
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 92 additions and 59 deletions

View File

@ -42,6 +42,7 @@ server {
sub_filter __APPSMITH_DISABLE_TELEMETRY__ '${APPSMITH_DISABLE_TELEMETRY}'; sub_filter __APPSMITH_DISABLE_TELEMETRY__ '${APPSMITH_DISABLE_TELEMETRY}';
sub_filter __APPSMITH_CLOUD_SERVICES_BASE_URL__ '${APPSMITH_CLOUD_SERVICES_BASE_URL}'; sub_filter __APPSMITH_CLOUD_SERVICES_BASE_URL__ '${APPSMITH_CLOUD_SERVICES_BASE_URL}';
sub_filter __APPSMITH_RECAPTCHA_SITE_KEY__ '${APPSMITH_RECAPTCHA_SITE_KEY}'; sub_filter __APPSMITH_RECAPTCHA_SITE_KEY__ '${APPSMITH_RECAPTCHA_SITE_KEY}';
sub_filter __APPSMITH_FORM_LOGIN_DISABLED__ '${APPSMITH_FORM_LOGIN_DISABLED}';
} }
location /f { location /f {

View File

@ -52,6 +52,7 @@ server {
sub_filter __APPSMITH_DISABLE_TELEMETRY__ '${APPSMITH_DISABLE_TELEMETRY}'; sub_filter __APPSMITH_DISABLE_TELEMETRY__ '${APPSMITH_DISABLE_TELEMETRY}';
sub_filter __APPSMITH_CLOUD_SERVICES_BASE_URL__ '${APPSMITH_CLOUD_SERVICES_BASE_URL}'; sub_filter __APPSMITH_CLOUD_SERVICES_BASE_URL__ '${APPSMITH_CLOUD_SERVICES_BASE_URL}';
sub_filter __APPSMITH_RECAPTCHA_SITE_KEY__ '${APPSMITH_RECAPTCHA_SITE_KEY}'; sub_filter __APPSMITH_RECAPTCHA_SITE_KEY__ '${APPSMITH_RECAPTCHA_SITE_KEY}';
sub_filter __APPSMITH_FORM_LOGIN_DISABLED__ '${APPSMITH_FORM_LOGIN_DISABLED}';
} }
location /f { location /f {

View File

@ -50,6 +50,7 @@ server {
sub_filter __APPSMITH_CLOUD_SERVICES_BASE_URL__ '${APPSMITH_CLOUD_SERVICES_BASE_URL}'; sub_filter __APPSMITH_CLOUD_SERVICES_BASE_URL__ '${APPSMITH_CLOUD_SERVICES_BASE_URL}';
sub_filter __APPSMITH_RECAPTCHA_SITE_KEY__ '${APPSMITH_RECAPTCHA_SITE_KEY}'; sub_filter __APPSMITH_RECAPTCHA_SITE_KEY__ '${APPSMITH_RECAPTCHA_SITE_KEY}';
sub_filter __APPSMITH_DISABLE_INTERCOM__ '${APPSMITH_DISABLE_INTERCOM}'; sub_filter __APPSMITH_DISABLE_INTERCOM__ '${APPSMITH_DISABLE_INTERCOM}';
sub_filter __APPSMITH_FORM_LOGIN_DISABLED__ '${APPSMITH_FORM_LOGIN_DISABLED}';
} }
location /f { location /f {

View File

@ -41,6 +41,7 @@ module.exports = {
}, },
enableGoogleOAuth: parseConfig("__APPSMITH_OAUTH2_GOOGLE_CLIENT_ID__"), enableGoogleOAuth: parseConfig("__APPSMITH_OAUTH2_GOOGLE_CLIENT_ID__"),
enableGithubOAuth: parseConfig("__APPSMITH_OAUTH2_GITHUB_CLIENT_ID__"), enableGithubOAuth: parseConfig("__APPSMITH_OAUTH2_GITHUB_CLIENT_ID__"),
disableLoginForm: parseConfig("__APPSMITH_FORM_LOGIN_DISABLED__"),
enableRapidAPI: parseConfig("__APPSMITH_MARKETPLACE_ENABLED__"), enableRapidAPI: parseConfig("__APPSMITH_MARKETPLACE_ENABLED__"),
segment: { segment: {
apiKey: parseConfig("__APPSMITH_SEGMENT_KEY__"), apiKey: parseConfig("__APPSMITH_SEGMENT_KEY__"),

View File

@ -180,6 +180,7 @@
}, },
enableGoogleOAuth: parseConfig("__APPSMITH_OAUTH2_GOOGLE_CLIENT_ID__"), enableGoogleOAuth: parseConfig("__APPSMITH_OAUTH2_GOOGLE_CLIENT_ID__"),
enableGithubOAuth: parseConfig("__APPSMITH_OAUTH2_GITHUB_CLIENT_ID__"), enableGithubOAuth: parseConfig("__APPSMITH_OAUTH2_GITHUB_CLIENT_ID__"),
disableLoginForm: parseConfig("__APPSMITH_FORM_LOGIN_DISABLED__"),
enableRapidAPI: parseConfig("__APPSMITH_MARKETPLACE_ENABLED__"), enableRapidAPI: parseConfig("__APPSMITH_MARKETPLACE_ENABLED__"),
segment: { segment: {
apiKey: parseConfig("__APPSMITH_SEGMENT_KEY__"), apiKey: parseConfig("__APPSMITH_SEGMENT_KEY__"),

View File

@ -16,6 +16,7 @@ export type INJECTED_CONFIGS = {
}; };
enableGoogleOAuth: boolean; enableGoogleOAuth: boolean;
enableGithubOAuth: boolean; enableGithubOAuth: boolean;
disableLoginForm: boolean;
enableRapidAPI: boolean; enableRapidAPI: boolean;
segment: { segment: {
apiKey: string; apiKey: string;
@ -79,6 +80,7 @@ const getConfigsFromEnvVars = (): INJECTED_CONFIGS => {
enableGithubOAuth: process.env.REACT_APP_OAUTH2_GITHUB_CLIENT_ID enableGithubOAuth: process.env.REACT_APP_OAUTH2_GITHUB_CLIENT_ID
? process.env.REACT_APP_OAUTH2_GITHUB_CLIENT_ID.length > 0 ? process.env.REACT_APP_OAUTH2_GITHUB_CLIENT_ID.length > 0
: false, : false,
disableLoginForm: !!process.env.APPSMITH_FORM_LOGIN_DISABLED,
segment: { segment: {
apiKey: process.env.REACT_APP_SEGMENT_KEY || "", apiKey: process.env.REACT_APP_SEGMENT_KEY || "",
ceKey: process.env.REACT_APP_SEGMENT_CE_KEY || "", ceKey: process.env.REACT_APP_SEGMENT_CE_KEY || "",
@ -258,6 +260,8 @@ export const getAppsmithConfigs = (): AppsmithUIConfigs => {
enableGithubOAuth: enableGithubOAuth:
ENV_CONFIG.enableGithubOAuth || ENV_CONFIG.enableGithubOAuth ||
APPSMITH_FEATURE_CONFIGS.enableGithubOAuth, APPSMITH_FEATURE_CONFIGS.enableGithubOAuth,
disableLoginForm:
ENV_CONFIG.disableLoginForm || APPSMITH_FEATURE_CONFIGS.disableLoginForm,
enableGoogleOAuth: enableGoogleOAuth:
ENV_CONFIG.enableGoogleOAuth || ENV_CONFIG.enableGoogleOAuth ||
APPSMITH_FEATURE_CONFIGS.enableGoogleOAuth, APPSMITH_FEATURE_CONFIGS.enableGoogleOAuth,

View File

@ -55,6 +55,7 @@ export type AppsmithUIConfigs = {
enableRapidAPI: boolean; enableRapidAPI: boolean;
enableGoogleOAuth: boolean; enableGoogleOAuth: boolean;
enableGithubOAuth: boolean; enableGithubOAuth: boolean;
disableLoginForm: boolean;
enableMixpanel: boolean; enableMixpanel: boolean;
enableTNCPP: boolean; enableTNCPP: boolean;

View File

@ -50,7 +50,11 @@ import PerformanceTracker, {
} from "utils/PerformanceTracker"; } from "utils/PerformanceTracker";
import { getIsSafeRedirectURL } from "utils/helpers"; import { getIsSafeRedirectURL } from "utils/helpers";
import { getCurrentUser } from "selectors/usersSelectors"; import { getCurrentUser } from "selectors/usersSelectors";
const { enableGithubOAuth, enableGoogleOAuth } = getAppsmithConfigs(); const {
disableLoginForm,
enableGithubOAuth,
enableGoogleOAuth,
} = getAppsmithConfigs();
const validate = (values: LoginFormValues) => { const validate = (values: LoginFormValues) => {
const errors: LoginFormValues = {}; const errors: LoginFormValues = {};
@ -116,15 +120,17 @@ export function Login(props: LoginFormProps) {
<AuthCardHeader> <AuthCardHeader>
<h1>{createMessage(LOGIN_PAGE_TITLE)}</h1> <h1>{createMessage(LOGIN_PAGE_TITLE)}</h1>
</AuthCardHeader> </AuthCardHeader>
<SignUpLinkSection> {!disableLoginForm && (
{createMessage(NEW_TO_APPSMITH)} <SignUpLinkSection>
<AuthCardNavLink {createMessage(NEW_TO_APPSMITH)}
style={{ marginLeft: props.theme.spaces[3] }} <AuthCardNavLink
to={signupURL} style={{ marginLeft: props.theme.spaces[3] }}
> to={signupURL}
{createMessage(LOGIN_PAGE_SIGN_UP_LINK_TEXT)} >
</AuthCardNavLink> {createMessage(LOGIN_PAGE_SIGN_UP_LINK_TEXT)}
</SignUpLinkSection> </AuthCardNavLink>
</SignUpLinkSection>
)}
{showError && ( {showError && (
<FormMessage <FormMessage
actions={ actions={
@ -151,53 +157,59 @@ export function Login(props: LoginFormProps) {
{SocialLoginList.length > 0 && ( {SocialLoginList.length > 0 && (
<ThirdPartyAuth logins={SocialLoginList} type={"SIGNIN"} /> <ThirdPartyAuth logins={SocialLoginList} type={"SIGNIN"} />
)} )}
<SpacedSubmitForm action={loginURL} method="POST"> {!disableLoginForm && (
<FormGroup <>
intent={error ? "danger" : "none"} <SpacedSubmitForm action={loginURL} method="POST">
label={createMessage(LOGIN_PAGE_EMAIL_INPUT_LABEL)} <FormGroup
> intent={error ? "danger" : "none"}
<FormTextField label={createMessage(LOGIN_PAGE_EMAIL_INPUT_LABEL)}
autoFocus >
name={LOGIN_FORM_EMAIL_FIELD_NAME} <FormTextField
placeholder={createMessage(LOGIN_PAGE_EMAIL_INPUT_PLACEHOLDER)} autoFocus
type="email" name={LOGIN_FORM_EMAIL_FIELD_NAME}
/> placeholder={createMessage(LOGIN_PAGE_EMAIL_INPUT_PLACEHOLDER)}
</FormGroup> type="email"
<FormGroup />
intent={error ? "danger" : "none"} </FormGroup>
label={createMessage(LOGIN_PAGE_PASSWORD_INPUT_LABEL)} <FormGroup
> intent={error ? "danger" : "none"}
<FormTextField label={createMessage(LOGIN_PAGE_PASSWORD_INPUT_LABEL)}
name={LOGIN_FORM_PASSWORD_FIELD_NAME} >
placeholder={createMessage(LOGIN_PAGE_PASSWORD_INPUT_PLACEHOLDER)} <FormTextField
type="password" name={LOGIN_FORM_PASSWORD_FIELD_NAME}
/> placeholder={createMessage(
</FormGroup> LOGIN_PAGE_PASSWORD_INPUT_PLACEHOLDER,
)}
type="password"
/>
</FormGroup>
<FormActions> <FormActions>
<Button <Button
disabled={!isFormValid} disabled={!isFormValid}
fill fill
onClick={() => { onClick={() => {
PerformanceTracker.startTracking( PerformanceTracker.startTracking(
PerformanceTransactionName.LOGIN_CLICK, PerformanceTransactionName.LOGIN_CLICK,
); );
AnalyticsUtil.logEvent("LOGIN_CLICK", { AnalyticsUtil.logEvent("LOGIN_CLICK", {
loginMethod: "EMAIL", loginMethod: "EMAIL",
}); });
}} }}
size={Size.large} size={Size.large}
tag="button" tag="button"
text={createMessage(LOGIN_PAGE_LOGIN_BUTTON_TEXT)} text={createMessage(LOGIN_PAGE_LOGIN_BUTTON_TEXT)}
type="submit" type="submit"
/> />
</FormActions> </FormActions>
</SpacedSubmitForm> </SpacedSubmitForm>
<ForgotPasswordLink> <ForgotPasswordLink>
<Link to={forgotPasswordURL}> <Link to={forgotPasswordURL}>
{createMessage(LOGIN_PAGE_FORGOT_PASSWORD_TEXT)} {createMessage(LOGIN_PAGE_FORGOT_PASSWORD_TEXT)}
</Link> </Link>
</ForgotPasswordLink> </ForgotPasswordLink>
</>
)}
</> </>
); );
} }

View File

@ -1,8 +1,13 @@
import React from "react"; import React, { useEffect } from "react";
import { reduxForm, InjectedFormProps, formValueSelector } from "redux-form"; import { reduxForm, InjectedFormProps, formValueSelector } from "redux-form";
import { AUTH_LOGIN_URL } from "constants/routes"; import { AUTH_LOGIN_URL } from "constants/routes";
import { SIGNUP_FORM_NAME } from "constants/forms"; import { SIGNUP_FORM_NAME } from "constants/forms";
import { RouteComponentProps, useLocation, withRouter } from "react-router-dom"; import {
RouteComponentProps,
useHistory,
useLocation,
withRouter,
} from "react-router-dom";
import { import {
AuthCardHeader, AuthCardHeader,
AuthCardNavLink, AuthCardNavLink,
@ -61,7 +66,7 @@ declare global {
grecaptcha: any; grecaptcha: any;
} }
} }
const { googleRecaptchaSiteKey } = getAppsmithConfigs(); const { disableLoginForm, googleRecaptchaSiteKey } = getAppsmithConfigs();
const validate = (values: SignupFormValues) => { const validate = (values: SignupFormValues) => {
const errors: SignupFormValues = {}; const errors: SignupFormValues = {};
@ -85,6 +90,12 @@ type SignUpFormProps = InjectedFormProps<
RouteComponentProps<{ email: string }> & { theme: Theme; emailValue: string }; RouteComponentProps<{ email: string }> & { theme: Theme; emailValue: string };
export function SignUp(props: SignUpFormProps) { export function SignUp(props: SignUpFormProps) {
const history = useHistory();
useEffect(() => {
if (disableLoginForm) {
history.replace(AUTH_LOGIN_URL);
}
}, []);
const { emailValue: email, error, pristine, submitting, valid } = props; const { emailValue: email, error, pristine, submitting, valid } = props;
const isFormValid = valid && email && !isEmptyString(email); const isFormValid = valid && email && !isEmptyString(email);