diff --git a/controller/github.go b/controller/github.go index f6d3716f..79711841 100644 --- a/controller/github.go +++ b/controller/github.go @@ -142,8 +142,13 @@ func GitHubOAuth(c *gin.Context) { user.Email = githubUser.Email user.Role = common.RoleCommonUser user.Status = common.UserStatusEnabled + affCode := session.Get("aff") + inviterId := 0 + if affCode != nil { + inviterId, _ = model.GetUserIdByAffCode(affCode.(string)) + } - if err := user.Insert(0); err != nil { + if err := user.Insert(inviterId); err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), @@ -227,6 +232,10 @@ func GitHubBind(c *gin.Context) { func GenerateOAuthCode(c *gin.Context) { session := sessions.Default(c) state := common.GetRandomString(12) + affCode := c.Query("aff") + if affCode != "" { + session.Set("aff", affCode) + } session.Set("oauth_state", state) err := session.Save() if err != nil { diff --git a/controller/linuxdo.go b/controller/linuxdo.go index 38e622c6..2cdb3517 100644 --- a/controller/linuxdo.go +++ b/controller/linuxdo.go @@ -237,7 +237,13 @@ func LinuxdoOAuth(c *gin.Context) { user.Role = common.RoleCommonUser user.Status = common.UserStatusEnabled - if err := user.Insert(0); err != nil { + affCode := session.Get("aff") + inviterId := 0 + if affCode != nil { + inviterId, _ = model.GetUserIdByAffCode(affCode.(string)) + } + + if err := user.Insert(inviterId); err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), diff --git a/web/src/components/LoginForm.js b/web/src/components/LoginForm.js index f840c11d..ce4961ee 100644 --- a/web/src/components/LoginForm.js +++ b/web/src/components/LoginForm.js @@ -44,8 +44,15 @@ const LoginForm = () => { const [turnstileToken, setTurnstileToken] = useState(''); let navigate = useNavigate(); const [status, setStatus] = useState({}); + const [showWeChatLoginModal, setShowWeChatLoginModal] = useState(false); + const logo = getLogo(); + let affCode = new URLSearchParams(window.location.search).get('aff'); + if (affCode) { + localStorage.setItem('aff', affCode); + } + useEffect(() => { if (searchParams.get('expired')) { showError('未登录或登录已过期,请重新登录!'); @@ -61,7 +68,6 @@ const LoginForm = () => { } }, []); - const [showWeChatLoginModal, setShowWeChatLoginModal] = useState(false); const onWeChatLoginClicked = () => { setShowWeChatLoginModal(true); diff --git a/web/src/components/RegisterForm.js b/web/src/components/RegisterForm.js index 5ff25883..d3256960 100644 --- a/web/src/components/RegisterForm.js +++ b/web/src/components/RegisterForm.js @@ -1,10 +1,16 @@ import React, { useEffect, useState } from 'react'; import { Link, useNavigate } from 'react-router-dom'; -import { API, getLogo, showError, showInfo, showSuccess } from '../helpers'; +import { API, getLogo, showError, showInfo, showSuccess, updateAPI } from '../helpers'; import Turnstile from 'react-turnstile'; -import { Button, Card, Form, Layout } from '@douyinfe/semi-ui'; +import { Button, Card, Divider, Form, Icon, Layout, Modal } from '@douyinfe/semi-ui'; import Title from '@douyinfe/semi-ui/lib/es/typography/title'; import Text from '@douyinfe/semi-ui/lib/es/typography/text'; +import { IconGithubLogo } from '@douyinfe/semi-icons'; +import { onGitHubOAuthClicked, onLinuxDOOAuthClicked } from './utils.js'; +import LinuxDoIcon from './LinuxDoIcon.js'; +import WeChatIcon from './WeChatIcon.js'; +import TelegramLoginButton from 'react-telegram-login/src'; +import { setUserData } from '../helpers/data.js'; const RegisterForm = () => { const [inputs, setInputs] = useState({ @@ -20,7 +26,11 @@ const RegisterForm = () => { const [turnstileSiteKey, setTurnstileSiteKey] = useState(''); const [turnstileToken, setTurnstileToken] = useState(''); const [loading, setLoading] = useState(false); + const [showWeChatLoginModal, setShowWeChatLoginModal] = useState(false); + const [status, setStatus] = useState({}); + let navigate = useNavigate(); const logo = getLogo(); + let affCode = new URLSearchParams(window.location.search).get('aff'); if (affCode) { localStorage.setItem('aff', affCode); @@ -30,6 +40,7 @@ const RegisterForm = () => { let status = localStorage.getItem('status'); if (status) { status = JSON.parse(status); + setStatus(status); setShowEmailVerification(status.email_verification); if (status.turnstile_check) { setTurnstileEnabled(true); @@ -38,7 +49,32 @@ const RegisterForm = () => { } }); - let navigate = useNavigate(); + + const onWeChatLoginClicked = () => { + setShowWeChatLoginModal(true); + }; + + const onSubmitWeChatVerificationCode = async () => { + if (turnstileEnabled && turnstileToken === '') { + showInfo('请稍后几秒重试,Turnstile 正在检查用户环境!'); + return; + } + const res = await API.get( + `/api/oauth/wechat?code=${inputs.wechat_verification_code}`, + ); + const { success, message, data } = res.data; + if (success) { + userDispatch({ type: 'login', payload: data }); + localStorage.setItem('user', JSON.stringify(data)); + setUserData(data); + updateAPI(); + navigate('/'); + showSuccess('登录成功!'); + setShowWeChatLoginModal(false); + } else { + showError(message); + } + }; function handleChange(name, value) { setInputs((inputs) => ({ ...inputs, [name]: value })); @@ -189,14 +225,127 @@ const RegisterForm = () => { + {status.github_oauth || + status.wechat_login || + status.telegram_oauth || + status.linuxdo_oauth ? ( + <> + + 第三方登录 + +
+ {status.github_oauth ? ( +
+ {status.telegram_oauth ? ( + <> +
+ +
+ + ) : ( + <> + )} + + ) : ( + <> + )} - {turnstileEnabled ? ( - { - setTurnstileToken(token); + setShowWeChatLoginModal(false)} + okText={'登录'} + size={'small'} + centered={true} + > +
+ > + +
+
+

+ 微信扫码关注公众号,输入「验证码」获取验证码(三分钟内有效) +

+
+
+ + handleChange('wechat_verification_code', value) + } + /> + +
+ {turnstileEnabled ? ( +
+ { + setTurnstileToken(token); + }} + /> +
) : ( <> )} diff --git a/web/src/components/utils.js b/web/src/components/utils.js index 7772a5d8..a2ee8b7e 100644 --- a/web/src/components/utils.js +++ b/web/src/components/utils.js @@ -1,7 +1,12 @@ import { API, showError } from '../helpers'; export async function getOAuthState() { - const res = await API.get('/api/oauth/state'); + let path = '/api/oauth/state'; + let affCode = new URLSearchParams(window.location.search).get('aff'); + if (affCode) { + path += `?aff=${affCode}`; + } + const res = await API.get(path); const { success, message, data } = res.data; if (success) { return data;