diff --git a/web/berry/src/config.js b/web/berry/src/config.js
index f38d16fb..14e6ffcb 100644
--- a/web/berry/src/config.js
+++ b/web/berry/src/config.js
@@ -23,11 +23,11 @@ const config = {
version: '',
wechat_login: false,
wechat_qrcode: '',
- oauth2: false,
- oauth2_app_id: '',
- oauth2_authorization_endpoint: '',
- oauth2_token_endpoint: '',
- oauth2_userinfo_endpoint: '',
+ oidc: false,
+ oidc_app_id: '',
+ oidc_authorization_endpoint: '',
+ oidc_token_endpoint: '',
+ oidc_userinfo_endpoint: '',
}
};
diff --git a/web/berry/src/utils/common.js b/web/berry/src/utils/common.js
index a471c2cf..f9c2896c 100644
--- a/web/berry/src/utils/common.js
+++ b/web/berry/src/utils/common.js
@@ -98,12 +98,12 @@ export async function onLarkOAuthClicked(lark_client_id) {
window.open(`https://open.feishu.cn/open-apis/authen/v1/index?redirect_uri=${redirect_uri}&app_id=${lark_client_id}&state=${state}`);
}
-export async function onOAuth2Clicked(auth_url, client_id, openInNewTab = false) {
+export async function onOidcClicked(auth_url, client_id, openInNewTab = false) {
const state = await getOAuthState();
if (!state) return;
const redirect_uri = `${window.location.origin}/oauth/oidc`;
const response_type = "code";
- const scope = "profile email";
+ const scope = "openid profile email";
const url = `${auth_url}?client_id=${client_id}&redirect_uri=${redirect_uri}&response_type=${response_type}&scope=${scope}&state=${state}`;
if (openInNewTab) {
window.open(url);
diff --git a/web/berry/src/views/Authentication/Auth/OidcOAuth.js b/web/berry/src/views/Authentication/Auth/OidcOAuth.js
new file mode 100644
index 00000000..55d9372d
--- /dev/null
+++ b/web/berry/src/views/Authentication/Auth/OidcOAuth.js
@@ -0,0 +1,94 @@
+import { Link, useNavigate, useSearchParams } from 'react-router-dom';
+import React, { useEffect, useState } from 'react';
+import { showError } from 'utils/common';
+import useLogin from 'hooks/useLogin';
+
+// material-ui
+import { useTheme } from '@mui/material/styles';
+import { Grid, Stack, Typography, useMediaQuery, CircularProgress } from '@mui/material';
+
+// project imports
+import AuthWrapper from '../AuthWrapper';
+import AuthCardWrapper from '../AuthCardWrapper';
+import Logo from 'ui-component/Logo';
+
+// assets
+
+// ================================|| AUTH3 - LOGIN ||================================ //
+
+const OidcOAuth = () => {
+ const theme = useTheme();
+ const matchDownSM = useMediaQuery(theme.breakpoints.down('md'));
+
+ const [searchParams] = useSearchParams();
+ const [prompt, setPrompt] = useState('处理中...');
+ const { oidcLogin } = useLogin();
+
+ let navigate = useNavigate();
+
+ const sendCode = async (code, state, count) => {
+ const { success, message } = await oidcLogin(code, state);
+ if (!success) {
+ if (message) {
+ showError(message);
+ }
+ if (count === 0) {
+ setPrompt(`操作失败,重定向至登录界面中...`);
+ await new Promise((resolve) => setTimeout(resolve, 2000));
+ navigate('/login');
+ return;
+ }
+ count++;
+ setPrompt(`出现错误,第 ${count} 次重试中...`);
+ await new Promise((resolve) => setTimeout(resolve, 2000));
+ await sendCode(code, state, count);
+ }
+ };
+
+ useEffect(() => {
+ let code = searchParams.get('code');
+ let state = searchParams.get('state');
+ sendCode(code, state, 0).then();
+ }, []);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ OIDC 登录
+
+
+
+
+
+
+
+
+ {prompt}
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default OidcOAuth;
diff --git a/web/berry/src/views/Authentication/AuthForms/AuthLogin.js b/web/berry/src/views/Authentication/AuthForms/AuthLogin.js
index 582fdfbe..7e4abc1c 100644
--- a/web/berry/src/views/Authentication/AuthForms/AuthLogin.js
+++ b/web/berry/src/views/Authentication/AuthForms/AuthLogin.js
@@ -36,7 +36,8 @@ import VisibilityOff from '@mui/icons-material/VisibilityOff';
import Github from 'assets/images/icons/github.svg';
import Wechat from 'assets/images/icons/wechat.svg';
import Lark from 'assets/images/icons/lark.svg';
-import { onGitHubOAuthClicked, onLarkOAuthClicked, onOAuth2Clicked } from 'utils/common';
+import OIDC from 'assets/images/icons/oidc.svg';
+import { onGitHubOAuthClicked, onLarkOAuthClicked, onOidcClicked } from 'utils/common';
// ============================|| FIREBASE - LOGIN ||============================ //
@@ -50,7 +51,7 @@ const LoginForm = ({ ...others }) => {
// const [checked, setChecked] = useState(true);
let tripartiteLogin = false;
- if (siteInfo.github_oauth || siteInfo.wechat_login || siteInfo.lark_client_id || siteInfo.oauth2) {
+ if (siteInfo.github_oauth || siteInfo.wechat_login || siteInfo.lark_client_id || siteInfo.oidc) {
tripartiteLogin = true;
}
@@ -145,13 +146,13 @@ const LoginForm = ({ ...others }) => {
)}
- {siteInfo.oauth2 && (
+ {siteInfo.oidc && (
diff --git a/web/berry/src/views/Profile/index.js b/web/berry/src/views/Profile/index.js
index 4705d8af..721ead7b 100644
--- a/web/berry/src/views/Profile/index.js
+++ b/web/berry/src/views/Profile/index.js
@@ -20,7 +20,7 @@ import SubCard from 'ui-component/cards/SubCard';
import { IconBrandWechat, IconBrandGithub, IconMail } from '@tabler/icons-react';
import Label from 'ui-component/Label';
import { API } from 'utils/api';
-import { showError, showSuccess } from 'utils/common';
+import { onOidcClicked, showError, showSuccess } from 'utils/common';
import { onGitHubOAuthClicked, onLarkOAuthClicked, copy } from 'utils/common';
import * as Yup from 'yup';
import WechatModal from 'views/Authentication/AuthForms/WechatModal';
@@ -28,6 +28,7 @@ import { useSelector } from 'react-redux';
import EmailModal from './component/EmailModal';
import Turnstile from 'react-turnstile';
import { ReactComponent as Lark } from 'assets/images/icons/lark.svg';
+import { ReactComponent as OIDC } from 'assets/images/icons/oidc.svg';
const validationSchema = Yup.object().shape({
username: Yup.string().required('用户名 不能为空').min(3, '用户名 不能小于 3 个字符'),
@@ -123,6 +124,15 @@ export default function Profile() {
loadUser().then();
}, [status]);
+ function getOidcId(){
+ if (!inputs.oidc_id) return '';
+ let oidc_id = inputs.oidc_id;
+ if (inputs.oidc_id.length > 8) {
+ oidc_id = inputs.oidc_id.slice(0, 6) + '...' + inputs.oidc_id.slice(-6);
+ }
+ return oidc_id;
+ }
+
return (
<>
@@ -141,6 +151,9 @@ export default function Profile() {
+
@@ -216,6 +229,13 @@ export default function Profile() {
)}
+ {status.oidc && !inputs.oidc_id && (
+
+
+
+ )}
}
+ label="允许通过 Oidc 登录 & 注册"
+ control={}
/>
@@ -663,10 +663,10 @@ const SystemSetting = () => {
- 用以支持通过第三方 OAuth2 登录,例如 Okta、Auth0 或自建的兼容 OAuth2.0 协议的 IdP 等
+ 用以支持通过 OIDC 登录,例如 Okta、Auth0 等兼容 OIDC 协议的 IdP
}
>
@@ -679,11 +679,11 @@ const SystemSetting = () => {
- App ID
+ App ID
{
- App Secret
+ App Secret
{
- 授权地址
+ 授权地址
{
- 认证地址
+ 认证地址
{
- 用户地址
+ 用户地址
{
-