Content-Length: 19258 | pFad | http://github.com/lowcoder-org/lowcoder/pull/1643.patch
thub.com
From 4b58461e23d7d51f1d8c333926297ebe2fb85b84 Mon Sep 17 00:00:00 2001
From: RAHEEL
Date: Thu, 17 Apr 2025 16:10:13 +0500
Subject: [PATCH 1/3] show error message if user not found in login flow
---
client/packages/lowcoder/src/i18n/locales/en.ts | 1 +
.../lowcoder/src/pages/userAuth/formLoginSteps.tsx | 13 +++++++------
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index 735b797d4e..ce47ff7093 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -3205,6 +3205,7 @@ export const en = {
"enterPassword": "Enter your password",
"selectAuthProvider": "Select Authentication Provider",
"selectWorkspace": "Select your workspace",
+ "userNotFound": "User not found. Please make sure you entered the correct email."
},
"preLoad": {
"jsLibraryHelpText": "Add JavaScript Libraries to Your Current Application via URL Addresses. lodash, day.js, uuid, numbro are Built into the System for Immediate Use. JavaScript Libraries are Loaded Before the Application is Initialized, Which Can Have an Impact on Application Performance.",
diff --git a/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx b/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx
index aced446bd9..a04b9b34c9 100644
--- a/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx
+++ b/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx
@@ -177,11 +177,12 @@ export default function FormLoginSteps(props: FormLoginProps) {
setElements({elements: resp.data || [], total: resp.total || 1})
setOrgList(resp.data);
if (!resp.data.length) {
- history.push(
- AUTH_REGISTER_URL,
- {...location.state || {}, email: account},
- )
- return;
+ // history.push(
+ // AUTH_REGISTER_URL,
+ // {...location.state || {}, email: account},
+ // )
+ // return;
+ throw new Error(trans("userAuth.userNotFound"));
}
if (resp.data.length === 1) {
setOrganizationId(resp.data[0].orgId);
@@ -228,7 +229,7 @@ export default function FormLoginSteps(props: FormLoginProps) {
{trans("userAuth.register")}
From a43628bb8cd31c9b67efe3b8ed55017c699c4d09 Mon Sep 17 00:00:00 2001
From: RAHEEL
Date: Fri, 18 Apr 2025 02:11:50 +0500
Subject: [PATCH 2/3] update login flow for enterprise mode
---
.../src/pages/userAuth/formLoginSteps.tsx | 82 +++++++++++++++----
.../lowcoder/src/pages/userAuth/register.tsx | 8 +-
.../userAuth/thirdParty/thirdPartyAuth.tsx | 17 +++-
3 files changed, 85 insertions(+), 22 deletions(-)
diff --git a/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx b/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx
index a04b9b34c9..b04e4b8367 100644
--- a/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx
+++ b/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx
@@ -4,7 +4,7 @@ import {
ConfirmButton,
StyledRouteLink,
} from "pages/userAuth/authComponents";
-import React, { useContext, useEffect, useState } from "react";
+import React, { useContext, useEffect, useMemo, useState } from "react";
import styled from "styled-components";
import UserApi from "api/userApi";
import { useRedirectUrl } from "util/hooks";
@@ -19,7 +19,7 @@ import { Divider } from "antd";
import Flex from "antd/es/flex";
import { validateResponse } from "@lowcoder-ee/api/apiUtils";
import OrgApi from "@lowcoder-ee/api/orgApi";
-import { AccountLoginWrapper } from "./formLoginAdmin";
+import FormLogin, { AccountLoginWrapper } from "./formLoginAdmin";
import { default as Button } from "antd/es/button";
import LeftOutlined from "@ant-design/icons/LeftOutlined";
import { fetchConfigAction } from "@lowcoder-ee/redux/reduxActions/configActions";
@@ -28,6 +28,9 @@ import history from "util/history";
import { getServerSettings } from "@lowcoder-ee/redux/selectors/applicationSelector";
import {fetchOrgPaginationByEmail} from "@lowcoder-ee/util/pagination/axios";
import PaginationComp from "@lowcoder-ee/util/pagination/Pagination";
+import { getSystemConfigFetching } from "@lowcoder-ee/redux/selectors/configSelectors";
+import Spin from "antd/es/spin";
+import LoadingOutlined from "@ant-design/icons/LoadingOutlined";
const StyledCard = styled.div<{$selected: boolean}>`
display: flex;
@@ -107,18 +110,28 @@ export default function FormLoginSteps(props: FormLoginProps) {
const { systemConfig, inviteInfo, fetchUserAfterAuthSuccess } = useContext(AuthContext);
const invitationId = inviteInfo?.invitationId;
const authId = systemConfig?.form.id;
- const isFormLoginEnabled = systemConfig?.form.enableLogin;
+ const isFormLoginEnabled = systemConfig?.form.enableLogin; // check from configs
const [orgLoading, setOrgLoading] = useState(false);
const [orgList, setOrgList] = useState([]);
const [currentStep, setCurrentStep] = useState(CurrentStepEnum.EMAIL);
const [organizationId, setOrganizationId] = useState(props.organizationId);
const [skipWorkspaceStep, setSkipWorkspaceStep] = useState(false);
const [signupEnabled, setSignupEnabled] = useState(true);
+ const [signinEnabled, setSigninEnabled] = useState(true); // check from server settings
const serverSettings = useSelector(getServerSettings);
+ const isFetchingConfig = useSelector(getSystemConfigFetching);
const [elements, setElements] = useState({ elements: [], total: 0 });
const [currentPage, setCurrentPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
+ const isEmailLoginEnabled = useMemo(() => {
+ return isFormLoginEnabled && signinEnabled;
+ }, [isFormLoginEnabled, signinEnabled]);
+
+ const isEnterpriseMode = useMemo(() => {
+ return serverSettings?.LOWCODER_WORKSPACE_MODE === "ENTERPRISE" || serverSettings?.LOWCODER_WORKSPACE_MODE === "SINGLEWORKSPACE";
+ }, [serverSettings]);
+
useEffect(() => {
if (account)
fetchOrgPaginationByEmail({
@@ -133,11 +146,13 @@ export default function FormLoginSteps(props: FormLoginProps) {
}, [pageSize, currentPage])
useEffect(() => {
- const { LOWCODER_EMAIL_SIGNUP_ENABLED } = serverSettings;
- if (!LOWCODER_EMAIL_SIGNUP_ENABLED) {
- return setSignupEnabled(true);
- }
+ const {
+ LOWCODER_EMAIL_SIGNUP_ENABLED,
+ LOWCODER_EMAIL_AUTH_ENABLED,
+ } = serverSettings;
+
setSignupEnabled(LOWCODER_EMAIL_SIGNUP_ENABLED === 'true');
+ setSigninEnabled(LOWCODER_EMAIL_AUTH_ENABLED === 'true');
}, [serverSettings]);
const { onSubmit, loading } = useAuthSubmit(
@@ -167,8 +182,9 @@ export default function FormLoginSteps(props: FormLoginProps) {
}
setOrgLoading(true);
+ // for enterprise mode, we will not ask for email in first step
fetchOrgPaginationByEmail({
- email: account,
+ email: isEnterpriseMode ? ' ' : account,
pageNum: currentPage,
pageSize: pageSize
})
@@ -177,16 +193,13 @@ export default function FormLoginSteps(props: FormLoginProps) {
setElements({elements: resp.data || [], total: resp.total || 1})
setOrgList(resp.data);
if (!resp.data.length) {
- // history.push(
- // AUTH_REGISTER_URL,
- // {...location.state || {}, email: account},
- // )
- // return;
throw new Error(trans("userAuth.userNotFound"));
}
if (resp.data.length === 1) {
- setOrganizationId(resp.data[0].orgId);
- dispatch(fetchConfigAction(resp.data[0].orgId));
+ // in Enterprise mode, we will get org data in different format
+ const selectedOrgId = isEnterpriseMode ? resp.data[0].id : resp.data[0].orgId;
+ setOrganizationId(selectedOrgId);
+ dispatch(fetchConfigAction(selectedOrgId));
setCurrentStep(CurrentStepEnum.AUTH_PROVIDERS);
return;
}
@@ -203,6 +216,39 @@ export default function FormLoginSteps(props: FormLoginProps) {
});
}
+ useEffect(() => {
+ if (isEnterpriseMode) {
+ // dispatch(fetchConfigAction());
+ fetchOrgsByEmail();
+ }
+ }, [isEnterpriseMode]);
+
+ if (isEnterpriseMode) {
+ return (
+ } spinning={isFetchingConfig}>
+ { isEmailLoginEnabled && }
+
+ {signupEnabled && (
+ <>
+
+
+
+ {trans("userAuth.register")}
+
+
+ >
+ )}
+
+ );
+ }
+
if(currentStep === CurrentStepEnum.EMAIL) {
return (
<>
@@ -281,10 +327,10 @@ export default function FormLoginSteps(props: FormLoginProps) {
}} />
- {isFormLoginEnabled && (
+ {isEmailLoginEnabled && (
<>
)}
- {isFormLoginEnabled && signupEnabled && (
+ {isEmailLoginEnabled && signupEnabled && (
<>
diff --git a/client/packages/lowcoder/src/pages/userAuth/register.tsx b/client/packages/lowcoder/src/pages/userAuth/register.tsx
index 62bd7f7c2c..0280947eb2 100644
--- a/client/packages/lowcoder/src/pages/userAuth/register.tsx
+++ b/client/packages/lowcoder/src/pages/userAuth/register.tsx
@@ -63,12 +63,16 @@ function UserRegister() {
return inviteInfo?.invitedOrganizationId;
}
return orgId;
- }, [ inviteInfo, orgId ])
+ }, [ inviteInfo, orgId ]);
const authId = systemConfig?.form.id;
const serverSettings = useSelector(getServerSettings);
+ const isEnterpriseMode = useMemo(() => {
+ return serverSettings?.LOWCODER_WORKSPACE_MODE === "ENTERPRISE" || serverSettings?.LOWCODER_WORKSPACE_MODE === "SINGLEWORKSPACE";
+ }, [serverSettings]);
+
useEffect(() => {
const { LOWCODER_EMAIL_SIGNUP_ENABLED } = serverSettings;
if(
@@ -160,7 +164,7 @@ function UserRegister() {
{trans("userAuth.register")}
setSubmitBtnDisable(!e.target.checked)} />
- {organizationId && (
+ {(organizationId || isEnterpriseMode) && (
{
+ return isFormLoginEnabled && serverSettings.LOWCODER_EMAIL_AUTH_ENABLED === 'true';
+ }, [isFormLoginEnabled, serverSettings]);
+
+ const isEmailSignupEnabled = useMemo(() => {
+ return serverSettings.LOWCODER_EMAIL_SIGNUP_ENABLED === 'true';
+ }, [serverSettings]);
if (systemConfigFetching) {
return } />;
@@ -140,7 +150,10 @@ export function ThirdPartyAuth(props: {
});
return (
- { isFormLoginEnabled && Boolean(socialLoginButtons.length) && (
+ { (
+ (isEmailLoginEnabled && props.authGoal === 'login')
+ || (isEmailSignupEnabled && props.authGoal === 'register')
+ ) && Boolean(socialLoginButtons.length) && (
or
From 79c07b0af58d1b636707c7b496347e4aa34c2790 Mon Sep 17 00:00:00 2001
From: RAHEEL
Date: Sat, 19 Apr 2025 01:22:04 +0500
Subject: [PATCH 3/3] on logout, user should redirect to workspace login page
when login/register using workspace url
---
client/packages/lowcoder/src/api/apiUtils.ts | 9 ++++++++-
.../lowcoder/src/pages/common/profileDropdown.tsx | 8 +++++++-
.../lowcoder/src/pages/userAuth/formLoginSteps.tsx | 11 +++++++++--
.../packages/lowcoder/src/pages/userAuth/register.tsx | 9 ++++++++-
4 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/client/packages/lowcoder/src/api/apiUtils.ts b/client/packages/lowcoder/src/api/apiUtils.ts
index 8396e35014..3b8e4e4344 100644
--- a/client/packages/lowcoder/src/api/apiUtils.ts
+++ b/client/packages/lowcoder/src/api/apiUtils.ts
@@ -122,7 +122,14 @@ export const apiFailureResponseInterceptor = (error: any) => {
if (!notAuthRequiredPath(error.config?.url)) {
if (error.response.status === API_STATUS_CODES.REQUEST_NOT_AUTHORISED) {
// get x-org-id from failed request
- const organizationId = error.response.headers['x-org-id'] || undefined;
+ let organizationId;
+ if (error.response.headers['x-org-id']) {
+ organizationId = error.response.headers['x-org-id'];
+ }
+ if (localStorage.getItem('lowcoder_login_orgId')) {
+ organizationId = localStorage.getItem('lowcoder_login_orgId');
+ localStorage.removeItem('lowcoder_login_orgId');
+ }
// Redirect to login and set a redirect url.
StoreRegistry.getStore().dispatch(
logoutAction({
diff --git a/client/packages/lowcoder/src/pages/common/profileDropdown.tsx b/client/packages/lowcoder/src/pages/common/profileDropdown.tsx
index 992227bd1d..d3f8b2a6d9 100644
--- a/client/packages/lowcoder/src/pages/common/profileDropdown.tsx
+++ b/client/packages/lowcoder/src/pages/common/profileDropdown.tsx
@@ -150,7 +150,13 @@ export default function ProfileDropdown(props: DropDownProps) {
dispatch(profileSettingModalVisible(true));
} else if (e.key === "logout") {
// logout
- dispatch(logoutAction({}));
+ const organizationId = localStorage.getItem('lowcoder_login_orgId');
+ if (organizationId) {
+ localStorage.removeItem('lowcoder_login_orgId');
+ }
+ dispatch(logoutAction({
+ organizationId: organizationId || undefined,
+ }));
} else if (e.keyPath.includes("switchOrg")) {
if (e.key === "newOrganization") {
// create new organization
diff --git a/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx b/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx
index b04e4b8367..1e036f3a32 100644
--- a/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx
+++ b/client/packages/lowcoder/src/pages/userAuth/formLoginSteps.tsx
@@ -155,6 +155,13 @@ export default function FormLoginSteps(props: FormLoginProps) {
setSigninEnabled(LOWCODER_EMAIL_AUTH_ENABLED === 'true');
}, [serverSettings]);
+ const afterLoginSuccess = () => {
+ if (props.organizationId) {
+ localStorage.setItem("lowcoder_login_orgId", props.organizationId);
+ }
+ fetchUserAfterAuthSuccess?.();
+ }
+
const { onSubmit, loading } = useAuthSubmit(
() =>
UserApi.formLogin({
@@ -168,7 +175,7 @@ export default function FormLoginSteps(props: FormLoginProps) {
}),
false,
redirectUrl,
- fetchUserAfterAuthSuccess,
+ afterLoginSuccess,
);
const fetchOrgsByEmail = () => {
@@ -274,7 +281,7 @@ export default function FormLoginSteps(props: FormLoginProps) {
{trans("userAuth.register")}
diff --git a/client/packages/lowcoder/src/pages/userAuth/register.tsx b/client/packages/lowcoder/src/pages/userAuth/register.tsx
index 0280947eb2..41ba0115ef 100644
--- a/client/packages/lowcoder/src/pages/userAuth/register.tsx
+++ b/client/packages/lowcoder/src/pages/userAuth/register.tsx
@@ -86,6 +86,13 @@ function UserRegister() {
};
}, [serverSettings]);
+ const afterLoginSuccess = () => {
+ if (organizationId) {
+ localStorage.setItem("lowcoder_login_orgId", organizationId);
+ }
+ fetchUserAfterAuthSuccess?.();
+ }
+
const { loading, onSubmit } = useAuthSubmit(
() =>
UserApi.formLogin({
@@ -99,7 +106,7 @@ function UserRegister() {
}),
false,
redirectUrl,
- fetchUserAfterAuthSuccess,
+ afterLoginSuccess,
);
const checkEmailExist = () => {
--- a PPN by Garber Painting Akron. With Image Size Reduction included!Fetched URL: http://github.com/lowcoder-org/lowcoder/pull/1643.patch
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy