From 46e79dde278e41b078f39df38a003a852922222e Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Thu, 4 Jan 2024 16:27:17 +0530 Subject: [PATCH] fix: Login workflow depending on smtp is configured (#3307) --- apiserver/.env.example | 1 - apiserver/plane/app/views/config.py | 15 +- packages/types/src/app.d.ts | 4 +- .../account/sign-in-forms/email-form.tsx | 20 ++- .../account/sign-in-forms/password.tsx | 43 +++--- web/components/account/sign-in-forms/root.tsx | 131 +++++++++--------- .../account/sign-in-forms/unique-code.tsx | 5 +- 7 files changed, 121 insertions(+), 98 deletions(-) diff --git a/apiserver/.env.example b/apiserver/.env.example index 3ac9a3aeb..6558078e2 100644 --- a/apiserver/.env.example +++ b/apiserver/.env.example @@ -39,7 +39,6 @@ OPENAI_API_BASE="https://api.openai.com/v1" # deprecated OPENAI_API_KEY="sk-" # deprecated GPT_ENGINE="gpt-3.5-turbo" # deprecated - # Settings related to Docker DOCKERIZED=1 # deprecated diff --git a/apiserver/plane/app/views/config.py b/apiserver/plane/app/views/config.py index c53b30495..80467c90d 100644 --- a/apiserver/plane/app/views/config.py +++ b/apiserver/plane/app/views/config.py @@ -20,7 +20,6 @@ class ConfigurationEndpoint(BaseAPIView): ] def get(self, request): - # Get all the configuration ( GOOGLE_CLIENT_ID, @@ -90,8 +89,12 @@ class ConfigurationEndpoint(BaseAPIView): data = {} # Authentication - data["google_client_id"] = GOOGLE_CLIENT_ID if GOOGLE_CLIENT_ID and GOOGLE_CLIENT_ID != "\"\"" else None - data["github_client_id"] = GITHUB_CLIENT_ID if GITHUB_CLIENT_ID and GITHUB_CLIENT_ID != "\"\"" else None + data["google_client_id"] = ( + GOOGLE_CLIENT_ID if GOOGLE_CLIENT_ID and GOOGLE_CLIENT_ID != '""' else None + ) + data["github_client_id"] = ( + GITHUB_CLIENT_ID if GITHUB_CLIENT_ID and GITHUB_CLIENT_ID != '""' else None + ) data["github_app_name"] = GITHUB_APP_NAME data["magic_login"] = ( bool(EMAIL_HOST_USER) and bool(EMAIL_HOST_PASSWORD) @@ -114,7 +117,9 @@ class ConfigurationEndpoint(BaseAPIView): # File size settings data["file_size_limit"] = float(os.environ.get("FILE_SIZE_LIMIT", 5242880)) - # is self managed - data["is_self_managed"] = bool(int(os.environ.get("IS_SELF_MANAGED", "1"))) + # is smtp configured + data["is_smtp_configured"] = not ( + bool(EMAIL_HOST_USER) and bool(EMAIL_HOST_PASSWORD) + ) return Response(data, status=status.HTTP_200_OK) diff --git a/packages/types/src/app.d.ts b/packages/types/src/app.d.ts index 4d938ce26..92b304e17 100644 --- a/packages/types/src/app.d.ts +++ b/packages/types/src/app.d.ts @@ -1,5 +1,3 @@ - - export interface IAppConfig { email_password_login: boolean; file_size_limit: number; @@ -12,5 +10,5 @@ export interface IAppConfig { posthog_host: string | null; has_openai_configured: boolean; has_unsplash_configured: boolean; - is_self_managed: boolean; + is_smtp_configured: boolean; } diff --git a/web/components/account/sign-in-forms/email-form.tsx b/web/components/account/sign-in-forms/email-form.tsx index c1e124eab..7642c3b99 100644 --- a/web/components/account/sign-in-forms/email-form.tsx +++ b/web/components/account/sign-in-forms/email-form.tsx @@ -1,10 +1,12 @@ import React, { useEffect } from "react"; import { Controller, useForm } from "react-hook-form"; import { XCircle } from "lucide-react"; +import { observer } from "mobx-react-lite"; // services import { AuthService } from "services/auth.service"; // hooks import useToast from "hooks/use-toast"; +import { useApplication } from "hooks/store"; // ui import { Button, Input } from "@plane/ui"; // helpers @@ -25,11 +27,13 @@ type TEmailFormValues = { const authService = new AuthService(); -export const EmailForm: React.FC = (props) => { +export const EmailForm: React.FC = observer((props) => { const { handleStepChange, updateEmail } = props; - + // hooks const { setToastAlert } = useToast(); - + const { + config: { envConfig }, + } = useApplication(); const { control, formState: { errors, isSubmitting, isValid }, @@ -54,9 +58,11 @@ export const EmailForm: React.FC = (props) => { await authService .emailCheck(payload) .then((res) => { - // if the password has been autoset, send the user to magic sign-in - if (res.is_password_autoset) handleStepChange(ESignInSteps.UNIQUE_CODE); - // if the password has not been autoset, send them to password sign-in + // if the password has been auto set, send the user to magic sign-in + if (res.is_password_autoset && envConfig?.is_smtp_configured) { + handleStepChange(ESignInSteps.UNIQUE_CODE); + } + // if the password has not been auto set, send them to password sign-in else handleStepChange(ESignInSteps.PASSWORD); }) .catch((err) => @@ -119,4 +125,4 @@ export const EmailForm: React.FC = (props) => { ); -}; +}); diff --git a/web/components/account/sign-in-forms/password.tsx b/web/components/account/sign-in-forms/password.tsx index ef9edbfbc..c2eb358f2 100644 --- a/web/components/account/sign-in-forms/password.tsx +++ b/web/components/account/sign-in-forms/password.tsx @@ -6,6 +6,7 @@ import { XCircle } from "lucide-react"; import { AuthService } from "services/auth.service"; // hooks import useToast from "hooks/use-toast"; +import { useApplication } from "hooks/store"; // ui import { Button, Input } from "@plane/ui"; // helpers @@ -14,12 +15,14 @@ import { checkEmailValidity } from "helpers/string.helper"; import { IPasswordSignInData } from "@plane/types"; // constants import { ESignInSteps } from "components/account"; +import { observer } from "mobx-react-lite"; type Props = { email: string; updateEmail: (email: string) => void; handleStepChange: (step: ESignInSteps) => void; handleSignInRedirection: () => Promise; + handleEmailClear: () => void; }; type TPasswordFormValues = { @@ -34,13 +37,16 @@ const defaultValues: TPasswordFormValues = { const authService = new AuthService(); -export const PasswordForm: React.FC = (props) => { - const { email, updateEmail, handleStepChange, handleSignInRedirection } = props; +export const PasswordForm: React.FC = observer((props) => { + const { email, updateEmail, handleStepChange, handleSignInRedirection, handleEmailClear } = props; // states const [isSendingUniqueCode, setIsSendingUniqueCode] = useState(false); const [isSendingResetPasswordLink, setIsSendingResetPasswordLink] = useState(false); // toast alert const { setToastAlert } = useToast(); + const { + config: { envConfig }, + } = useApplication(); // form info const { control, @@ -157,11 +163,12 @@ export const PasswordForm: React.FC = (props) => { hasError={Boolean(errors.email)} placeholder="orville.wright@frstflt.com" className="h-[46px] w-full border border-onboarding-border-100 pr-12 placeholder:text-onboarding-text-400" + disabled /> {value.length > 0 && ( onChange("")} + onClick={handleEmailClear} /> )} @@ -199,26 +206,28 @@ export const PasswordForm: React.FC = (props) => { -
- +
+ {envConfig && envConfig.is_smtp_configured && ( + + )}

@@ -230,4 +239,4 @@ export const PasswordForm: React.FC = (props) => { ); -}; +}); diff --git a/web/components/account/sign-in-forms/root.tsx b/web/components/account/sign-in-forms/root.tsx index 616f4809f..80f46c63e 100644 --- a/web/components/account/sign-in-forms/root.tsx +++ b/web/components/account/sign-in-forms/root.tsx @@ -13,7 +13,6 @@ import { OAuthOptions, OptionalSetPasswordForm, CreatePasswordForm, - SelfHostedSignInForm, } from "components/account"; export enum ESignInSteps { @@ -45,69 +44,73 @@ export const SignInRoot = observer(() => { return ( <>

- {envConfig?.is_self_managed ? ( - setEmail(newEmail)} - handleSignInRedirection={handleRedirection} - /> - ) : ( - <> - {signInStep === ESignInSteps.EMAIL && ( - setSignInStep(step)} - updateEmail={(newEmail) => setEmail(newEmail)} - /> - )} - {signInStep === ESignInSteps.PASSWORD && ( - setEmail(newEmail)} - handleStepChange={(step) => setSignInStep(step)} - handleSignInRedirection={handleRedirection} - /> - )} - {signInStep === ESignInSteps.SET_PASSWORD_LINK && ( - setEmail(newEmail)} /> - )} - {signInStep === ESignInSteps.USE_UNIQUE_CODE_FROM_PASSWORD && ( - setEmail(newEmail)} - handleStepChange={(step) => setSignInStep(step)} - handleSignInRedirection={handleRedirection} - submitButtonLabel="Go to workspace" - showTermsAndConditions - updateUserOnboardingStatus={(value) => setIsOnboarded(value)} - /> - )} - {signInStep === ESignInSteps.UNIQUE_CODE && ( - setEmail(newEmail)} - handleStepChange={(step) => setSignInStep(step)} - handleSignInRedirection={handleRedirection} - updateUserOnboardingStatus={(value) => setIsOnboarded(value)} - /> - )} - {signInStep === ESignInSteps.OPTIONAL_SET_PASSWORD && ( - setSignInStep(step)} - handleSignInRedirection={handleRedirection} - isOnboarded={isOnboarded} - /> - )} - {signInStep === ESignInSteps.CREATE_PASSWORD && ( - setSignInStep(step)} - handleSignInRedirection={handleRedirection} - isOnboarded={isOnboarded} - /> - )} - - )} + <> + {signInStep === ESignInSteps.EMAIL && ( + setSignInStep(step)} + updateEmail={(newEmail) => setEmail(newEmail)} + /> + )} + {signInStep === ESignInSteps.PASSWORD && ( + setEmail(newEmail)} + handleStepChange={(step) => setSignInStep(step)} + handleEmailClear={() => { + setEmail(""); + setSignInStep(ESignInSteps.EMAIL); + }} + handleSignInRedirection={handleRedirection} + /> + )} + {signInStep === ESignInSteps.SET_PASSWORD_LINK && ( + setEmail(newEmail)} /> + )} + {signInStep === ESignInSteps.USE_UNIQUE_CODE_FROM_PASSWORD && ( + setEmail(newEmail)} + handleStepChange={(step) => setSignInStep(step)} + handleSignInRedirection={handleRedirection} + submitButtonLabel="Go to workspace" + showTermsAndConditions + updateUserOnboardingStatus={(value) => setIsOnboarded(value)} + handleEmailClear={() => { + setEmail(""); + setSignInStep(ESignInSteps.EMAIL); + }} + /> + )} + {signInStep === ESignInSteps.UNIQUE_CODE && ( + setEmail(newEmail)} + handleStepChange={(step) => setSignInStep(step)} + handleSignInRedirection={handleRedirection} + updateUserOnboardingStatus={(value) => setIsOnboarded(value)} + handleEmailClear={() => { + setEmail(""); + setSignInStep(ESignInSteps.EMAIL); + }} + /> + )} + {signInStep === ESignInSteps.OPTIONAL_SET_PASSWORD && ( + setSignInStep(step)} + handleSignInRedirection={handleRedirection} + isOnboarded={isOnboarded} + /> + )} + {signInStep === ESignInSteps.CREATE_PASSWORD && ( + setSignInStep(step)} + handleSignInRedirection={handleRedirection} + isOnboarded={isOnboarded} + /> + )} +
{isOAuthEnabled && !OAUTH_HIDDEN_STEPS.includes(signInStep) && ( diff --git a/web/components/account/sign-in-forms/unique-code.tsx b/web/components/account/sign-in-forms/unique-code.tsx index 433fea00a..3ab75831d 100644 --- a/web/components/account/sign-in-forms/unique-code.tsx +++ b/web/components/account/sign-in-forms/unique-code.tsx @@ -25,6 +25,7 @@ type Props = { submitButtonLabel?: string; showTermsAndConditions?: boolean; updateUserOnboardingStatus: (value: boolean) => void; + handleEmailClear: () => void; }; type TUniqueCodeFormValues = { @@ -50,6 +51,7 @@ export const UniqueCodeForm: React.FC = (props) => { submitButtonLabel = "Continue", showTermsAndConditions = false, updateUserOnboardingStatus, + handleEmailClear, } = props; // states const [isRequestingNewCode, setIsRequestingNewCode] = useState(false); @@ -183,11 +185,12 @@ export const UniqueCodeForm: React.FC = (props) => { hasError={Boolean(errors.email)} placeholder="orville.wright@frstflt.com" className="h-[46px] w-full border border-onboarding-border-100 pr-12 placeholder:text-onboarding-text-400" + disabled /> {value.length > 0 && ( onChange("")} + onClick={handleEmailClear} /> )}