Skip to content

Commit 8b01d78

Browse files
feat: oauth flow updates for third party login options
1 parent 4de487c commit 8b01d78

File tree

12 files changed

+143
-57
lines changed

12 files changed

+143
-57
lines changed

‎client/packages/lowcoder-cli/client.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ declare var LOWCODER_NODE_SERVICE_URL: string;
3434
declare var LOWCODER_SHOW_BRAND: string;
3535
declare var LOWCODER_CUSTOM_LOGO: string;
3636
declare var LOWCODER_CUSTOM_LOGO_SQUARE: string;
37-
declare var LOWCODER_SHOW_CUSTOM_AUTH_WELCOME_TEXT: string;
37+
declare var LOWCODER_CUSTOM_AUTH_WELCOME_TEXT: string;
3838
declare var REACT_APP_ENV: string;
3939
declare var REACT_APP_BUILD_ID: string;
4040
declare var REACT_APP_LOG_LEVEL: string;

‎client/packages/lowcoder-dev-utils/buildVars.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ export const buildVars = [
3636
defaultValue: "",
3737
},
3838
{
39-
name: "LOWCODER_SHOW_CUSTOM_AUTH_WELCOME_TEXT",
40-
defaultValue: "",
39+
name: "LOWCODER_CUSTOM_AUTH_WELCOME_TEXT",
40+
defaultValue: "This is custom welcome message",
4141
},
4242
{
4343
name: "REACT_APP_ENV",

‎client/packages/lowcoder/src/app-env.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ declare var LOWCODER_NODE_SERVICE_URL: string;
3737
declare var LOWCODER_SHOW_BRAND: string;
3838
declare var LOWCODER_CUSTOM_LOGO: string;
3939
declare var LOWCODER_CUSTOM_LOGO_SQUARE: string;
40-
declare var LOWCODER_SHOW_CUSTOM_AUTH_WELCOME_TEXT: string;
40+
declare var LOWCODER_CUSTOM_AUTH_WELCOME_TEXT: string;
4141
declare var REACT_APP_ENV: string;
4242
declare var REACT_APP_BUILD_ID: string;
4343
declare var REACT_APP_LOG_LEVEL: string;

‎client/packages/lowcoder/src/app.tsx

+20-10
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import {
1313
IMPORT_APP_FROM_TEMPLATE_URL,
1414
INVITE_LANDING_URL,
1515
isAuthUnRequired,
16+
ORG_AUTH_LOGIN_URL,
17+
ORG_AUTH_REGISTER_URL,
1618
QUERY_LIBRARY_URL,
1719
SETTING,
1820
TRASH_URL,
@@ -70,10 +72,11 @@ const Wrapper = (props: { children: React.ReactNode }) => (
7072
type AppIndexProps = {
7173
isFetchUserFinished: boolean;
7274
isFetchHomeFinished: boolean;
73-
isFetchingConfig: boolean;
75+
// isFetchingConfig: boolean;
76+
currentOrgId?: string;
7477
orgDev: boolean;
7578
defaultHomePage: string | null | undefined;
76-
fetchConfig: () => void;
79+
fetchConfig: (orgId?: string) => void;
7780
getCurrentUser: () => void;
7881
fetchHome: () => void;
7982
favicon: string;
@@ -83,18 +86,22 @@ type AppIndexProps = {
8386
class AppIndex extends React.Component<AppIndexProps, any> {
8487
componentDidMount() {
8588
this.props.getCurrentUser();
86-
if (!history.location.pathname.startsWith("/invite/")) {
87-
this.props.fetchConfig();
88-
}
89-
if (history.location.pathname === BASE_URL) {
89+
const { pathname } = history.location;
90+
91+
this.props.fetchConfig(this.props.currentOrgId);
92+
93+
if (pathname === BASE_URL) {
9094
this.props.fetchHome();
9195
}
9296
}
9397

94-
componentDidUpdate() {
98+
componentDidUpdate(prevProps: AppIndexProps) {
9599
if (history.location.pathname === BASE_URL) {
96100
this.props.fetchHome();
97101
}
102+
if(prevProps.currentOrgId !== this.props.currentOrgId) {
103+
this.props.fetchConfig(this.props.currentOrgId);
104+
}
98105
}
99106

100107
render() {
@@ -103,7 +110,7 @@ class AppIndex extends React.Component<AppIndexProps, any> {
103110
// make sure all users in this app have checked login info
104111
if (
105112
!this.props.isFetchUserFinished ||
106-
this.props.isFetchingConfig ||
113+
// this.props.isFetchingConfig ||
107114
(pathname === BASE_URL && !this.props.isFetchHomeFinished)
108115
) {
109116
const hideLoadingHeader = isTemplate || isAuthUnRequired(pathname);
@@ -153,6 +160,8 @@ class AppIndex extends React.Component<AppIndexProps, any> {
153160
component={ApplicationHome}
154161
/>
155162
<LazyRoute path={USER_AUTH_URL} component={LazyUserAuthComp} />
163+
<LazyRoute path={ORG_AUTH_LOGIN_URL} component={LazyUserAuthComp} />
164+
<LazyRoute path={ORG_AUTH_REGISTER_URL} component={LazyUserAuthComp} />
156165
<LazyRoute path={INVITE_LANDING_URL} component={LazyInviteLanding} />
157166
<LazyRoute path={`${COMPONENT_DOC_URL}/:name`} component={LazyComponentDoc} />
158167
<LazyRoute path={`/playground/:name/:dsl`} component={LazyComponentPlayground} />
@@ -176,8 +185,9 @@ class AppIndex extends React.Component<AppIndexProps, any> {
176185

177186
const mapStateToProps = (state: AppState) => ({
178187
isFetchUserFinished: isFetchUserFinished(state),
179-
isFetchingConfig: getSystemConfigFetching(state),
188+
// isFetchingConfig: getSystemConfigFetching(state),
180189
orgDev: state.ui.users.user.orgDev,
190+
currentOrgId: state.ui.users.user.currentOrgId,
181191
defaultHomePage: state.ui.application.homeOrg?.commonSettings.defaultHomePage,
182192
isFetchHomeFinished: state.ui.application.loadingStatus.fetchHomeDataFinished,
183193
favicon: getBrandingConfig(state)?.favicon
@@ -190,7 +200,7 @@ const mapDispatchToProps = (dispatch: any) => ({
190200
getCurrentUser: () => {
191201
dispatch(fetchUserAction());
192202
},
193-
fetchConfig: () => dispatch(fetchConfigAction()),
203+
fetchConfig: (orgId?: string) => dispatch(fetchConfigAction(orgId)),
194204
fetchHome: () => dispatch(fetchHomeData({})),
195205
});
196206

‎client/packages/lowcoder/src/constants/authConstants.ts

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import {
33
AUTH_LOGIN_URL,
44
AUTH_REGISTER_URL,
55
OAUTH_REDIRECT,
6+
ORG_AUTH_LOGIN_URL,
7+
ORG_AUTH_REGISTER_URL,
68
} from "constants/routesURL";
79
import { InviteInfo } from "api/inviteApi";
810
import Login, { ThirdPartyBindCard } from "pages/userAuth/login";
@@ -73,6 +75,8 @@ export const AuthRoutes: Array<{ path: string; component: React.ComponentType<an
7375
{ path: AUTH_BIND_URL, component: ThirdPartyBindCard },
7476
{ path: AUTH_REGISTER_URL, component: UserRegister },
7577
{ path: OAUTH_REDIRECT, component: AuthRedirect },
78+
{ path: ORG_AUTH_LOGIN_URL, component: Login },
79+
{ path: ORG_AUTH_REGISTER_URL, component: UserRegister },
7680
];
7781

7882
export type ServerAuthType = "GOOGLE" | "GITHUB" | "FORM";

‎client/packages/lowcoder/src/constants/routesURL.ts

+4
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ export const CAS_AUTH_REDIRECT = `${USER_AUTH_URL}/cas/redirect`;
4141
export const LDAP_AUTH_LOGIN_URL = `${USER_AUTH_URL}/ldap/login`;
4242
export const USER_INFO_COMPLETION = `${USER_AUTH_URL}/completion`;
4343
export const INVITE_LANDING_URL = "/invite/:invitationId";
44+
export const ORG_AUTH_LOGIN_URL = `/org/:orgId/auth/login`;
45+
export const ORG_AUTH_REGISTER_URL = `/org/:orgId/auth/register`;
4446

4547
export const APPLICATION_VIEW_URL = (appId: string, viewMode: AppViewMode) =>
4648
`${ALL_APPLICATIONS_URL}/${appId}/${viewMode}`;
@@ -49,6 +51,8 @@ export const isAuthUnRequired = (pathname: string): boolean => {
4951
return (
5052
pathname.startsWith("/invite/") ||
5153
pathname.startsWith(USER_AUTH_URL) ||
54+
pathname.endsWith('/auth/login') ||
55+
pathname.endsWith('/auth/register') ||
5256
pathname.startsWith(COMPONENT_DOC_URL)
5357
);
5458
};

‎client/packages/lowcoder/src/pages/common/inviteLanding.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ function InviteLanding(props: InviteLandingProp) {
5858
messageInstance.error(errorResp.message);
5959
history.push(BASE_URL);
6060
}).finally(() => {
61-
fetchConfig(orgId);
61+
// fetchConfig(orgId);
6262
});
6363
}, [fetchUserFinished, invitationId, fetchConfig]);
6464
return null;

‎client/packages/lowcoder/src/pages/userAuth/authUtils.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
} from "constants/authConstants";
2424

2525
export const AuthContext = createContext<{
26-
systemConfig: SystemConfig;
26+
systemConfig?: SystemConfig;
2727
inviteInfo?: AuthInviteInfo;
2828
thirdPartyAuthError?: boolean;
2929
}>(undefined as any);

‎client/packages/lowcoder/src/pages/userAuth/formLogin.tsx

+35-17
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
LoginCardTitle,
77
StyledRouteLink,
88
} from "pages/userAuth/authComponents";
9-
import React, { useContext, useState } from "react";
9+
import React, { useContext, useMemo, useState } from "react";
1010
import styled from "styled-components";
1111
import UserApi from "api/userApi";
1212
import { useRedirectUrl } from "util/hooks";
@@ -15,8 +15,8 @@ import { UserConnectionSource } from "@lowcoder-ee/constants/userConstants";
1515
import { trans } from "i18n";
1616
import { AuthContext, useAuthSubmit } from "pages/userAuth/authUtils";
1717
import { ThirdPartyAuth } from "pages/userAuth/thirdParty/thirdPartyAuth";
18-
import { AUTH_REGISTER_URL } from "constants/routesURL";
19-
import { useLocation } from "react-router-dom";
18+
import { AUTH_REGISTER_URL, ORG_AUTH_REGISTER_URL } from "constants/routesURL";
19+
import { useLocation, useParams } from "react-router-dom";
2020
import { Divider } from "antd";
2121

2222
const AccountLoginWrapper = styled(FormWrapperMobile)`
@@ -25,15 +25,26 @@ const AccountLoginWrapper = styled(FormWrapperMobile)`
2525
margin-bottom: 106px;
2626
`;
2727

28-
export default function FormLogin() {
28+
type FormLoginProps = {
29+
organizationId?: string;
30+
}
31+
32+
export default function FormLogin(props: FormLoginProps) {
2933
const [account, setAccount] = useState("");
3034
const [password, setPassword] = useState("");
3135
const redirectUrl = useRedirectUrl();
3236
const { systemConfig, inviteInfo } = useContext(AuthContext);
3337
const invitationId = inviteInfo?.invitationId;
34-
const invitedOrganizationId = inviteInfo?.invitedOrganizationId;
3538
const authId = systemConfig?.form.id;
3639
const location = useLocation();
40+
const orgId = useParams<any>().orgId;
41+
42+
// const organizationId = useMemo(() => {
43+
// if(inviteInfo?.invitedOrganizationId) {
44+
// return inviteInfo?.invitedOrganizationId;
45+
// }
46+
// return orgId;
47+
// }, [ inviteInfo, orgId ])
3748

3849
const { onSubmit, loading } = useAuthSubmit(
3950
() =>
@@ -71,20 +82,27 @@ export default function FormLogin() {
7182
<ConfirmButton loading={loading} disabled={!account || !password} onClick={onSubmit}>
7283
{trans("userAuth.login")}
7384
</ConfirmButton>
74-
75-
<Divider />
76-
<ThirdPartyAuth
77-
invitationId={invitationId}
78-
invitedOrganizationId={invitedOrganizationId}
79-
authGoal="login"
80-
/>
85+
86+
{props.organizationId && (
87+
<>
88+
<Divider />
89+
<ThirdPartyAuth
90+
invitationId={invitationId}
91+
invitedOrganizationId={props.organizationId}
92+
authGoal="login"
93+
/>
94+
</>
95+
)}
8196
</AccountLoginWrapper>
8297
<AuthBottomView>
83-
{systemConfig.form.enableRegister && (
84-
<StyledRouteLink to={{ pathname: AUTH_REGISTER_URL, state: location.state }}>
85-
{trans("userAuth.register")}
86-
</StyledRouteLink>
87-
)}
98+
<StyledRouteLink to={{
99+
pathname: orgId
100+
? ORG_AUTH_REGISTER_URL.replace(':orgId', orgId)
101+
: AUTH_REGISTER_URL,
102+
state: location.state
103+
}}>
104+
{trans("userAuth.register")}
105+
</StyledRouteLink>
88106
</AuthBottomView>
89107
</>
90108
);

‎client/packages/lowcoder/src/pages/userAuth/index.tsx

+26-6
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,39 @@
11
import { AUTH_LOGIN_URL, USER_AUTH_URL } from "constants/routesURL";
2-
import { Redirect, Route, Switch, useLocation } from "react-router-dom";
3-
import React from "react";
4-
import { useSelector } from "react-redux";
2+
import { Redirect, Route, Switch, useLocation, useParams } from "react-router-dom";
3+
import React, { useEffect, useMemo } from "react";
4+
import { useSelector, useDispatch } from "react-redux";
55
import { selectSystemConfig } from "redux/selectors/configSelectors";
66
import { AuthContext } from "pages/userAuth/authUtils";
77
import { AuthRoutes } from "@lowcoder-ee/constants/authConstants";
88
import { AuthLocationState } from "constants/authConstants";
99
import { ProductLoading } from "components/ProductLoading";
10+
import { fetchConfigAction } from "redux/reduxActions/configActions";
11+
import _ from "lodash";
1012

1113
export default function UserAuth() {
14+
const dispatch = useDispatch();
1215
const location = useLocation<AuthLocationState>();
13-
const systemConfig = useSelector(selectSystemConfig);
14-
if (!systemConfig) {
16+
const systemConfig = useSelector(selectSystemConfig, _.isEqual);
17+
const orgId = useParams<any>().orgId;
18+
const inviteInfo = location.state?.inviteInfo;
19+
20+
const organizationId = useMemo(() => {
21+
if(inviteInfo?.invitedOrganizationId) {
22+
return inviteInfo?.invitedOrganizationId;
23+
}
24+
return orgId;
25+
}, [ orgId, inviteInfo ])
26+
27+
useEffect(() => {
28+
if(organizationId) {
29+
dispatch(fetchConfigAction(organizationId));
30+
}
31+
}, [organizationId, dispatch])
32+
33+
if (organizationId && !systemConfig) {
1534
return <ProductLoading hideHeader />;
1635
}
36+
1737
return (
1838
<AuthContext.Provider
1939
value={{
@@ -25,7 +45,7 @@ export default function UserAuth() {
2545
<Switch location={location}>
2646
<Redirect exact from={USER_AUTH_URL} to={AUTH_LOGIN_URL} />
2747
{AuthRoutes.map((route) => (
28-
<Route key={route.path} exact path={route.path} component={route.component} />
48+
<Route key={route.path} path={route.path} component={route.component} />
2949
))}
3050
</Switch>
3151
</AuthContext.Provider>

‎client/packages/lowcoder/src/pages/userAuth/login.tsx

+21-10
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { useLocation } from "react-router-dom";
1+
import { useLocation, useParams } from "react-router-dom";
22
import { AuthSearchParams } from "constants/authConstants";
33
import { CommonTextLabel } from "components/Label";
44
import { trans } from "i18n";
55
import { ThirdPartyAuth } from "pages/userAuth/thirdParty/thirdPartyAuth";
66
import FormLogin from "@lowcoder-ee/pages/userAuth/formLogin";
77
import { AuthContainer } from "pages/userAuth/authComponents";
8-
import React, { useContext } from "react";
8+
import React, { useContext, useMemo } from "react";
99
import { AuthContext, getLoginTitle } from "pages/userAuth/authUtils";
1010
import styled from "styled-components";
1111
import { requiresUnAuth } from "pages/userAuth/authHOC";
@@ -69,8 +69,8 @@ export const ThirdPartyBindCard = () => {
6969
<ThirdPartyAuth
7070
authGoal="bind"
7171
autoJumpSource={
72-
systemConfig.authConfigs.length === 1
73-
? systemConfig.authConfigs[0].sourceType
72+
systemConfig?.authConfigs.length === 1
73+
? systemConfig?.authConfigs[0].sourceType
7474
: undefined
7575
}
7676
labelFormatter={thirdPartyLoginLabel}
@@ -85,7 +85,9 @@ function Login() {
8585
const invitationId = inviteInfo?.invitationId;
8686
const location = useLocation();
8787
const queryParams = new URLSearchParams(location.search);
88-
const loginType = systemConfig.authConfigs.find(
88+
const orgId = useParams<any>().orgId;
89+
90+
const loginType = systemConfig?.authConfigs.find(
8991
(config) => config.sourceType === queryParams.get(AuthSearchParams.loginType)
9092
)?.sourceType;
9193
let autoJumpSource: string | undefined;
@@ -96,6 +98,13 @@ function Login() {
9698
autoJumpSource = systemConfig.authConfigs[0].sourceType;
9799
}
98100

101+
const organizationId = useMemo(() => {
102+
if(inviteInfo?.invitedOrganizationId) {
103+
return inviteInfo?.invitedOrganizationId;
104+
}
105+
return orgId;
106+
}, [ inviteInfo, orgId ])
107+
99108
const thirdPartyLoginView = (
100109
<ThirdAuthWrapper>
101110
{!autoJumpSource && (
@@ -116,16 +125,18 @@ function Login() {
116125
if (loginType) {
117126
loginCardView = thirdPartyLoginView;
118127
// Specify the login type with query param
119-
} else if (systemConfig.form.enableLogin) {
120-
loginCardView = <FormLogin />;
128+
} else if (systemConfig?.form.enableLogin) {
129+
loginCardView = <FormLogin organizationId={organizationId} />;
121130
} else {
122131
loginCardView = thirdPartyLoginView;
123132
}
124133

134+
const loginTitle = organizationId && LOWCODER_CUSTOM_AUTH_WELCOME_TEXT !== ""
135+
? LOWCODER_CUSTOM_AUTH_WELCOME_TEXT
136+
: getLoginTitle(inviteInfo?.createUserName, systemConfig?.branding?.brandName)
137+
125138
return (
126-
<AuthContainer
127-
title={getLoginTitle(inviteInfo?.createUserName, systemConfig.branding?.brandName)}
128-
>
139+
<AuthContainer title={loginTitle} >
129140
{loginCardView}
130141
</AuthContainer>
131142
);

0 commit comments

Comments
 (0)