v2board/app/Http/Controllers/Passport/AuthController.php

302 lines
11 KiB
PHP
Raw Normal View History

2020-01-29 16:22:39 +08:00
<?php
namespace App\Http\Controllers\Passport;
use App\Http\Controllers\Controller;
use App\Http\Requests\Passport\AuthRegister;
use App\Http\Requests\Passport\AuthForget;
use App\Http\Requests\Passport\AuthLogin;
2022-06-27 01:47:18 +08:00
use App\Jobs\SendEmailJob;
2022-12-13 12:29:23 +08:00
use App\Services\AuthService;
2020-01-29 16:22:39 +08:00
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
2020-02-04 00:33:02 +08:00
use App\Models\Plan;
2020-01-29 16:22:39 +08:00
use App\Models\User;
2020-01-30 17:18:25 +08:00
use App\Models\InviteCode;
2020-01-29 16:22:39 +08:00
use App\Utils\Helper;
2020-02-09 18:01:06 +08:00
use App\Utils\Dict;
2020-03-13 14:32:36 +08:00
use App\Utils\CacheKey;
2020-10-09 23:27:36 +08:00
use ReCaptcha\ReCaptcha;
2020-01-29 16:22:39 +08:00
class AuthController extends Controller
{
2022-06-27 01:47:18 +08:00
public function loginWithMailLink(Request $request)
{
if (!(int)config('v2board.login_with_mail_link_enable')) {
abort(404);
}
$params = $request->validate([
'email' => 'required|email',
'redirect' => 'nullable'
]);
if (Cache::get(CacheKey::get('LAST_SEND_LOGIN_WITH_MAIL_LINK_TIMESTAMP', $params['email']))) {
abort(500, __('Sending frequently, please try again later'));
}
$user = User::where('email', $params['email'])->first();
if (!$user) {
return response([
'data' => true
]);
}
$code = Helper::guid();
$key = CacheKey::get('TEMP_TOKEN', $code);
Cache::put($key, $user->id, 300);
Cache::put(CacheKey::get('LAST_SEND_LOGIN_WITH_MAIL_LINK_TIMESTAMP', $params['email']), time(), 60);
$redirect = '/#/login?verify=' . $code . '&redirect=' . ($request->input('redirect') ? $request->input('redirect') : 'dashboard');
if (config('v2board.app_url')) {
$link = config('v2board.app_url') . $redirect;
} else {
$link = url($redirect);
}
SendEmailJob::dispatch([
'email' => $user->email,
'subject' => __('Login to :name', [
'name' => config('v2board.app_name', 'V2Board')
]),
'template_name' => 'login',
'template_value' => [
'name' => config('v2board.app_name', 'V2Board'),
'link' => $link,
'url' => config('v2board.app_url')
]
]);
return response([
'data' => $link
]);
}
2020-01-29 16:22:39 +08:00
public function register(AuthRegister $request)
{
2022-03-29 20:57:19 +08:00
if ((int)config('v2board.register_limit_by_ip_enable', 0)) {
$registerCountByIP = Cache::get(CacheKey::get('REGISTER_IP_RATE_LIMIT', $request->ip())) ?? 0;
2022-03-29 21:11:37 +08:00
if ((int)$registerCountByIP >= (int)config('v2board.register_limit_count', 3)) {
2022-12-05 19:45:02 +08:00
abort(500, __('Register frequently, please try again after :minute minute', [
'minute' => config('v2board.register_limit_expire', 60)
]));
2022-03-29 20:57:19 +08:00
}
2022-03-29 20:39:22 +08:00
}
2020-10-09 23:27:36 +08:00
if ((int)config('v2board.recaptcha_enable', 0)) {
$recaptcha = new ReCaptcha(config('v2board.recaptcha_key'));
$recaptchaResp = $recaptcha->verify($request->input('recaptcha_data'));
if (!$recaptchaResp->isSuccess()) {
2021-06-12 00:56:39 +08:00
abort(500, __('Invalid code is incorrect'));
2020-10-09 23:27:36 +08:00
}
}
2020-02-09 18:09:48 +08:00
if ((int)config('v2board.email_whitelist_enable', 0)) {
2020-02-09 18:01:06 +08:00
if (!Helper::emailSuffixVerify(
$request->input('email'),
2020-02-09 18:09:48 +08:00
config('v2board.email_whitelist_suffix', Dict::EMAIL_WHITELIST_SUFFIX_DEFAULT))
2020-02-09 18:01:06 +08:00
) {
2021-06-12 00:56:39 +08:00
abort(500, __('Email suffix is not in the Whitelist'));
2020-02-09 18:01:06 +08:00
}
}
2020-05-25 18:02:13 +08:00
if ((int)config('v2board.email_gmail_limit_enable', 0)) {
$prefix = explode('@', $request->input('email'))[0];
if (strpos($prefix, '.') !== false || strpos($prefix, '+') !== false) {
2021-06-12 00:56:39 +08:00
abort(500, __('Gmail alias is not supported'));
2020-05-25 18:02:13 +08:00
}
}
2020-01-29 16:22:39 +08:00
if ((int)config('v2board.stop_register', 0)) {
2021-06-12 00:56:39 +08:00
abort(500, __('Registration has closed'));
2020-01-29 16:22:39 +08:00
}
if ((int)config('v2board.invite_force', 0)) {
if (empty($request->input('invite_code'))) {
2021-06-12 00:56:39 +08:00
abort(500, __('You must use the invitation code to register'));
2020-01-29 16:22:39 +08:00
}
}
if ((int)config('v2board.email_verify', 0)) {
if (empty($request->input('email_code'))) {
2021-06-12 00:56:39 +08:00
abort(500, __('Email verification code cannot be empty'));
2020-01-29 16:22:39 +08:00
}
2020-03-13 14:32:36 +08:00
if (Cache::get(CacheKey::get('EMAIL_VERIFY_CODE', $request->input('email'))) !== $request->input('email_code')) {
2021-06-12 00:56:39 +08:00
abort(500, __('Incorrect email verification code'));
2020-01-29 16:22:39 +08:00
}
}
$email = $request->input('email');
$password = $request->input('password');
$exist = User::where('email', $email)->first();
if ($exist) {
2021-06-12 00:56:39 +08:00
abort(500, __('Email already exists'));
2020-01-29 16:22:39 +08:00
}
$user = new User();
$user->email = $email;
$user->password = password_hash($password, PASSWORD_DEFAULT);
2020-06-08 01:08:07 +08:00
$user->uuid = Helper::guid(true);
2020-01-29 16:22:39 +08:00
$user->token = Helper::guid();
if ($request->input('invite_code')) {
$inviteCode = InviteCode::where('code', $request->input('invite_code'))
->where('status', 0)
->first();
if (!$inviteCode) {
if ((int)config('v2board.invite_force', 0)) {
2021-06-12 00:56:39 +08:00
abort(500, __('Invalid invitation code'));
2020-01-29 16:22:39 +08:00
}
} else {
$user->invite_user_id = $inviteCode->user_id ? $inviteCode->user_id : null;
2020-03-13 14:33:48 +08:00
if (!(int)config('v2board.invite_never_expire', 0)) {
2020-01-29 16:22:39 +08:00
$inviteCode->status = 1;
$inviteCode->save();
}
}
}
// try out
2020-02-08 23:03:48 +08:00
if ((int)config('v2board.try_out_plan_id', 0)) {
2020-01-29 16:22:39 +08:00
$plan = Plan::find(config('v2board.try_out_plan_id'));
if ($plan) {
$user->transfer_enable = $plan->transfer_enable * 1073741824;
$user->plan_id = $plan->id;
$user->group_id = $plan->group_id;
$user->expired_at = time() + (config('v2board.try_out_hour', 1) * 3600);
}
}
if (!$user->save()) {
2021-06-12 00:56:39 +08:00
abort(500, __('Register failed'));
2020-01-29 16:22:39 +08:00
}
if ((int)config('v2board.email_verify', 0)) {
2020-03-13 14:32:36 +08:00
Cache::forget(CacheKey::get('EMAIL_VERIFY_CODE', $request->input('email')));
2020-01-29 16:22:39 +08:00
}
2021-09-04 20:41:57 +08:00
2022-03-29 20:39:22 +08:00
$user->last_login_at = time();
$user->save();
2022-03-29 20:57:19 +08:00
if ((int)config('v2board.register_limit_by_ip_enable', 0)) {
2022-03-29 21:11:37 +08:00
Cache::put(
CacheKey::get('REGISTER_IP_RATE_LIMIT', $request->ip()),
(int)$registerCountByIP + 1,
(int)config('v2board.register_limit_expire', 60) * 60
);
2022-03-29 20:57:19 +08:00
}
2022-12-13 12:29:23 +08:00
$authService = new AuthService($user);
2020-01-29 16:22:39 +08:00
return response()->json([
2022-12-15 15:53:25 +08:00
'data' => $authService->generateAuthData($request)
2020-01-29 16:22:39 +08:00
]);
}
public function login(AuthLogin $request)
{
$email = $request->input('email');
$password = $request->input('password');
2022-12-15 01:58:01 +08:00
$passwordErrorCount = (int)Cache::get(CacheKey::get('PASSWORD_ERROR_LIMIT', $email), 0);
2022-12-14 22:58:42 +08:00
if ($passwordErrorCount >= 5) {
2022-12-14 23:02:12 +08:00
abort(500, __('There are too many password errors, please try again after 30 minutes.'));
2022-12-14 22:58:42 +08:00
}
2020-01-29 16:22:39 +08:00
$user = User::where('email', $email)->first();
if (!$user) {
2021-06-12 00:56:39 +08:00
abort(500, __('Incorrect email or password'));
2020-01-29 16:22:39 +08:00
}
2020-02-02 20:44:52 +08:00
if (!Helper::multiPasswordVerify(
2020-01-31 21:54:17 +08:00
$user->password_algo,
2021-09-14 12:10:29 +08:00
$user->password_salt,
2020-01-31 21:54:17 +08:00
$password,
$user->password)
) {
2022-12-14 22:58:42 +08:00
Cache::put(
CacheKey::get('PASSWORD_ERROR_LIMIT', $email),
(int)$passwordErrorCount + 1,
30 * 60
);
2021-06-12 00:56:39 +08:00
abort(500, __('Incorrect email or password'));
2020-01-29 16:22:39 +08:00
}
2020-03-02 20:29:17 +08:00
if ($user->banned) {
2021-06-12 00:56:39 +08:00
abort(500, __('Your account has been suspended'));
2020-01-29 16:22:39 +08:00
}
2022-12-13 12:29:23 +08:00
$authService = new AuthService($user);
2020-01-29 16:22:39 +08:00
return response([
2022-12-15 15:53:25 +08:00
'data' => $authService->generateAuthData($request)
2020-01-29 16:22:39 +08:00
]);
}
public function token2Login(Request $request)
{
if ($request->input('token')) {
2020-08-13 21:36:59 +08:00
$redirect = '/#/login?verify=' . $request->input('token') . '&redirect=' . ($request->input('redirect') ? $request->input('redirect') : 'dashboard');
2020-01-29 16:22:39 +08:00
if (config('v2board.app_url')) {
$location = config('v2board.app_url') . $redirect;
} else {
$location = url($redirect);
}
2020-10-14 16:21:20 +08:00
return redirect()->to($location)->send();
2020-01-29 16:22:39 +08:00
}
if ($request->input('verify')) {
2020-08-13 21:36:59 +08:00
$key = CacheKey::get('TEMP_TOKEN', $request->input('verify'));
2020-01-29 16:22:39 +08:00
$userId = Cache::get($key);
if (!$userId) {
2021-06-12 00:56:39 +08:00
abort(500, __('Token error'));
2020-01-29 16:22:39 +08:00
}
$user = User::find($userId);
if (!$user) {
2021-06-12 00:56:39 +08:00
abort(500, __('The user does not '));
2020-01-29 16:22:39 +08:00
}
2020-03-02 20:29:17 +08:00
if ($user->banned) {
2021-06-12 00:56:39 +08:00
abort(500, __('Your account has been suspended'));
2020-01-29 16:22:39 +08:00
}
Cache::forget($key);
2022-12-13 12:29:23 +08:00
$authService = new AuthService($user);
2020-01-29 16:22:39 +08:00
return response([
2022-12-15 15:53:25 +08:00
'data' => $authService->generateAuthData($request)
2020-01-29 16:22:39 +08:00
]);
}
}
2020-10-20 02:09:32 +08:00
public function getQuickLoginUrl(Request $request)
{
2022-10-01 02:28:49 +08:00
$authorization = $request->input('auth_data') ?? $request->header('authorization');
if (!$authorization) abort(403, '未登录或登陆已过期');
2022-12-13 12:29:23 +08:00
$user = AuthService::decryptAuthData($authorization);
if (!$user) abort(403, '未登录或登陆已过期');
2020-10-20 02:09:32 +08:00
$code = Helper::guid();
$key = CacheKey::get('TEMP_TOKEN', $code);
2022-12-13 12:29:23 +08:00
Cache::put($key, $user['id'], 60);
2020-10-20 02:09:32 +08:00
$redirect = '/#/login?verify=' . $code . '&redirect=' . ($request->input('redirect') ? $request->input('redirect') : 'dashboard');
if (config('v2board.app_url')) {
$url = config('v2board.app_url') . $redirect;
} else {
$url = url($redirect);
}
return response([
'data' => $url
]);
}
2020-01-29 16:22:39 +08:00
public function forget(AuthForget $request)
{
2020-03-13 14:32:36 +08:00
if (Cache::get(CacheKey::get('EMAIL_VERIFY_CODE', $request->input('email'))) !== $request->input('email_code')) {
2021-06-12 00:56:39 +08:00
abort(500, __('Incorrect email verification code'));
2020-01-29 16:22:39 +08:00
}
$user = User::where('email', $request->input('email'))->first();
2020-02-07 19:34:24 +08:00
if (!$user) {
2021-06-12 00:56:39 +08:00
abort(500, __('This email is not registered in the system'));
2020-02-07 19:34:24 +08:00
}
2020-01-29 16:22:39 +08:00
$user->password = password_hash($request->input('password'), PASSWORD_DEFAULT);
2020-01-31 21:54:17 +08:00
$user->password_algo = NULL;
2021-09-14 12:12:44 +08:00
$user->password_salt = NULL;
2020-01-29 16:22:39 +08:00
if (!$user->save()) {
2021-06-12 00:56:39 +08:00
abort(500, __('Reset failed'));
2020-01-29 16:22:39 +08:00
}
2020-03-13 14:32:36 +08:00
Cache::forget(CacheKey::get('EMAIL_VERIFY_CODE', $request->input('email')));
2020-01-29 16:22:39 +08:00
return response([
'data' => true
]);
}
}