Skip to content

Commit 1f34215

Browse files
authored
Merge branch 'dev' into main
2 parents 5a77d70 + afae00b commit 1f34215

19 files changed

+520
-141
lines changed
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 12 additions & 0 deletions
Loading

client/packages/lowcoder/src/assets/icons/index.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import GoogleLoginIcon from "./icon-login-google.svg";
22
import GithubLoginIcon from "./icon-login-github.svg";
3+
import OryLoginIcon from "./icon-login-ory.svg";
4+
import KeyCloakLoginIcon from "./icon-login-keycloak.svg";
35
import GeneralLoginIcon from "./icon-login-general.svg";
46
import EmailLoginIcon from "./icon-login-email.svg";
57

@@ -10,4 +12,11 @@ export { ReactComponent as DocIcon } from "./view-doc.svg";
1012
export { ReactComponent as TutorialIcon } from "./tutorial.svg";
1113
export { ReactComponent as ShortcutIcon } from "./icon-help-shortcut.svg";
1214

13-
export { GoogleLoginIcon, GithubLoginIcon, GeneralLoginIcon, EmailLoginIcon };
15+
export {
16+
GoogleLoginIcon,
17+
GithubLoginIcon,
18+
OryLoginIcon,
19+
KeyCloakLoginIcon,
20+
GeneralLoginIcon,
21+
EmailLoginIcon
22+
};

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

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@ import Login, { ThirdPartyBindCard } from "pages/userAuth/login";
1111
import UserRegister from "pages/userAuth/register";
1212
import { AuthRedirect } from "pages/userAuth/thirdParty/authRedirect";
1313
import React from "react";
14-
import { GoogleLoginIcon, GithubLoginIcon, EmailLoginIcon } from "assets/icons";
14+
import {
15+
GoogleLoginIcon,
16+
GithubLoginIcon,
17+
OryLoginIcon,
18+
KeyCloakLoginIcon,
19+
EmailLoginIcon
20+
} from "assets/icons";
1521

1622
export type AuthInviteInfo = InviteInfo & { invitationId: string };
1723
export type AuthLocationState = { inviteInfo?: AuthInviteInfo; thirdPartyAuthError?: boolean };
@@ -79,15 +85,26 @@ export const AuthRoutes: Array<{ path: string; component: React.ComponentType<an
7985
{ path: ORG_AUTH_REGISTER_URL, component: UserRegister },
8086
];
8187

82-
export type ServerAuthType = "GOOGLE" | "GITHUB" | "FORM";
88+
export type ServerAuthType = "GOOGLE" | "GITHUB" | "FORM" | "KEYCLOAK" | "ORY";
8389

8490
export type ServerAuthTypeInfoValueType = { logo: string; isOAuth2?: boolean };
8591
export const ServerAuthTypeInfo: { [key in ServerAuthType]?: ServerAuthTypeInfoValueType } = {
8692
GOOGLE: {
8793
logo: GoogleLoginIcon,
8894
isOAuth2: true,
8995
},
90-
GITHUB: { logo: GithubLoginIcon, isOAuth2: true },
96+
GITHUB: {
97+
logo: GithubLoginIcon,
98+
isOAuth2: true
99+
},
100+
KEYCLOAK: {
101+
logo: KeyCloakLoginIcon,
102+
isOAuth2: true
103+
},
104+
ORY: {
105+
logo: OryLoginIcon,
106+
isOAuth2: true
107+
},
91108
FORM: { logo: EmailLoginIcon },
92109
};
93110

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ export const THEME_SETTING = "/setting/theme";
1313
export const PLUGINS_SETTING = "/setting/plugins";
1414
export const THEME_DETAIL = "/setting/theme/detail";
1515

16-
export const IDSOURCE_SETTING = "/setting/idsource";
17-
export const IDSOURCE_DETAIL = "/setting/idsource/detail";
16+
export const OAUTH_PROVIDER_SETTING = "/setting/oauth-provider";
17+
export const OAUTH_PROVIDER_DETAIL = "/setting/oauth-provider/detail";
1818

1919
export const PERMISSION_SETTING_DETAIL = `${PERMISSION_SETTING}/:groupId`;
2020
export const ORGANIZATION_SETTING_DETAIL = `${ORGANIZATION_SETTING}/:orgId`;

client/packages/lowcoder/src/i18n/locales/en.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,15 +1487,17 @@ export const en = {
14871487
},
14881488
settings: {
14891489
title: "Settings",
1490-
member: "Members",
1490+
userGroups: "User Groups",
14911491
organization: "Workspaces",
14921492
audit: "Audit Logs",
14931493
theme: "Themes",
14941494
plugin: "Plugins",
14951495
advanced: "Advanced",
14961496
lab: "Lab",
14971497
branding: "Branding",
1498-
idSource: "ID Providers",
1498+
oauthProviders: "OAuth Providers",
1499+
appUsage: "App Usage Logs",
1500+
environments: "Environments",
14991501
premium: "Premium",
15001502
},
15011503
memberSettings: {
@@ -2544,7 +2546,7 @@ export const en = {
25442546
table,
25452547
},
25462548
idSource: {
2547-
title: "ID Providers",
2549+
title: "OAuth Providers",
25482550
form: "Email",
25492551
pay: "Premium",
25502552
enable: "Enable",

client/packages/lowcoder/src/i18n/locales/zh.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,15 +1367,17 @@ drawer: {
13671367
},
13681368
settings: {
13691369
title: "设置",
1370-
member: "成员",
1370+
userGroups: "用户组",
13711371
organization: "工作空间",
13721372
audit: "审计日志",
13731373
theme: "主题",
13741374
plugin: "插件",
13751375
advanced: "高级",
13761376
lab: "实验室",
13771377
branding: "品牌",
1378-
idSource: "登录方式",
1378+
oauthProviders: "OAuth 提供商",
1379+
appUsage: "应用程序使用日志",
1380+
environments: "环境",
13791381
premium: "高级版",
13801382
},
13811383
memberSettings: {
@@ -2408,7 +2410,7 @@ componentDocExtra: {
24082410
table,
24092411
},
24102412
idSource: {
2411-
title: "登录方式",
2413+
title: "OAuth 提供商",
24122414
form: "电子邮件",
24132415
pay: "高级",
24142416
enable: "启用",
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
import { useEffect, useMemo, useState } from "react";
2+
import { messageInstance, CustomSelect, CloseEyeIcon } from "lowcoder-design";
3+
import {
4+
CustomModalStyled,
5+
} from "../styled";
6+
import { trans } from "i18n";
7+
import {
8+
FormStyled,
9+
CheckboxStyled,
10+
SpanStyled,
11+
PasswordLabel
12+
} from "./styledComponents";
13+
import { Form, Input, Select, Tooltip } from "antd";
14+
import IdSourceApi, { ConfigItem } from "api/idSourceApi";
15+
import { validateResponse } from "api/apiUtils";
16+
import { authConfig, AuthType, clientIdandSecretConfig, ItemType } from "./idSourceConstants";
17+
import { ServerAuthTypeInfo } from "constants/authConstants";
18+
import { GeneralLoginIcon } from "assets/icons";
19+
import _ from "lodash";
20+
21+
type CreateModalProp = {
22+
modalVisible: boolean;
23+
oauthProvidersList: AuthType[],
24+
closeModal: () => void;
25+
onConfigCreate: () => void;
26+
};
27+
28+
function CreateModal(props: CreateModalProp) {
29+
const {
30+
modalVisible,
31+
oauthProvidersList,
32+
closeModal,
33+
onConfigCreate
34+
} = props;
35+
const [form] = Form.useForm();
36+
const [saveLoading, setSaveLoading] = useState(false);
37+
38+
const handleOk = () => {
39+
form.validateFields().then(values => {
40+
console.log(values)
41+
saveAuthProvider(values)
42+
})
43+
}
44+
function saveAuthProvider(values: ConfigItem) {
45+
setSaveLoading(true);
46+
const config = {
47+
...values,
48+
enableRegister: true,
49+
}
50+
IdSourceApi.saveConfig(config)
51+
.then((resp) => {
52+
if (validateResponse(resp)) {
53+
messageInstance.success(trans("idSource.saveSuccess"));
54+
}
55+
})
56+
.catch((e) => messageInstance.error(e.message))
57+
.finally(() => {
58+
setSaveLoading(false);
59+
onConfigCreate();
60+
});
61+
}
62+
63+
function handleCancel() {
64+
closeModal();
65+
form.resetFields();
66+
}
67+
68+
const authConfigOptions = Object.values(authConfig)
69+
.filter(config => {
70+
return !(oauthProvidersList.indexOf(config.sourceValue) > -1)
71+
})
72+
.map(config => ({
73+
label: config.sourceName,
74+
value: config.sourceValue,
75+
}));
76+
77+
const selectedAuthType = Form.useWatch('authType', form);;
78+
79+
const authConfigForm = useMemo(() => {
80+
if(!authConfig[selectedAuthType]) return clientIdandSecretConfig;
81+
return authConfig[selectedAuthType].form;
82+
}, [selectedAuthType])
83+
84+
return (
85+
<CustomModalStyled
86+
width="500px"
87+
title={"Add OAuth Provider"}
88+
open={modalVisible}
89+
okText={"Save and Enable"}
90+
okButtonProps={{
91+
loading: saveLoading
92+
}}
93+
onOk={handleOk}
94+
onCancel={handleCancel}
95+
destroyOnClose
96+
afterClose={() => form.resetFields()}
97+
>
98+
<FormStyled
99+
form={form}
100+
name="basic"
101+
layout="vertical"
102+
style={{ maxWidth: 440 }}
103+
autoComplete="off"
104+
>
105+
<Form.Item
106+
name="authType"
107+
label="Auth Type"
108+
rules={[{ required: true }]}
109+
>
110+
<CustomSelect
111+
placeholder={trans("idSource.formSelectPlaceholder", {
112+
label: 'Auth Type',
113+
})}
114+
>
115+
{authConfigOptions.map(config => (
116+
<Select.Option key={config.value} value={config.value}>
117+
<SpanStyled disabled={false}>
118+
{
119+
<img
120+
src={ServerAuthTypeInfo[config.value]?.logo || GeneralLoginIcon}
121+
alt={config.value}
122+
/>
123+
}
124+
<span>{config.label}</span>
125+
</SpanStyled>
126+
</Select.Option>
127+
))}
128+
</CustomSelect>
129+
</Form.Item>
130+
{Object.entries(authConfigForm).map(([key, value]) => {
131+
const valueObject = _.isObject(value) ? (value as ItemType) : false;
132+
const required = true;
133+
const label = valueObject ? valueObject.label : value;
134+
const tip = valueObject && valueObject.tip;
135+
const isPassword = valueObject && valueObject.isPassword;
136+
return (
137+
<div key={key}>
138+
<Form.Item
139+
key={key}
140+
name={key}
141+
rules={[
142+
{
143+
required,
144+
message: trans("idSource.formPlaceholder", {
145+
label,
146+
}),
147+
},
148+
]}
149+
label={
150+
isPassword ? (
151+
<PasswordLabel>
152+
<span>{label}:</span>
153+
<CloseEyeIcon />
154+
</PasswordLabel>
155+
) : (
156+
<Tooltip title={tip}>
157+
<span className={tip ? "has-tip" : ""}>{label}</span>:
158+
</Tooltip>
159+
)
160+
}
161+
>
162+
{isPassword ? (
163+
<Input
164+
type={"password"}
165+
placeholder={trans("idSource.encryptedServer")}
166+
autoComplete={"one-time-code"}
167+
/>
168+
) : (
169+
<Input
170+
placeholder={trans("idSource.formPlaceholder", {
171+
label,
172+
})}
173+
/>
174+
)}
175+
</Form.Item>
176+
</div>
177+
);
178+
})}
179+
{/* <Form.Item
180+
name="clientId"
181+
label="Client ID"
182+
rules={[{ required: true }]}
183+
>
184+
<Input
185+
placeholder={trans("idSource.formPlaceholder", {
186+
label: 'Client ID',
187+
})}
188+
autoComplete="off"
189+
/>
190+
</Form.Item>
191+
<Form.Item
192+
name="clientSecret"
193+
label={
194+
<PasswordLabel>
195+
<span>{"Client secret"}:</span>
196+
<CloseEyeIcon />
197+
</PasswordLabel>
198+
}
199+
rules={[{
200+
required: true,
201+
message: trans("idSource.formPlaceholder", {
202+
label: 'Client secret',
203+
})
204+
}]}
205+
>
206+
<Input
207+
type="password"
208+
placeholder={trans("idSource.encryptedServer")}
209+
autoComplete="off"
210+
/>
211+
</Form.Item> */}
212+
</FormStyled>
213+
</CustomModalStyled>
214+
);
215+
}
216+
217+
export default CreateModal;

client/packages/lowcoder/src/pages/setting/idSource/detail/deleteConfig.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { validateResponse } from "api/apiUtils";
66
import IdSourceApi from "api/idSourceApi";
77
import { DangerIcon, CustomModal } from "lowcoder-design";
88
import history from "util/history";
9-
import { IDSOURCE_SETTING } from "constants/routesURL";
9+
import { OAUTH_PROVIDER_SETTING } from "constants/routesURL";
1010
import { messageInstance } from "lowcoder-design";
1111

1212
export const DeleteConfig = (props: { id: string }) => {
@@ -21,7 +21,7 @@ export const DeleteConfig = (props: { id: string }) => {
2121
.then((resp) => {
2222
if (validateResponse(resp)) {
2323
messageInstance.success(trans("idSource.disableSuccess"), 0.8, () =>
24-
history.push(IDSOURCE_SETTING)
24+
history.push(OAUTH_PROVIDER_SETTING)
2525
);
2626
}
2727
})

0 commit comments

Comments
 (0)