Skip to content

Commit 726b77f

Browse files
login/register through third party oauth
1 parent 1800886 commit 726b77f

File tree

16 files changed

+134
-45
lines changed

16 files changed

+134
-45
lines changed

client/packages/lowcoder/src/api/configApi.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@ export interface ConfigResponse extends ApiResponse {
88
}
99

1010
class ConfigApi extends Api {
11-
static configURL = "/v1/configs";
11+
static configURL = "/configs";
1212

13-
static fetchConfig(): AxiosPromise<ConfigResponse> {
14-
return Api.get(ConfigApi.configURL);
13+
static fetchConfig(orgId?: string): AxiosPromise<ConfigResponse> {
14+
let authConfigURL = ConfigApi.configURL;
15+
if(orgId?.length) {
16+
authConfigURL += `?orgId?=${orgId}`;
17+
}
18+
return Api.get(authConfigURL);
1519
}
1620
}
1721

client/packages/lowcoder/src/api/inviteApi.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ export type InviteInfo = {
1414
inviteCode: string;
1515
createUserName: string;
1616
invitedOrganizationName: string;
17+
invitedOrganizationId: string;
1718
};
1819

1920
class InviteApi extends Api {
20-
static getInviteURL = "/v1/invitation";
21+
static getInviteURL = "/invitation";
2122
static acceptInviteURL = (invitationId: string) => `/v1/invitation/${invitationId}/invite`;
2223

2324
// generate invitation

client/packages/lowcoder/src/api/userApi.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export interface CommonLoginParam {
99
invitationId?: string;
1010
authId?: string;
1111
source?: string;
12+
orgId?: string;
1213
}
1314

1415
export interface CommonBindParam {
@@ -17,8 +18,8 @@ export interface CommonBindParam {
1718
source?: string;
1819
}
1920

20-
interface ThirdPartyAuthRequest {
21-
state: string;
21+
export interface ThirdPartyAuthRequest {
22+
state?: string;
2223
code: string;
2324
redirectUrl: string;
2425
}

client/packages/lowcoder/src/app.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ type AppIndexProps = {
8383
class AppIndex extends React.Component<AppIndexProps, any> {
8484
componentDidMount() {
8585
this.props.getCurrentUser();
86-
this.props.fetchConfig();
86+
if (!history.location.pathname.startsWith("/invite/")) {
87+
this.props.fetchConfig();
88+
}
8789
if (history.location.pathname === BASE_URL) {
8890
this.props.fetchHome();
8991
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export type AuthSessionStoreParams = {
5656
afterLoginRedirect: string | null;
5757
sourceType: string;
5858
invitationId?: string;
59+
invitedOrganizationId?: string;
5960
routeLink?: boolean;
6061
name: string;
6162
authId?: string;
@@ -65,7 +66,7 @@ export type AuthSessionStoreParams = {
6566
* action after third party auth
6667
* bind & innerBind has different redirect action
6768
*/
68-
export type ThirdPartyAuthGoal = "login" | "bind" | "innerBind";
69+
export type ThirdPartyAuthGoal = "register" | "login" | "bind" | "innerBind";
6970

7071
export const AuthRoutes: Array<{ path: string; component: React.ComponentType<any> }> = [
7172
{ path: AUTH_LOGIN_URL, component: Login },

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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@ import { RouteComponentProps } from "react-router-dom";
88
import { AppState } from "redux/reducers";
99
import history from "util/history";
1010
import { isFetchUserFinished } from "redux/selectors/usersSelectors";
11+
import { fetchConfigAction } from "redux/reduxActions/configActions";
1112
import { trans } from "i18n";
1213
import { messageInstance } from "lowcoder-design";
1314

1415
type InviteLandingProp = RouteComponentProps<{ invitationId: string }, StaticContext, any> & {
1516
invitationId: string;
17+
fetchConfig: (orgId?: string) => void;
1618
};
1719

1820
function InviteLanding(props: InviteLandingProp) {
19-
const { invitationId } = props;
21+
const { invitationId, fetchConfig } = props;
2022
const fetchUserFinished = useSelector(isFetchUserFinished);
2123
useEffect(() => {
2224
if (!fetchUserFinished) {
@@ -27,6 +29,7 @@ function InviteLanding(props: InviteLandingProp) {
2729
history.push(BASE_URL);
2830
return;
2931
}
32+
let orgId:string | undefined = undefined;
3033
// accept the invitation
3134
InviteApi.acceptInvite({ invitationId })
3235
.then((resp) => {
@@ -39,6 +42,7 @@ function InviteLanding(props: InviteLandingProp) {
3942
resp?.status === API_STATUS_CODES.REQUEST_NOT_AUTHORISED
4043
) {
4144
const inviteInfo = resp.data.data;
45+
orgId = inviteInfo.invitedOrganizationId;
4246
const inviteState = inviteInfo ? { ...inviteInfo, invitationId } : { invitationId };
4347
history.push({
4448
pathname: AUTH_LOGIN_URL,
@@ -53,8 +57,10 @@ function InviteLanding(props: InviteLandingProp) {
5357
.catch((errorResp) => {
5458
messageInstance.error(errorResp.message);
5559
history.push(BASE_URL);
60+
}).finally(() => {
61+
fetchConfig(orgId);
5662
});
57-
}, [fetchUserFinished, invitationId]);
63+
}, [fetchUserFinished, invitationId, fetchConfig]);
5864
return null;
5965
}
6066

@@ -64,4 +70,9 @@ const mapStateToProps = (state: AppState, props: InviteLandingProp) => {
6470
};
6571
};
6672

67-
export default connect(mapStateToProps)(InviteLanding);
73+
const mapDispatchToProps = (dispatch: any) => ({
74+
fetchConfig: (orgId?: string) => dispatch(fetchConfigAction(orgId)),
75+
});
76+
77+
78+
export default connect(mapStateToProps, mapDispatchToProps)(InviteLanding);

client/packages/lowcoder/src/pages/userAuth/authComponents.tsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,23 @@ export const LoginLogoStyle = styled.img`
199199
margin-right: 8px;
200200
width: 32px;
201201
height: 32px;
202+
position: absolute;
203+
left: 6px;
202204
`;
203205

204-
export const StyledLoginButton = styled.button`
205-
padding: 0;
206+
export const LoginLabelStyle = styled.p`
207+
font-size: 16px;
208+
color: #333333;
209+
line-height: 16px;
210+
margin: 0px;
211+
`;
212+
213+
export const StyledLoginButton = styled(TacoButton)`
214+
position: relative;
215+
height: 48px;
216+
border: 1px solid lightgray !important;
217+
border-radius: 8px;
218+
padding: 8px;
206219
white-space: nowrap;
207220
word-break: keep-all;
208221
outline: 0;

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ export const geneAuthStateAndSaveParam = (
125125
authGoal: ThirdPartyAuthGoal,
126126
config: ThirdPartyConfigType,
127127
afterLoginRedirect: string | null,
128-
invitationId?: string
128+
invitationId?: string,
129+
invitedOrganizationId?: string,
129130
) => {
130131
const state = Math.floor(Math.random() * 0xffffffff).toString(16);
131132
const params: AuthSessionStoreParams = {
@@ -135,6 +136,7 @@ export const geneAuthStateAndSaveParam = (
135136
afterLoginRedirect: afterLoginRedirect || null,
136137
sourceType: config.sourceType,
137138
invitationId: invitationId,
139+
invitedOrganizationId: invitedOrganizationId,
138140
routeLink: config.routeLink,
139141
name: config.name,
140142
authId: config.id,

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { AuthContext, useAuthSubmit } from "pages/userAuth/authUtils";
1717
import { ThirdPartyAuth } from "pages/userAuth/thirdParty/thirdPartyAuth";
1818
import { AUTH_REGISTER_URL } from "constants/routesURL";
1919
import { useLocation } from "react-router-dom";
20+
import { Divider } from "antd";
2021

2122
const AccountLoginWrapper = styled(FormWrapperMobile)`
2223
display: flex;
@@ -30,6 +31,7 @@ export default function FormLogin() {
3031
const redirectUrl = useRedirectUrl();
3132
const { systemConfig, inviteInfo } = useContext(AuthContext);
3233
const invitationId = inviteInfo?.invitationId;
34+
const invitedOrganizationId = inviteInfo?.invitedOrganizationId;
3335
const authId = systemConfig?.form.id;
3436
const location = useLocation();
3537

@@ -69,9 +71,18 @@ export default function FormLogin() {
6971
<ConfirmButton loading={loading} disabled={!account || !password} onClick={onSubmit}>
7072
{trans("userAuth.login")}
7173
</ConfirmButton>
74+
{Boolean(invitationId) && (
75+
<>
76+
<Divider />
77+
<ThirdPartyAuth
78+
invitationId={invitationId}
79+
invitedOrganizationId={invitedOrganizationId}
80+
authGoal="login"
81+
/>
82+
</>
83+
)}
7284
</AccountLoginWrapper>
7385
<AuthBottomView>
74-
<ThirdPartyAuth invitationId={invitationId} authGoal="login" />
7586
{systemConfig.form.enableRegister && (
7687
<StyledRouteLink to={{ pathname: AUTH_REGISTER_URL, state: location.state }}>
7788
{trans("userAuth.register")}

client/packages/lowcoder/src/pages/userAuth/register.tsx

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import { useLocation } from "react-router-dom";
1818
import { UserConnectionSource } from "@lowcoder-ee/constants/userConstants";
1919
import { trans } from "i18n";
2020
import { AuthContext, checkPassWithMsg, useAuthSubmit } from "pages/userAuth/authUtils";
21+
import { Divider } from "antd";
22+
import { ThirdPartyAuth } from "pages/userAuth/thirdParty/thirdPartyAuth";
2123

2224
const StyledFormInput = styled(FormInput)`
2325
margin-bottom: 16px;
@@ -30,16 +32,10 @@ const StyledPasswordInput = styled(PasswordInput)`
3032
const RegisterContent = styled(FormWrapperMobile)`
3133
display: flex;
3234
flex-direction: column;
35+
margin-bottom: 106px;
3336
3437
button {
35-
margin: 20px 0 16px 0;
36-
}
37-
`;
38-
39-
const TermsAndPrivacyInfoWrapper = styled.div`
40-
margin-bottom: 80px;
41-
@media screen and (max-width: 640px) {
42-
margin: 10px 0 64px 0;
38+
margin-bottom: 16px;
4339
}
4440
`;
4541

@@ -50,14 +46,16 @@ function UserRegister() {
5046
const redirectUrl = useRedirectUrl();
5147
const location = useLocation();
5248
const { systemConfig, inviteInfo } = useContext(AuthContext);
49+
const invitationId = inviteInfo?.invitationId;
50+
const invitedOrganizationId = inviteInfo?.invitedOrganizationId;
5351
const authId = systemConfig.form.id;
5452
const { loading, onSubmit } = useAuthSubmit(
5553
() =>
5654
UserApi.formLogin({
5755
register: true,
5856
loginId: account,
5957
password: password,
60-
invitationId: inviteInfo?.invitationId,
58+
invitationId,
6159
source: UserConnectionSource.email,
6260
authId,
6361
}),
@@ -95,13 +93,21 @@ function UserRegister() {
9593
>
9694
{trans("userAuth.register")}
9795
</ConfirmButton>
98-
<TermsAndPrivacyInfoWrapper>
99-
<TermsAndPrivacyInfo onCheckChange={(e) => setSubmitBtnDisable(!e.target.checked)} />
100-
</TermsAndPrivacyInfoWrapper>
101-
<StyledRouteLinkLogin to={{ pathname: AUTH_LOGIN_URL, state: location.state }}>
102-
{trans("userAuth.userLogin")}
103-
</StyledRouteLinkLogin>
96+
<TermsAndPrivacyInfo onCheckChange={(e) => setSubmitBtnDisable(!e.target.checked)} />
97+
{Boolean(invitationId) && (
98+
<>
99+
<Divider />
100+
<ThirdPartyAuth
101+
invitationId={invitationId}
102+
invitedOrganizationId={invitedOrganizationId}
103+
authGoal="register"
104+
/>
105+
</>
106+
)}
104107
</RegisterContent>
108+
<StyledRouteLinkLogin to={{ pathname: AUTH_LOGIN_URL, state: location.state }}>
109+
{trans("userAuth.userLogin")}
110+
</StyledRouteLinkLogin>
105111
</AuthContainer>
106112
);
107113
}

client/packages/lowcoder/src/pages/userAuth/thirdParty/authRedirect.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useLocation } from "react-router-dom";
22
import { AuthSessionStoreParams } from "constants/authConstants";
33
import { messageInstance } from "lowcoder-design";
44

5-
import { AUTH_LOGIN_URL, BASE_URL } from "constants/routesURL";
5+
import { AUTH_LOGIN_URL, AUTH_REGISTER_URL, BASE_URL } from "constants/routesURL";
66
import history from "util/history";
77
import PageSkeleton from "components/PageSkeleton";
88
import { trans } from "i18n";
@@ -35,7 +35,13 @@ function validateParam(authParams: AuthSessionStoreParams, urlParam: AuthRedirec
3535
return true;
3636
} else {
3737
messageInstance.error(trans("userAuth.invalidThirdPartyParam"));
38-
history.push(authParams.authGoal === "login" ? AUTH_LOGIN_URL : BASE_URL, {
38+
let redirectUrl = BASE_URL;
39+
if(authParams.authGoal === "login") {
40+
redirectUrl = AUTH_LOGIN_URL;
41+
} else if(authParams.authGoal === "register") {
42+
redirectUrl = AUTH_REGISTER_URL;
43+
}
44+
history.push(redirectUrl, {
3945
thirdPartyAuthError: true,
4046
});
4147
return false;

client/packages/lowcoder/src/pages/userAuth/thirdParty/authenticator/abstractAuthenticator.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ export abstract class AbstractAuthenticator {
2828

2929
doAuth() {
3030
const { authParams } = this;
31-
authParams.authGoal === "login" ? this.doLogin() : this.doBind();
31+
(authParams.authGoal === "login" || authParams.authGoal === "register")
32+
? this.doLogin()
33+
: this.doBind();
3234
}
3335

3436
protected doLogin() {

client/packages/lowcoder/src/pages/userAuth/thirdParty/authenticator/oAuthAuthenticator.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { AbstractAuthenticator } from "./abstractAuthenticator";
22
import { AxiosPromise } from "axios";
3-
import UserApi from "api/userApi";
3+
import UserApi, { CommonLoginParam, ThirdPartyAuthRequest } from "api/userApi";
44
import { ApiResponse } from "api/apiResponses";
55

66
export class OAuthAuthenticator extends AbstractAuthenticator {
@@ -19,13 +19,16 @@ export class OAuthAuthenticator extends AbstractAuthenticator {
1919

2020
login(): AxiosPromise<ApiResponse> {
2121
const { urlParam, authParams, redirectUrl } = this;
22-
return UserApi.thirdPartyLogin({
22+
const params: ThirdPartyAuthRequest & CommonLoginParam = {
2323
state: urlParam.state!,
2424
code: urlParam.code!,
2525
source: authParams.sourceType,
2626
authId: authParams.authId,
2727
redirectUrl: redirectUrl,
28-
...(authParams.invitationId && { invitationId: authParams.invitationId }),
29-
});
28+
}
29+
if(authParams.invitedOrganizationId) {
30+
params.orgId = authParams.invitedOrganizationId;
31+
}
32+
return UserApi.thirdPartyLogin(params);
3033
}
3134
}

0 commit comments

Comments
 (0)