From e7b222873d440b414489d44e084574f121dadb41 Mon Sep 17 00:00:00 2001 From: LZS911 <932177767@qq.com> Date: Tue, 18 Feb 2025 16:50:01 +0800 Subject: [PATCH 1/6] =?UTF-8?q?[feature](base/system=E3=80=81login)=20supp?= =?UTF-8?q?ort=20disabling=20local=20login?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/base/src/locale/zh-CN/dmsSystem.ts | 18 +- .../Login/__snapshots__/index.test.tsx.snap | 4 +- packages/base/src/page/Login/index.test.tsx | 70 +++- packages/base/src/page/Login/index.tsx | 32 +- .../LoginConnection/LDAPSetting/index.tsx | 3 + .../__snapshots__/indes.test.tsx.snap | 133 ++++++++ .../LoginBasicSetting/indes.test.tsx | 149 +++++++++ .../LoginBasicSetting/index.tsx | 123 ++++++++ .../Oauth/__snapshots__/index.test.tsx.snap | 64 ++-- .../Oauth/components/ConfigField.tsx | 8 +- .../__snapshots__/ConfigField.test.tsx.snap | 8 +- .../LoginConnection/Oauth/index.test.tsx | 2 +- .../System/LoginConnection/Oauth/index.tsx | 46 +-- .../LoginConnection/Oauth/index.type.ts | 2 +- .../__snapshots__/index.ce.test.tsx.snap | 4 +- .../__snapshots__/index.test.tsx.snap | 298 +++++++++++++++++- .../page/System/LoginConnection/context.ts | 18 ++ .../System/LoginConnection/index.test.tsx | 72 ++++- .../src/page/System/LoginConnection/index.tsx | 23 +- .../base/src/testUtils/mockApi/system/data.ts | 7 + .../src/testUtils/mockApi/system/index.ts | 21 +- packages/base/vite.config.mts | 2 +- .../api/base/service/Configuration/index.d.ts | 9 + .../api/base/service/Configuration/index.ts | 23 ++ .../shared/lib/api/base/service/common.d.ts | 28 ++ 25 files changed, 1054 insertions(+), 113 deletions(-) create mode 100644 packages/base/src/page/System/LoginConnection/LoginBasicSetting/__snapshots__/indes.test.tsx.snap create mode 100644 packages/base/src/page/System/LoginConnection/LoginBasicSetting/indes.test.tsx create mode 100644 packages/base/src/page/System/LoginConnection/LoginBasicSetting/index.tsx create mode 100644 packages/base/src/page/System/LoginConnection/context.ts diff --git a/packages/base/src/locale/zh-CN/dmsSystem.ts b/packages/base/src/locale/zh-CN/dmsSystem.ts index 734ad2c01..cf6227c78 100644 --- a/packages/base/src/locale/zh-CN/dmsSystem.ts +++ b/packages/base/src/locale/zh-CN/dmsSystem.ts @@ -12,7 +12,7 @@ export default { tabPaneTitle: { pushNotification: '消息推送', processConnection: '流程对接', - loginConnection: '登录对接', + loginConnection: '登录配置', globalConfiguration: '全局配置', license: '许可证', personalize: '个性化设置' @@ -133,9 +133,9 @@ export default { userWechatTagNameTips: 'sqle会尝试使用此路径,从第三方平台获取用户信息的响应中解析出用户微信ID', - loginButtonText: '登录按钮文字', - loginButtonTextTips: 'login页面OAuth2.0登录按钮文字', loginButtonTextValidateMessage: '最多输入28个字符', + oauth2ButtonText: 'OAuth2.0 跳转按钮文字', + oauth2ButtonTextTips: 'login页面OAuth2.0登录按钮文字', autoCreateUser: '自动创建并绑定用户', autoCreateUserTips: @@ -151,6 +151,18 @@ export default { '系统自动创建的新用户将使用此密码作为初始登录密码,请妥善保存。此外,为保证账户安全,建议用户首次登录后及时修改密码。如果之前配置过该项,更新时不填写该项代表不更新密钥。' }, + loginBasic: { + passwordLoginDisabled: '是否禁用账密登录', + passwordLoginDisabledTips: '禁止除管理员外的普通用户通过账号和密码登录', + loginButtonText: '登录按钮文字', + loginButtonTextTips: 'login页面登录按钮文字', + enableOAuthFirst: '需先启用OAuth2.0登录', + confirmDisable: '是否确认关闭当前配置?', + confirmEnableWithLDAP: + '基于账密登录的LDAP服务会被同时禁用,确认开启禁用吗?', + confirmEnable: '是否确认开启当前配置?' + }, + dingTalk: { titleTips: '审批信息将根据审核人的手机号发送到相应的钉钉账号', enable: '启用钉钉审批', diff --git a/packages/base/src/page/Login/__snapshots__/index.test.tsx.snap b/packages/base/src/page/Login/__snapshots__/index.test.tsx.snap index 0846ac4db..35b946770 100644 --- a/packages/base/src/page/Login/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/Login/__snapshots__/index.test.tsx.snap @@ -249,7 +249,7 @@ exports[`page/Login-ee render login snap 1`] = ` type="submit" > - 登 录 + Login - Login With Oauth2 + Oauth2 Login diff --git a/packages/base/src/page/Login/index.test.tsx b/packages/base/src/page/Login/index.test.tsx index 08627432a..257e5817e 100644 --- a/packages/base/src/page/Login/index.test.tsx +++ b/packages/base/src/page/Login/index.test.tsx @@ -1,6 +1,6 @@ import { act, cleanup, fireEvent, screen } from '@testing-library/react'; import { useDispatch } from 'react-redux'; -import { useNavigate, useLocation, useSearchParams } from 'react-router-dom'; +import { useNavigate, useSearchParams } from 'react-router-dom'; import MockDate from 'mockdate'; import { superRender } from '../../testUtils/customRender'; import dms from '../../testUtils/mockApi/global'; @@ -12,9 +12,12 @@ import { eventEmitter } from '@actiontech/shared/lib/utils/EventEmitter'; import Login from '.'; import { CompanyNoticeDisplayStatusEnum, - StorageKey + StorageKey, + SystemRole } from '@actiontech/shared/lib/enum'; import { OPEN_CLOUD_BEAVER_URL_PARAM_NAME } from '@actiontech/shared/lib/data/routePaths'; +import system from '../../testUtils/mockApi/system'; +import { mockGetLoginBasicConfigurationData } from '../../testUtils/mockApi/system/data'; jest.mock('react-router-dom', () => { return { @@ -33,6 +36,7 @@ describe('page/Login-ee', () => { const navigateSpy = jest.fn(); const assignMock = jest.fn(); const useSearchParamsSpy: jest.Mock = useSearchParams as jest.Mock; + let requestGetOauth2Tip: jest.SpyInstance; const customRender = (params = {}) => { return superRender(, undefined, { initStore: params }); @@ -44,24 +48,28 @@ describe('page/Login-ee', () => { jest.useFakeTimers(); useSearchParamsSpy.mockReturnValue([new URLSearchParams()]); MockDate.set('2023-12-19 12:00:00'); + requestGetOauth2Tip = system.getLoginTips(); dms.mockAllApi(); }); afterEach(() => { jest.useRealTimers(); + jest.clearAllMocks(); + jest.clearAllTimers(); assignMock.mockClear(); cleanup(); MockDate.reset(); }); it('render login snap', async () => { - const requestGetOauth2Tip = dms.getOauth2Tips(); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3300)); expect(requestGetOauth2Tip).toHaveBeenCalledTimes(1); expect(screen.queryByText('已阅读并同意')).toBeInTheDocument(); expect(screen.queryByText('用户协议')).toBeInTheDocument(); - expect(screen.queryByText('Login With Oauth2')).toBeInTheDocument(); + expect( + screen.queryByText(mockGetLoginBasicConfigurationData.oauth2_login_tip) + ).toBeInTheDocument(); expect(baseElement).toMatchSnapshot(); const otherLoginBtn = getBySelector('.other-login-btn', baseElement); @@ -69,10 +77,13 @@ describe('page/Login-ee', () => { }); it('render login when return no auth', async () => { - const requestGetOauth2Tip = dms.getOauth2Tips(); requestGetOauth2Tip.mockImplementation(() => createSpySuccessResponse({ - data: { enable_oauth2: false, login_tip: 'Login no Oauth2' } + data: { + enable_oauth2: false, + oauth2_login_tip: 'Login no Oauth2', + login_button_text: '' + } }) ); @@ -101,11 +112,21 @@ describe('page/Login-ee', () => { }); describe('render login success when has location search val', () => { + beforeEach(() => { + requestGetOauth2Tip.mockImplementation(() => + createSpySuccessResponse({ + data: { + login_button_text: '登录', + enable_oauth2: true, + oauth2_login_tip: 'Login With Oauth2' + } + }) + ); + }); + it('render with other search val', async () => { - const requestGetOauth2Tip = dms.getOauth2Tips(); const requestLogin = dms.addSession(); const LocalStorageWrapperSet = jest.spyOn(LocalStorageWrapper, 'set'); - useSearchParamsSpy.mockReturnValue([ new URLSearchParams({ target: encodeURIComponent('/index1') @@ -156,10 +177,8 @@ describe('page/Login-ee', () => { }); it('render with other search val', async () => { - const requestGetOauth2Tip = dms.getOauth2Tips(); const requestLogin = dms.addSession(); const LocalStorageWrapperSet = jest.spyOn(LocalStorageWrapper, 'set'); - useSearchParamsSpy.mockReturnValue([ new URLSearchParams({ target: encodeURIComponent('/project/700300/cloud-beaver') @@ -212,10 +231,8 @@ describe('page/Login-ee', () => { }); it('render search value with search params', async () => { - const requestGetOauth2Tip = dms.getOauth2Tips(); const requestLogin = dms.addSession(); const LocalStorageWrapperSet = jest.spyOn(LocalStorageWrapper, 'set'); - useSearchParamsSpy.mockReturnValue([ new URLSearchParams({ target: encodeURIComponent('/transit?from=cloudbeaver') @@ -259,13 +276,38 @@ describe('page/Login-ee', () => { }); }); + it('should enable login button when user is admin regardless of disable_user_pwd_login setting', async () => { + requestGetOauth2Tip.mockImplementation(() => + createSpySuccessResponse({ + data: { + login_button_text: '登录', + enable_oauth2: true, + oauth2_login_tip: 'Login With Oauth2', + disable_user_pwd_login: true + } + }) + ); + + superRender(); + await act(async () => jest.advanceTimersByTime(3000)); + + const usernameInput = getBySelector('#username'); + const loginButton = screen.getByText('登 录').closest('button'); + + expect(loginButton).toBeDisabled(); + + fireEvent.change(usernameInput, { target: { value: SystemRole.admin } }); + await act(async () => jest.advanceTimersByTime(0)); + + expect(loginButton).not.toBeDisabled(); + }); + it('render login snap when current browser is not chrome', async () => { const eventEmitSpy = jest.spyOn(eventEmitter, 'emit'); const userAgentGetter = jest.spyOn(window.navigator, 'userAgent', 'get'); userAgentGetter.mockReturnValue( 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Safari/605.1.15' ); - const requestGetOauth2Tip = dms.getOauth2Tips(); customRender(); await act(async () => jest.advanceTimersByTime(3300)); expect(requestGetOauth2Tip).toHaveBeenCalledTimes(1); @@ -278,7 +320,6 @@ describe('page/Login-ee', () => { userAgentGetter.mockReturnValue( 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.0.0 Safari/537.36' ); - const requestGetOauth2Tip = dms.getOauth2Tips(); customRender(); await act(async () => jest.advanceTimersByTime(3300)); expect(requestGetOauth2Tip).toHaveBeenCalledTimes(1); @@ -291,7 +332,6 @@ describe('page/Login-ee', () => { userAgentGetter.mockReturnValue( 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.0.0 Safari/537.36' ); - const requestGetOauth2Tip = dms.getOauth2Tips(); customRender(); await act(async () => jest.advanceTimersByTime(3300)); expect(requestGetOauth2Tip).toHaveBeenCalledTimes(1); diff --git a/packages/base/src/page/Login/index.tsx b/packages/base/src/page/Login/index.tsx index bff7e3d51..0ffc309a4 100644 --- a/packages/base/src/page/Login/index.tsx +++ b/packages/base/src/page/Login/index.tsx @@ -21,17 +21,23 @@ import useThemeStyleData from '../../hooks/useThemeStyleData'; import { LocalStorageWrapper } from '@actiontech/shared'; import { StorageKey, - CompanyNoticeDisplayStatusEnum + CompanyNoticeDisplayStatusEnum, + SystemRole } from '@actiontech/shared/lib/enum'; import { OPEN_CLOUD_BEAVER_URL_PARAM_NAME, ROUTE_PATHS } from '@actiontech/shared/lib/data/routePaths'; +import { ConfigurationService } from '@actiontech/shared/lib/api'; +import { useMemo } from 'react'; const Login = () => { const { t } = useTranslation(); const { baseTheme } = useThemeStyleData(); + const [form] = Form.useForm(); + + const username = Form.useWatch('username', form); useBrowserVersionTips(); @@ -96,18 +102,28 @@ const Login = () => { }); }; - const { run: getOauth2Tips, data: oauthConfig } = useRequest( + const { run: getLoginBasicConfig, data: loginBasicConfig } = useRequest( () => { - return OAuth2.GetOauth2Tips().then((res) => res.data?.data ?? {}); + return ConfigurationService.GetLoginTips().then( + (res) => res.data?.data ?? {} + ); }, { manual: true } ); + const disabledLoginButton = useMemo(() => { + if (username === SystemRole.admin) { + return false; + } + + return !!loginBasicConfig?.disable_user_pwd_login; + }, [loginBasicConfig?.disable_user_pwd_login, username]); + // #if [ee] useEffect(() => { - getOauth2Tips(); + getLoginBasicConfig(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // #endif @@ -116,6 +132,7 @@ const Login = () => { {contextHolder}
{ className="login-btn" htmlType="submit" loading={loading} + disabled={disabledLoginButton} > - {t('dmsLogin.login')} + {loginBasicConfig?.login_button_text || t('dmsLogin.login')} - {oauthConfig?.enable_oauth2 ? ( + {loginBasicConfig?.enable_oauth2 ? ( - {oauthConfig?.login_tip} + {loginBasicConfig?.oauth2_login_tip} ) : null}
diff --git a/packages/base/src/page/System/LoginConnection/LDAPSetting/index.tsx b/packages/base/src/page/System/LoginConnection/LDAPSetting/index.tsx index 87e222e87..e4b02d96d 100644 --- a/packages/base/src/page/System/LoginConnection/LDAPSetting/index.tsx +++ b/packages/base/src/page/System/LoginConnection/LDAPSetting/index.tsx @@ -19,9 +19,11 @@ import { PERMISSIONS, PermissionControl } from '@actiontech/shared/lib/features'; +import { useLoginConnectionContext } from '../context'; const LDAPSetting = () => { const { t } = useTranslation(); + const { setLDAPEnabled } = useLoginConnectionContext(); const { form, @@ -44,6 +46,7 @@ const LDAPSetting = () => { { onSuccess(res) { if (res) { + setLDAPEnabled(!!res.enable_ldap); form.setFieldsValue({ enable_ldap: !!res.enable_ldap }); diff --git a/packages/base/src/page/System/LoginConnection/LoginBasicSetting/__snapshots__/indes.test.tsx.snap b/packages/base/src/page/System/LoginConnection/LoginBasicSetting/__snapshots__/indes.test.tsx.snap new file mode 100644 index 000000000..275666b99 --- /dev/null +++ b/packages/base/src/page/System/LoginConnection/LoginBasicSetting/__snapshots__/indes.test.tsx.snap @@ -0,0 +1,133 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`LoginBasicSetting updateLoginConfig should match snapshot 1`] = ` + +
+
+
+
+
+
+
+ 登录按钮文字 +
+
+ login页面登录按钮文字 +
+
+
+
+
+ Login +
+
+ +
+
+
+
+
+
+
+ 是否禁用账密登录 +
+
+ 禁止除管理员外的普通用户通过账号和密码登录 +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+ +`; diff --git a/packages/base/src/page/System/LoginConnection/LoginBasicSetting/indes.test.tsx b/packages/base/src/page/System/LoginConnection/LoginBasicSetting/indes.test.tsx new file mode 100644 index 000000000..76c7ea467 --- /dev/null +++ b/packages/base/src/page/System/LoginConnection/LoginBasicSetting/indes.test.tsx @@ -0,0 +1,149 @@ +import { act, fireEvent, screen } from '@testing-library/react'; +import { superRender } from '@actiontech/shared/lib/testUtil/customRender'; +import LoginBasicSetting from '.'; +import { createSpyFailResponse } from '@actiontech/shared/lib/testUtil/mockApi'; +import system from '../../../../testUtils/mockApi/system'; +import { getBySelector } from '@actiontech/shared/lib/testUtil/customQuery'; +import { useLoginConnectionContext } from '../context'; + +jest.mock('../context', () => ({ + useLoginConnectionContext: jest.fn() +})); + +describe('LoginBasicSetting', () => { + let requestUpdateLoginConfig: jest.SpyInstance; + let requestGetLoginTips: jest.SpyInstance; + const mockUseLoginConnectionContext = ({ + isLDAPEnabled = false, + isOAuthEnabled = false + } = {}) => { + (useLoginConnectionContext as jest.Mock).mockImplementation(() => ({ + isLDAPEnabled, + isOAuthEnabled + })); + }; + + beforeEach(() => { + jest.useFakeTimers(); + requestUpdateLoginConfig = system.updateLoginConfiguration(); + requestGetLoginTips = system.getLoginTips(); + mockUseLoginConnectionContext(); + }); + + afterEach(() => { + jest.useRealTimers(); + jest.clearAllMocks(); + jest.clearAllTimers(); + }); + + describe('updateLoginConfig', () => { + it('should match snapshot', async () => { + const { baseElement } = superRender(); + await act(async () => jest.advanceTimersByTime(3000)); + expect(baseElement).toMatchSnapshot(); + }); + + it('should update login button text and refresh when success', async () => { + const { baseElement } = superRender(); + await act(async () => jest.advanceTimersByTime(3000)); + + expect(requestGetLoginTips).toHaveBeenCalled(); + + const editBtn = getBySelector( + '.config-item-filed-edit-button', + baseElement + ); + fireEvent.click(editBtn); + const inputEle = getBySelector('#editInput', baseElement); + fireEvent.change(inputEle, { + target: { + value: 'new button text' + } + }); + fireEvent.keyDown(inputEle, { + key: 'Enter', + keyCode: 13 + }); + + expect(requestUpdateLoginConfig).toHaveBeenCalledWith({ + login: { + login_button_text: 'new button text' + } + }); + await act(async () => jest.advanceTimersByTime(3000)); + expect(requestGetLoginTips).toHaveBeenCalledTimes(2); + }); + + it('should disable password login when oauth is disabled', async () => { + mockUseLoginConnectionContext({ + isLDAPEnabled: true, + isOAuthEnabled: false + }); + superRender(); + await act(async () => jest.advanceTimersByTime(3000)); + const switchEle = screen.getByTestId( + 'password-disabled-login-switch-disabled-mode' + ); + expect(switchEle).toBeDisabled(); + + fireEvent.mouseOver(switchEle); + + await screen.findByText('需先启用OAuth2.0登录'); + }); + + it('should update password login status and refresh when success', async () => { + mockUseLoginConnectionContext({ + isLDAPEnabled: true, + isOAuthEnabled: true + }); + + superRender(); + await act(async () => jest.advanceTimersByTime(3000)); + const switchEle = screen.getByTestId('password-disabled-login-switch'); + + fireEvent.click(switchEle); + + await screen.findByText( + '基于账密登录的LDAP服务会被同时禁用,确认开启禁用吗?' + ); + + fireEvent.click(screen.getByText('确 认')); + + expect(requestUpdateLoginConfig).toHaveBeenCalledWith({ + login: { + disable_user_pwd_login: true + } + }); + await act(async () => jest.advanceTimersByTime(3000)); + expect(requestGetLoginTips).toHaveBeenCalledTimes(2); + }); + + it('should not refresh when api returns error', async () => { + requestUpdateLoginConfig.mockImplementation(() => + createSpyFailResponse({}) + ); + + const { baseElement } = superRender(); + await act(async () => jest.advanceTimersByTime(3000)); + + const editBtn = getBySelector( + '.config-item-filed-edit-button', + baseElement + ); + fireEvent.click(editBtn); + const inputEle = getBySelector('#editInput', baseElement); + fireEvent.change(inputEle, { + target: { + value: 'new button text' + } + }); + fireEvent.keyDown(inputEle, { + key: 'Enter', + keyCode: 13 + }); + await act(async () => jest.advanceTimersByTime(3000)); + + expect(requestGetLoginTips).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/packages/base/src/page/System/LoginConnection/LoginBasicSetting/index.tsx b/packages/base/src/page/System/LoginConnection/LoginBasicSetting/index.tsx new file mode 100644 index 000000000..bb98e2417 --- /dev/null +++ b/packages/base/src/page/System/LoginConnection/LoginBasicSetting/index.tsx @@ -0,0 +1,123 @@ +import { Popconfirm, Spin } from 'antd'; +import { useTranslation } from 'react-i18next'; +import { + BasicSwitch, + BasicToolTip, + ConfigItem, + EditInput, + LabelContent +} from '@actiontech/shared'; +import { useState } from 'react'; +import { useLoginConnectionContext } from '../context'; +import { useBoolean, useRequest } from 'ahooks'; +import { ConfigurationService } from '@actiontech/shared/lib/api'; +import { ResponseCode } from '@actiontech/shared/lib/enum'; +import { ILoginConfiguration } from '@actiontech/shared/lib/api/base/service/common'; + +const LoginBasicSetting: React.FC = () => { + const { t } = useTranslation(); + const { isLDAPEnabled, isOAuthEnabled } = useLoginConnectionContext(); + const [isPasswordLoginDisabled, setIsPasswordLoginDisabled] = useState(false); + const [loginButtonText, setLoginButtonText] = useState(); + const [ + isLoginButtonEditing, + { setTrue: startEditing, setFalse: finishEditing } + ] = useBoolean(); + + const updateLoginConfig = async ( + value: string | boolean, + configKey: keyof ILoginConfiguration + ) => { + const res = await ConfigurationService.UpdateLoginConfiguration({ + login: { + [configKey]: value + } + }); + if (res.data.code === ResponseCode.SUCCESS) { + refresh(); + } + }; + + const { loading, refresh } = useRequest(() => + ConfigurationService.GetLoginTips().then((res) => { + if (res.data.code === ResponseCode.SUCCESS) { + setLoginButtonText(res.data.data?.login_button_text); + setIsPasswordLoginDisabled(!!res.data.data?.disable_user_pwd_login); + } + }) + ); + + const renderPasswordLoginSwitch = () => { + if (!isOAuthEnabled) { + return ( + + + + ); + } + + const confirmTitle = isPasswordLoginDisabled + ? t('dmsSystem.loginBasic.confirmDisable') + : isLDAPEnabled + ? t('dmsSystem.loginBasic.confirmEnableWithLDAP') + : t('dmsSystem.loginBasic.confirmEnable'); + + return ( + { + const newValue = !isPasswordLoginDisabled; + setIsPasswordLoginDisabled(newValue); + updateLoginConfig(newValue, 'disable_user_pwd_login'); + }} + > + + + ); + }; + + return ( + + + {t('dmsSystem.loginBasic.loginButtonText')} + + } + descNode={loginButtonText ?? '-'} + fieldVisible={isLoginButtonEditing} + showField={startEditing} + hideField={finishEditing} + inputNode={ + { + updateLoginConfig(value, 'login_button_text'); + }} + /> + } + /> + + {t('dmsSystem.loginBasic.passwordLoginDisabled')} + + } + inputNode={renderPasswordLoginSwitch()} + /> + + ); +}; + +export default LoginBasicSetting; diff --git a/packages/base/src/page/System/LoginConnection/Oauth/__snapshots__/index.test.tsx.snap b/packages/base/src/page/System/LoginConnection/Oauth/__snapshots__/index.test.tsx.snap index bdcd2f981..546b50882 100644 --- a/packages/base/src/page/System/LoginConnection/Oauth/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/System/LoginConnection/Oauth/__snapshots__/index.test.tsx.snap @@ -775,14 +775,14 @@ exports[`base/System/LoginConnection/Oauth render snap 1`] = ` >