diff --git a/packages/renderer/src/pages/Login.tsx b/packages/renderer/src/pages/Login.tsx index 7145a28..860b8b1 100644 --- a/packages/renderer/src/pages/Login.tsx +++ b/packages/renderer/src/pages/Login.tsx @@ -1,10 +1,16 @@ import md5 from 'md5' import QRCode from 'qrcode' import { Fragment } from 'react' -import {loginWithEmail, loginWithPhone} from '@/api/auth' +import { + checkLoginQrCodeStatus, + fetchLoginQrCodeKey, + loginWithEmail, + loginWithPhone, +} from '@/api/auth' import SvgIcon from '@/components/SvgIcon' import { state } from '@/store' import { setCookies } from '@/utils/cookie' +import { useInterval } from 'react-use' enum Method { QRCODE = 'qrcode', @@ -196,25 +202,24 @@ const LoginWithEmail = () => { const navigate = useNavigate() const doLogin = useMutation( - () => { - return loginWithEmail({ - email: email.trim(), - md5_password: md5(password.trim()) - }) + () => + loginWithEmail({ + email: email.trim(), + md5_password: md5(password.trim()), + }), + { + onSuccess: result => { + if (result?.code !== 200) { + toast(`Login failed: ${result.code}`) + return + } + saveCookie(result.cookie) + navigate(-1) }, - { - onSuccess: result => { - if (result?.code !== 200) { - toast(`Login failed: ${result.code}`) - return - } - saveCookie(result.cookie) - navigate(-1) - }, - onError: error => { - toast(`Login failed: ${error}`) - }, - } + onError: error => { + toast(`Login failed: ${error}`) + }, + } ) const handleLogin = () => { @@ -226,7 +231,11 @@ const LoginWithEmail = () => { toast.error('Please enter password') return } - if (email.match(/^[^\s@]+@(126|163|yeah|188|vip\.163|vip\.126)\.(com|net)$/) == null){ + if ( + email.match( + /^[^\s@]+@(126|163|yeah|188|vip\.163|vip\.126)\.(com|net)$/ + ) == null + ) { toast.error('Please use netease email') return } @@ -304,10 +313,61 @@ const LoginWithPhone = () => { // Login with QRCode const LoginWithQRCode = () => { - const [qrCodeUrl, setQrCodeUrl] = useState('dasdasfa') + const [qrCodeMessage, setQrCodeMessage] = useState('扫码登录') const [qrCodeImage, setQrCodeImage] = useState('') - useMemo(async () => { - try { + + const navigate = useNavigate() + + const { + data: key = { code: 200, data: { code: 200, unikey: 'Not Ready' } }, + status: keyStatus, + refetch: refetchKey, + } = useQuery( + 'qrCodeKey', + async () => { + const result = await fetchLoginQrCodeKey() + if (result.data.code !== 200) { + throw Error(`Failed to fetch QR code key: ${result.data.code}`) + } + return result + }, + { + retry: true, + retryDelay: 500, + } + ) + + useInterval(async () => { + if (keyStatus !== 'success') return + const qrCodeStatus = await checkLoginQrCodeStatus({ key: key.data.unikey }) + switch (qrCodeStatus.code) { + case 800: + refetchKey() + break + case 801: + setQrCodeMessage('等待扫码') + break + case 802: + setQrCodeMessage('等待确认') + break + case 803: + if (qrCodeStatus.cookie === undefined) { + toast('checkLoginQrCodeStatus returned 803 without cookie') + break + } + saveCookie(qrCodeStatus.cookie) + navigate(-1) + break + } + }, 1000) + + const qrCodeUrl = useMemo( + () => `https://music.163.com/login?codekey=${key.data.unikey}`, + [key] + ) + + useEffect(() => { + const updateImage = async () => { const image = await QRCode.toDataURL(qrCodeUrl, { width: 1024, margin: 0, @@ -317,11 +377,10 @@ const LoginWithQRCode = () => { }, }) setQrCodeImage(image) - } catch (err) { - console.error(err) } + updateImage() }, [qrCodeUrl]) - const qrCodeMessage = 'test' + return (
diff --git a/packages/renderer/src/utils/cookie.ts b/packages/renderer/src/utils/cookie.ts index 5e3f694..b87851d 100644 --- a/packages/renderer/src/utils/cookie.ts +++ b/packages/renderer/src/utils/cookie.ts @@ -1,7 +1,7 @@ import Cookies from 'js-cookie' export function setCookies(string: string) { - const cookies = string.replace('HTTPOnly', '').split(';;') + const cookies = string.replace(/;.*?HTTPOnly.*?;/g, ';;').split(';;') cookies.map(cookie => { const cookieKeyValue = cookie.split(';')[0].split('=') const [key, value] = cookieKeyValue