feat: Adding an auth page to the user center

This commit is contained in:
haitaoo 2023-04-19 16:31:28 +08:00
parent fd2c5f9946
commit 901f2cb232
12 changed files with 96 additions and 43 deletions

View File

@ -8,6 +8,12 @@ export const CAPTCHA_CODE_STORAGE_KEY = '_a_captcha_';
export const DRAFT_QUESTION_STORAGE_KEY = '_a_dq_';
export const DRAFT_ANSWER_STORAGE_KEY = '_a_da_';
export const DRAFT_TIMESIGH_STORAGE_KEY = '|_a_t_s_|';
export const USER_AGENT_NAMES = {
SegmentFault: 'SegmentFault',
WeChat: 'WeChat',
WeCom: 'WeCom',
DingTalk: 'DingTalk',
};
export const IGNORE_PATH_LIST = [
'/users/login',

View File

@ -1,9 +1,9 @@
const pattern = {
email:
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+\.)+[a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{2,}))$/,
wx: /micromessenger/,
wxwork: /wxwork/,
dingtalk: /dingtalk/,
uaWeChat: /micromessenger/i,
uaWeCom: /wxwork/i,
uaDingTalk: /dingtalk/i,
};
export default pattern;

View File

@ -5,9 +5,10 @@ import { useTranslation } from 'react-i18next';
import QrCode from 'qrcode';
import { userCenterStore } from '@/stores';
import { guard, getUserAgentType } from '@/utils';
import { guard, getUaType, floppyNavigation } from '@/utils';
import { USER_AGENT_NAMES } from '@/common/constants';
import { getLoginConf, checkLoginResult } from './wecom.service';
import { getLoginConf, checkLoginResult } from './service';
let checkTimer: NodeJS.Timeout;
const Index: FC = () => {
@ -47,12 +48,14 @@ const Index: FC = () => {
return;
}
getLoginConf().then((res) => {
if (getUserAgentType() === 'wxwork') {
window.location.replace(res?.redirect_url);
if (getUaType() === USER_AGENT_NAMES.WeCom) {
floppyNavigation.navigate(res?.redirect_url, {
handler: 'replace',
});
} else {
handleQrCode(res?.redirect_url);
handleLoginResult(res?.key);
}
handleLoginResult(res?.key);
});
}, [agentName]);
useEffect(() => {
@ -60,7 +63,7 @@ const Index: FC = () => {
clearTimeout(checkTimer);
};
}, []);
if (/WeCom/i.test(agentName) && getUserAgentType() !== 'wxwork') {
if (getUaType() !== USER_AGENT_NAMES.WeCom) {
return (
<Card className="text-center">
<Card.Body>

View File

@ -0,0 +1,28 @@
import { memo } from 'react';
import { Container, Col } from 'react-bootstrap';
import { useSearchParams } from 'react-router-dom';
import { userCenterStore } from '@/stores';
import { USER_AGENT_NAMES } from '@/common/constants';
import WeComAuth from './components/WeCom';
const Index = () => {
const [searchParam] = useSearchParams();
const { agent: ucAgent } = userCenterStore();
let agentName = ucAgent?.agent_info.name || '';
if (searchParam.get('agent_name')) {
agentName = searchParam.get('agent_name') || '';
}
return (
<Container style={{ paddingTop: '5rem', paddingBottom: '5rem' }}>
<Col md={4} className="mx-auto">
{USER_AGENT_NAMES.WeCom.toLowerCase() === agentName.toLowerCase() ? (
<WeComAuth />
) : null}
</Col>
</Container>
);
};
export default memo(Index);

View File

@ -3,6 +3,7 @@ import { Container } from 'react-bootstrap';
import { useSearchParams } from 'react-router-dom';
import { userCenterStore } from '@/stores';
import { USER_AGENT_NAMES } from '@/common/constants';
import WeCom from './components/WeCom';
@ -13,7 +14,13 @@ const Index = () => {
if (searchParam.get('agent_name')) {
agentName = searchParam.get('agent_name') || '';
}
return <Container>{/^WeCom/i.test(agentName) ? <WeCom /> : null}</Container>;
return (
<Container>
{USER_AGENT_NAMES.WeCom.toLowerCase() === agentName.toLowerCase() ? (
<WeCom />
) : null}
</Container>
);
};
export default memo(Index);

View File

@ -17,7 +17,7 @@ import {
userCenterStore,
} from '@/stores';
import { guard, handleFormError } from '@/utils';
import { login, checkImgCode } from '@/services';
import { login, checkImgCode, UcAgent } from '@/services';
import { PicAuthCodeModal } from '@/components/Modal';
const Index: React.FC = () => {
@ -28,8 +28,12 @@ const Index: React.FC = () => {
const { user: storeUser, update: updateUser } = loggedUserInfoStore((_) => _);
const loginSetting = loginSettingStore((state) => state.login);
const ucAgent = userCenterStore().agent;
const ucLoginRedirect =
ucAgent?.enabled && ucAgent?.agent_info?.login_redirect_url;
let ucAgentInfo: UcAgent['agent_info'] | undefined;
if (ucAgent?.enabled && ucAgent?.agent_info) {
ucAgentInfo = ucAgent.agent_info;
}
const canOriginalLogin =
!ucAgentInfo || ucAgentInfo.enabled_original_user_system;
const [formData, setFormData] = useState<FormDataType>({
e_mail: {
@ -61,7 +65,7 @@ const Index: React.FC = () => {
};
const getImgCode = () => {
if (ucLoginRedirect) {
if (!canOriginalLogin) {
return;
}
checkImgCode({
@ -171,14 +175,13 @@ const Index: React.FC = () => {
return (
<Container style={{ paddingTop: '4rem', paddingBottom: '5rem' }}>
<WelcomeTitle />
{ucLoginRedirect && step === 1 && (
<Col className="mx-auto" md={4}>
<PluginUcLogin />
</Col>
)}
{step === 1 && !ucLoginRedirect && (
{step === 1 && canOriginalLogin ? (
<Col className="mx-auto" md={3}>
<PluginOauth className="mb-5" />
{ucAgentInfo ? (
<PluginUcLogin className="mb-5" />
) : (
<PluginOauth className="mb-5" />
)}
<Form noValidate onSubmit={handleSubmit}>
<Form.Group controlId="email" className="mb-3">
<Form.Label>{t('email.label')}</Form.Label>
@ -250,7 +253,7 @@ const Index: React.FC = () => {
</div>
)}
</Col>
)}
) : null}
{step === 2 && <Unactivate visible={step === 2} />}

View File

@ -2,28 +2,29 @@ import { memo, FC } from 'react';
import { Button } from 'react-bootstrap';
import { useTranslation } from 'react-i18next';
import classnames from 'classnames';
import { SvgIcon } from '@/components';
import { userCenterStore } from '@/stores';
import WeComLogin from './WeCom';
const Index: FC = () => {
interface Props {
className?: classnames.Argument;
}
const Index: FC<Props> = ({ className }) => {
const { t } = useTranslation('translation', { keyPrefix: 'plugins.oauth' });
const ucAgent = userCenterStore().agent;
const agentName = ucAgent?.agent_info?.name || '';
const ucLoginRedirect =
ucAgent?.enabled && ucAgent?.agent_info?.login_redirect_url;
if (/WeCom/i.test(agentName)) {
return <WeComLogin />;
}
if (ucLoginRedirect) {
return (
<Button
className="w-100"
className={classnames('w-100', className)}
variant="outline-secondary"
href={ucAgent?.agent_info.login_redirect_url}>
<SvgIcon base64={ucAgent?.agent_info.icon} />
<span>{t('connect', { auth_name: ucAgent?.agent_info.name })}</span>
<span>{t('connect', { auth_name: agentName })}</span>
</Button>
);
}

View File

@ -240,8 +240,8 @@ const routes: RouteNode[] = [
page: 'pages/Users/OauthBindEmail',
},
{
path: '/users/oauth',
page: 'pages/Users/OauthCallback',
path: '/users/auth-landing',
page: 'pages/Users/AuthCallback',
},
{
path: '/posts/:qid/timeline',
@ -362,6 +362,10 @@ const routes: RouteNode[] = [
},
],
},
{
path: '/user-center/auth',
page: 'pages/UserCenter/Auth',
},
{
path: '/user-center/auth-failed',
page: 'pages/UserCenter/AuthFailed',

View File

@ -14,6 +14,7 @@ export interface UcAgent {
login_redirect_url: string;
sign_up_redirect_url: string;
control_center: UcAgentControl[];
enabled_original_user_system: boolean;
};
}

View File

@ -1,6 +1,7 @@
import i18next from 'i18next';
import pattern from '@/common/pattern';
import { USER_AGENT_NAMES } from '@/common/constants';
const Diff = require('diff');
@ -258,18 +259,17 @@ function base64ToSvg(base64: string) {
// Determine whether the user is in WeChat or Enterprise WeChat or DingTalk, and return the corresponding type
function getUserAgentType() {
function getUaType() {
const ua = navigator.userAgent.toLowerCase();
if (pattern.wxwork.test(ua)) {
return 'wxwork';
if (pattern.uaWeCom.test(ua)) {
return USER_AGENT_NAMES.WeCom;
}
if (pattern.uaWeChat.test(ua)) {
return USER_AGENT_NAMES.WeChat;
}
if (pattern.uaDingTalk.test(ua)) {
return USER_AGENT_NAMES.DingTalk;
}
// if (pattern.wx.test(ua)) {
// return 'weixin';
// }
// if (pattern.dingtalk.test(ua)) {
// return 'dingtalk';
// }
return null;
}
@ -289,5 +289,5 @@ export {
handleFormError,
diffText,
base64ToSvg,
getUserAgentType,
getUaType,
};