| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588 |
- <?php
- namespace App\Controllers;
- use App\Models\InviteCode;
- use App\Services\Config;
- use App\Utils\Check;
- use App\Utils\Tools;
- use App\Utils\Radius;
- use Exception;
- use voku\helper\AntiXSS;
- use App\Utils\Hash;
- use App\Utils\Da;
- use App\Services\Auth;
- use App\Services\Mail;
- use App\Models\User;
- use App\Models\LoginIp;
- use App\Models\EmailVerify;
- use App\Utils\GA;
- use App\Utils\Geetest;
- use App\Utils\TelegramSessionManager;
- /**
- * AuthController
- */
- class AuthController extends BaseController
- {
- public function login()
- {
- $GtSdk = null;
- $recaptcha_sitekey = null;
- if (Config::get('enable_login_captcha') === 'true') {
- switch (Config::get('captcha_provider')) {
- case 'recaptcha':
- $recaptcha_sitekey = Config::get('recaptcha_sitekey');
- break;
- case 'geetest':
- $uid = time() . random_int(1, 10000);
- $GtSdk = Geetest::get($uid);
- break;
- }
- }
- if (Config::get('enable_telegram') === 'true') {
- $login_text = TelegramSessionManager::add_login_session();
- $login = explode('|', $login_text);
- $login_token = $login[0];
- $login_number = $login[1];
- } else {
- $login_token = '';
- $login_number = '';
- }
- return $this->view()
- ->assign('geetest_html', $GtSdk)
- ->assign('login_token', $login_token)
- ->assign('login_number', $login_number)
- ->assign('telegram_bot', Config::get('telegram_bot'))
- ->assign('base_url', Config::get('baseUrl'))
- ->assign('recaptcha_sitekey', $recaptcha_sitekey)
- ->display('auth/login.tpl');
- }
- public function getCaptcha($request, $response, $args)
- {
- $GtSdk = null;
- $recaptcha_sitekey = null;
- if (Config::get('captcha_provider') != '') {
- switch (Config::get('captcha_provider')) {
- case 'recaptcha':
- $recaptcha_sitekey = Config::get('recaptcha_sitekey');
- $res['recaptchaKey'] = $recaptcha_sitekey;
- break;
- case 'geetest':
- $uid = time() . random_int(1, 10000);
- $GtSdk = Geetest::get($uid);
- $res['GtSdk'] = $GtSdk;
- break;
- }
- }
- $res['respon'] = 1;
- return $response->getBody()->write(json_encode($res));
- }
- public function loginHandle($request, $response, $args)
- {
- // $data = $request->post('sdf');
- $email = $request->getParam('email');
- $email = trim($email);
- $email = strtolower($email);
- $passwd = $request->getParam('passwd');
- $code = $request->getParam('code');
- $rememberMe = $request->getParam('remember_me');
- if (Config::get('enable_login_captcha') === 'true') {
- switch (Config::get('captcha_provider')) {
- case 'recaptcha':
- $recaptcha = $request->getParam('recaptcha');
- if ($recaptcha == '') {
- $ret = false;
- } else {
- $json = file_get_contents('https://recaptcha.net/recaptcha/api/siteverify?secret=' . Config::get('recaptcha_secret') . '&response=' . $recaptcha);
- $ret = json_decode($json)->success;
- }
- break;
- case 'geetest':
- $ret = Geetest::verify($request->getParam('geetest_challenge'), $request->getParam('geetest_validate'), $request->getParam('geetest_seccode'));
- break;
- }
- if (!$ret) {
- $res['ret'] = 0;
- $res['msg'] = '系统无法接受您的验证结果,请刷新页面后重试。';
- return $response->getBody()->write(json_encode($res));
- }
- }
- // Handle Login
- $user = User::where('email', '=', $email)->first();
- if ($user == null) {
- $rs['ret'] = 0;
- $rs['msg'] = '邮箱不存在';
- return $response->getBody()->write(json_encode($rs));
- }
- if (!Hash::checkPassword($user->pass, $passwd)) {
- $rs['ret'] = 0;
- $rs['msg'] = '邮箱或者密码错误';
- $loginIP = new LoginIp();
- $loginIP->ip = $_SERVER['REMOTE_ADDR'];
- $loginIP->userid = $user->id;
- $loginIP->datetime = time();
- $loginIP->type = 1;
- $loginIP->save();
- return $response->getBody()->write(json_encode($rs));
- }
- $time = 3600 * 24;
- if ($rememberMe) {
- $time = 3600 * 24 * (Config::get('rememberMeDuration') ?: 7);
- }
- if ($user->ga_enable == 1) {
- $ga = new GA();
- $rcode = $ga->verifyCode($user->ga_token, $code);
- if (!$rcode) {
- $res['ret'] = 0;
- $res['msg'] = '两步验证码错误,如果您是丢失了生成器或者错误地设置了这个选项,您可以尝试重置密码,即可取消这个选项。';
- return $response->getBody()->write(json_encode($res));
- }
- }
- Auth::login($user->id, $time);
- $rs['ret'] = 1;
- $rs['msg'] = '登录成功';
- $loginIP = new LoginIp();
- $loginIP->ip = $_SERVER['REMOTE_ADDR'];
- $loginIP->userid = $user->id;
- $loginIP->datetime = time();
- $loginIP->type = 0;
- $loginIP->save();
- return $response->getBody()->write(json_encode($rs));
- }
- public function qrcode_loginHandle($request, $response, $args)
- {
- // $data = $request->post('sdf');
- $token = $request->getParam('token');
- $number = $request->getParam('number');
- $ret = TelegramSessionManager::step2_verify_login_session($token, $number);
- if (!$ret) {
- $res['ret'] = 0;
- $res['msg'] = '此令牌无法被使用。';
- return $response->getBody()->write(json_encode($res));
- }
- // Handle Login
- $user = User::where('id', '=', $ret)->first();
- // @todo
- $time = 3600 * 24;
- Auth::login($user->id, $time);
- $rs['ret'] = 1;
- $rs['msg'] = '登录成功';
- $this->logUserIp($user->id, $_SERVER['REMOTE_ADDR']);
- return $response->getBody()->write(json_encode($rs));
- }
- private function logUserIp($id, $ip)
- {
- $loginip = new LoginIp();
- $loginip->ip = $ip;
- $loginip->userid = $id;
- $loginip->datetime = time();
- $loginip->type = 0;
- $loginip->save();
- }
- public function register($request, $response, $next)
- {
- $ary = $request->getQueryParams();
- $code = '';
- if (isset($ary['code'])) {
- $antiXss = new AntiXSS();
- $code = $antiXss->xss_clean($ary['code']);
- }
- $GtSdk = null;
- $recaptcha_sitekey = null;
- if (Config::get('enable_reg_captcha') === 'true') {
- switch (Config::get('captcha_provider')) {
- case 'recaptcha':
- $recaptcha_sitekey = Config::get('recaptcha_sitekey');
- break;
- case 'geetest':
- $uid = time() . random_int(1, 10000);
- $GtSdk = Geetest::get($uid);
- break;
- }
- }
- return $this->view()
- ->assign('geetest_html', $GtSdk)
- ->assign('enable_email_verify', Config::get('enable_email_verify'))
- ->assign('code', $code)
- ->assign('recaptcha_sitekey', $recaptcha_sitekey)
- ->display('auth/register.tpl');
- }
- public function sendVerify($request, $response, $next)
- {
- if (Config::get('enable_email_verify') === 'true') {
- $email = $request->getParam('email');
- $email = trim($email);
- if ($email == '') {
- $res['ret'] = 0;
- $res['msg'] = '未填写邮箱';
- return $response->getBody()->write(json_encode($res));
- }
- // check email format
- if (!Check::isEmailLegal($email)) {
- $res['ret'] = 0;
- $res['msg'] = '邮箱无效';
- return $response->getBody()->write(json_encode($res));
- }
- $user = User::where('email', '=', $email)->first();
- if ($user != null) {
- $res['ret'] = 0;
- $res['msg'] = '此邮箱已经注册';
- return $response->getBody()->write(json_encode($res));
- }
- $ipcount = EmailVerify::where('ip', '=', $_SERVER['REMOTE_ADDR'])->where('expire_in', '>', time())->count();
- if ($ipcount >= (int)Config::get('email_verify_iplimit')) {
- $res['ret'] = 0;
- $res['msg'] = '此IP请求次数过多';
- return $response->getBody()->write(json_encode($res));
- }
- $mailcount = EmailVerify::where('email', '=', $email)->where('expire_in', '>', time())->count();
- if ($mailcount >= 3) {
- $res['ret'] = 0;
- $res['msg'] = '此邮箱请求次数过多';
- return $response->getBody()->write(json_encode($res));
- }
- $code = Tools::genRandomNum(6);
- $ev = new EmailVerify();
- $ev->expire_in = time() + Config::get('email_verify_ttl');
- $ev->ip = $_SERVER['REMOTE_ADDR'];
- $ev->email = $email;
- $ev->code = $code;
- $ev->save();
- $subject = Config::get('appName') . '- 验证邮件';
- try {
- Mail::send($email, $subject, 'auth/verify.tpl', [
- 'code' => $code, 'expire' => date('Y-m-d H:i:s', time() + Config::get('email_verify_ttl'))
- ], [
- //BASE_PATH.'/public/assets/email/styles.css'
- ]);
- } catch (Exception $e) {
- $res['ret'] = 1;
- $res['msg'] = '邮件发送失败,请联系网站管理员。';
- return $response->getBody()->write(json_encode($res));
- }
- $res['ret'] = 1;
- $res['msg'] = '验证码发送成功,请查收邮件。';
- return $response->getBody()->write(json_encode($res));
- }
- $res['ret'] = 0;
- return $response->getBody()->write(json_encode($res));
- }
- public function registerHandle($request, $response)
- {
- if (Config::get('register_mode') === 'close') {
- $res['ret'] = 0;
- $res['msg'] = '未开放注册。';
- return $response->getBody()->write(json_encode($res));
- }
- $name = $request->getParam('name');
- $email = $request->getParam('email');
- $email = trim($email);
- $email = strtolower($email);
- $passwd = $request->getParam('passwd');
- $repasswd = $request->getParam('repasswd');
- $code = $request->getParam('code');
- $code = trim($code);
- $imtype = $request->getParam('imtype');
- $emailcode = $request->getParam('emailcode');
- $emailcode = trim($emailcode);
- $wechat = $request->getParam('wechat');
- $wechat = trim($wechat);
- // check code
- if (Config::get('enable_reg_captcha') === 'true') {
- switch (Config::get('captcha_provider')) {
- case 'recaptcha':
- $recaptcha = $request->getParam('recaptcha');
- if ($recaptcha == '') {
- $ret = false;
- } else {
- $json = file_get_contents('https://recaptcha.net/recaptcha/api/siteverify?secret=' . Config::get('recaptcha_secret') . '&response=' . $recaptcha);
- $ret = json_decode($json)->success;
- }
- break;
- case 'geetest':
- $ret = Geetest::verify($request->getParam('geetest_challenge'), $request->getParam('geetest_validate'), $request->getParam('geetest_seccode'));
- break;
- }
- if (!$ret) {
- $res['ret'] = 0;
- $res['msg'] = '系统无法接受您的验证结果,请刷新页面后重试。';
- return $response->getBody()->write(json_encode($res));
- }
- }
- //dumplin:1、邀请人等级为0则邀请码不可用;2、邀请人invite_num为可邀请次数,填负数则为无限
- $c = InviteCode::where('code', $code)->first();
- if ($c == null) {
- if (Config::get('register_mode') === 'invite') {
- $res['ret'] = 0;
- $res['msg'] = '邀请码无效';
- return $response->getBody()->write(json_encode($res));
- }
- } elseif ($c->user_id != 0) {
- $gift_user = User::where('id', '=', $c->user_id)->first();
- if ($gift_user == null) {
- $res['ret'] = 0;
- $res['msg'] = '邀请人不存在';
- return $response->getBody()->write(json_encode($res));
- }
- if ($gift_user->class == 0) {
- $res['ret'] = 0;
- $res['msg'] = '邀请人不是VIP';
- return $response->getBody()->write(json_encode($res));
- }
- if ($gift_user->invite_num == 0) {
- $res['ret'] = 0;
- $res['msg'] = '邀请人可用邀请次数为0';
- return $response->getBody()->write(json_encode($res));
- }
- }
- // check email format
- if (!Check::isEmailLegal($email)) {
- $res['ret'] = 0;
- $res['msg'] = '邮箱无效';
- return $response->getBody()->write(json_encode($res));
- }
- // check email
- $user = User::where('email', $email)->first();
- if ($user != null) {
- $res['ret'] = 0;
- $res['msg'] = '邮箱已经被注册了';
- return $response->getBody()->write(json_encode($res));
- }
- if (Config::get('enable_email_verify') === 'true') {
- $mailcount = EmailVerify::where('email', '=', $email)->where('code', '=', $emailcode)->where('expire_in', '>', time())->first();
- if ($mailcount == null) {
- $res['ret'] = 0;
- $res['msg'] = '您的邮箱验证码不正确';
- return $response->getBody()->write(json_encode($res));
- }
- }
- // check pwd length
- if (strlen($passwd) < 8) {
- $res['ret'] = 0;
- $res['msg'] = '密码请大于8位';
- return $response->getBody()->write(json_encode($res));
- }
- // check pwd re
- if ($passwd != $repasswd) {
- $res['ret'] = 0;
- $res['msg'] = '两次密码输入不符';
- return $response->getBody()->write(json_encode($res));
- }
- if ($imtype == '' || $wechat == '') {
- $res['ret'] = 0;
- $res['msg'] = '请填上你的联络方式';
- return $response->getBody()->write(json_encode($res));
- }
- $user = User::where('im_value', $wechat)->where('im_type', $imtype)->first();
- if ($user != null) {
- $res['ret'] = 0;
- $res['msg'] = '此联络方式已注册';
- return $response->getBody()->write(json_encode($res));
- }
- if (Config::get('enable_email_verify') === 'true') {
- EmailVerify::where('email', '=', $email)->delete();
- }
- // do reg user
- $user = new User();
- $antiXss = new AntiXSS();
- $user->user_name = $antiXss->xss_clean($name);
- $user->email = $email;
- $user->pass = Hash::passwordHash($passwd);
- $user->passwd = Tools::genRandomChar(6);
- $user->port = Tools::getAvPort();
- $user->t = 0;
- $user->u = 0;
- $user->d = 0;
- $user->method = Config::get('reg_method');
- $user->protocol = Config::get('reg_protocol');
- $user->protocol_param = Config::get('reg_protocol_param');
- $user->obfs = Config::get('reg_obfs');
- $user->obfs_param = Config::get('reg_obfs_param');
- $user->forbidden_ip = Config::get('reg_forbidden_ip');
- $user->forbidden_port = Config::get('reg_forbidden_port');
- $user->im_type = $imtype;
- $user->im_value = $antiXss->xss_clean($wechat);
- $user->transfer_enable = Tools::toGB(Config::get('defaultTraffic'));
- $user->invite_num = Config::get('inviteNum');
- $user->auto_reset_day = Config::get('reg_auto_reset_day');
- $user->auto_reset_bandwidth = Config::get('reg_auto_reset_bandwidth');
- $user->money = 0;
- //dumplin:填写邀请人,写入邀请奖励
- $user->ref_by = 0;
- if (($c != null) && $c->user_id != 0) {
- $gift_user = User::where('id', '=', $c->user_id)->first();
- $user->ref_by = $c->user_id;
- $user->money = Config::get('invite_get_money');
- $gift_user->transfer_enable += Config::get('invite_gift') * 1024 * 1024 * 1024;
- --$gift_user->invite_num;
- $gift_user->save();
- }
- $user->class_expire = date('Y-m-d H:i:s', time() + Config::get('user_class_expire_default') * 3600);
- $user->class = Config::get('user_class_default');
- $user->node_connector = Config::get('user_conn');
- $user->node_speedlimit = Config::get('user_speedlimit');
- $user->expire_in = date('Y-m-d H:i:s', time() + Config::get('user_expire_in_default') * 86400);
- $user->reg_date = date('Y-m-d H:i:s');
- $user->reg_ip = $_SERVER['REMOTE_ADDR'];
- $user->plan = 'A';
- $user->theme = Config::get('theme');
- $groups = explode(',', Config::get('ramdom_group'));
- $user->node_group = $groups[array_rand($groups)];
- $ga = new GA();
- $secret = $ga->createSecret();
- $user->ga_token = $secret;
- $user->ga_enable = 0;
- if ($user->save()) {
- $res['ret'] = 1;
- $res['msg'] = '注册成功!正在进入登录界面';
- Radius::Add($user, $user->passwd);
- return $response->getBody()->write(json_encode($res));
- }
- $res['ret'] = 0;
- $res['msg'] = '未知错误';
- return $response->getBody()->write(json_encode($res));
- }
- public function logout($request, $response, $next)
- {
- Auth::logout();
- return $response->withStatus(302)->withHeader('Location', '/auth/login');
- }
- public function qrcode_check($request, $response, $args)
- {
- $token = $request->getParam('token');
- $number = $request->getParam('number');
- $user = Auth::getUser();
- if ($user->isLogin) {
- $res['ret'] = 0;
- return $response->getBody()->write(json_encode($res));
- }
- if (Config::get('enable_telegram') === 'true') {
- $ret = TelegramSessionManager::check_login_session($token, $number);
- $res['ret'] = $ret;
- return $response->getBody()->write(json_encode($res));
- }
- $res['ret'] = 0;
- return $response->getBody()->write(json_encode($res));
- }
- public function telegram_oauth($request, $response, $args)
- {
- if (Config::get('enable_telegram') === 'true') {
- $auth_data = $request->getQueryParams();
- if ($this->telegram_oauth_check($auth_data) === true) { // Looks good, proceed.
- $telegram_id = $auth_data['id'];
- $user = User::query()->where('telegram_id', $telegram_id)->firstOrFail(); // Welcome Back :)
- if ($user == null) {
- return $this->view()->assign('title', '您需要先进行邮箱注册后绑定Telegram才能使用授权登录')->assign('message', '很抱歉带来的不便,请重新试试')->assign('redirect', '/auth/login')->display('telegram_error.tpl');
- }
- Auth::login($user->id, 3600);
- $this->logUserIp($user->id, $_SERVER['REMOTE_ADDR']);
- // 登陆成功!
- return $this->view()->assign('title', '登录成功')->assign('message', '正在前往仪表盘')->assign('redirect', '/user')->display('telegram_success.tpl');
- }
- // 验证失败
- return $this->view()->assign('title', '登陆超时或非法构造信息')->assign('message', '很抱歉带来的不便,请重新试试')->assign('redirect', '/auth/login')->display('telegram_error.tpl');
- }
- return $response->withRedirect('/404');
- }
- private function telegram_oauth_check($auth_data)
- {
- $check_hash = $auth_data['hash'];
- $bot_token = Config::get('telegram_token');
- unset($auth_data['hash']);
- $data_check_arr = [];
- foreach ($auth_data as $key => $value) {
- $data_check_arr[] = $key . '=' . $value;
- }
- sort($data_check_arr);
- $data_check_string = implode("\n", $data_check_arr);
- $secret_key = hash('sha256', $bot_token, true);
- $hash = hash_hmac('sha256', $data_check_string, $secret_key);
- if (strcmp($hash, $check_hash) !== 0) {
- return false; // Bad Data :(
- }
- if ((time() - $auth_data['auth_date']) > 300) { // Expire @ 5mins
- return false;
- }
- return true; // Good to Go
- }
- }
|