You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
237 lines
7.4 KiB
237 lines
7.4 KiB
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Business;
|
|
use App\Models\User;
|
|
use App\Notifications\MailNotification;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\Notification;
|
|
use Illuminate\Support\Str;
|
|
use Illuminate\Validation\Rule;
|
|
use Laravel\Socialite\Facades\Socialite;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
class AuthController extends Controller
|
|
{
|
|
public function redirectToGoogle()
|
|
{
|
|
return Socialite::driver('google')->stateless()->redirect();
|
|
}
|
|
|
|
public function handleGoogleCallback(Request $request)
|
|
{
|
|
try {
|
|
|
|
$user = Socialite::driver('google')->stateless()->user();
|
|
$find_user = User::where('email', $user->email)->first();
|
|
|
|
if (!$find_user)
|
|
{
|
|
|
|
$find_user = User::create($user->user + [
|
|
'password' => Hash::make(Str::random(8)),
|
|
'username' => $user->email,
|
|
'active' => true,
|
|
'has_password' => false
|
|
]);
|
|
|
|
}
|
|
|
|
Auth::setUser($find_user);
|
|
|
|
$finger_print = $this->createFingerPrint();
|
|
|
|
return redirect('http://localhost:3000/login?token='.$finger_print->token);
|
|
|
|
} catch (Exception $e) {
|
|
dd($e->getMessage());
|
|
}
|
|
}
|
|
|
|
public function emailChecking(Request $request)
|
|
{
|
|
$this->validate($request, [
|
|
'email' => 'required|email',
|
|
]);
|
|
|
|
$user = User::where('email', $request->email)->first();
|
|
|
|
if ($user && $user->has_password) {
|
|
// email exists in db
|
|
// user before set a password
|
|
return response()->json(['message' => 'User exists must be login'], 200);
|
|
}
|
|
|
|
if ($user && !$user->has_password) {
|
|
// email exists in db
|
|
// user hasn't password (we set password for user)
|
|
$this->sendVerification($request->email, 'google');
|
|
return response()->json(['message' => 'Send email for validation'], 200);
|
|
}
|
|
|
|
if (Cache::has($request->email)) {
|
|
// email exists in cache
|
|
$this->sendVerification($request->email, Cache::get($request->email)['type']);
|
|
return response()->json(['message' => 'Send email for validation'], 200);
|
|
}
|
|
|
|
if (!$user && !Cache::has($request->email)) {
|
|
// user not exists in db and cache
|
|
$this->sendVerification($request->email, 'register');
|
|
return response()->json(['message' => 'Send email for validation'], 200);
|
|
}
|
|
}
|
|
|
|
public function login(Request $request)
|
|
{
|
|
// todo: Logging in from a new device will result in sending a notification
|
|
$this->validate($request, [
|
|
'email' => 'required|email|exists:users,email',
|
|
'password' => 'required|string|min:6'
|
|
]);
|
|
|
|
$user = User::where('email', $request->email)->first();
|
|
if ($user && Hash::check($request->password, $user->password)) {
|
|
Auth::setUser($user);
|
|
|
|
return [
|
|
'auth' => $this->createFingerPrint(),
|
|
'businesses' => Auth::user()->businesses->keyBy('id')->map(fn($b, $bid) => Business::info($bid))
|
|
];
|
|
}
|
|
|
|
return new JsonResponse([
|
|
'message' => trans('auth.failed'),
|
|
'status' => Response::HTTP_NOT_FOUND,
|
|
], Response::HTTP_NOT_FOUND);
|
|
}
|
|
|
|
public function verification(Request $request)
|
|
{
|
|
$this->validate($request, [
|
|
'email' => 'required|email',
|
|
'signature' => 'required|string',
|
|
]);
|
|
|
|
$this->checkValidation($request->email, 'google', $request->signature);
|
|
|
|
Auth::setUser(User::where('email', $request->email)->first());
|
|
|
|
return [
|
|
'auth' => $this->createFingerPrint(),
|
|
'businesses' => Auth::user()->businesses->keyBy('id')->map(fn($b, $bid) => Business::info($bid))
|
|
];
|
|
|
|
}
|
|
|
|
public function sendVerification($email, $type)
|
|
{
|
|
$signature = Str::random(30);
|
|
|
|
Cache::put($email, ['type' => $type, 'signature' => $signature], 3600);
|
|
|
|
Notification::route('mail', $email)->notify( new MailNotification([
|
|
'greeting' => __('notification.auth.verification.greeting'),
|
|
'subject' => __('notification.auth.verification.subject'),
|
|
'body' => __('notification.auth.verification.new_body'),
|
|
'link' => __('notification.auth.verification.link', [
|
|
'email' => $email,
|
|
'type' => $type,
|
|
'signature' => $signature
|
|
])
|
|
]));
|
|
|
|
// return $verification_code;
|
|
}
|
|
|
|
public function checkValidation($email, $type, $signature)
|
|
{
|
|
if (!Cache::has($email) || Cache::get($email)['type'] !== $type || Cache::get($email)['signature'] != $signature)
|
|
{
|
|
abort(403, 'Validation failed');
|
|
}
|
|
Cache::forget($email);
|
|
}
|
|
|
|
public function forgetPassword(Request $request)
|
|
{
|
|
$this->validate($request, [
|
|
'email' => 'required|email|exists:users,email'
|
|
]);
|
|
|
|
$this->sendVerification($request->email, 'forget');
|
|
|
|
return response()->json(['message' => 'Send email for validation'], 200);
|
|
}
|
|
|
|
public function updatePassword(Request $request)
|
|
{
|
|
$this->validate($request, [
|
|
'email' => 'required|email',
|
|
'password' => 'required|string|min:8|confirmed',
|
|
'signature' => 'required|string'
|
|
]);
|
|
|
|
$this->checkValidation($request->email, 'forget', $request->signature);
|
|
|
|
$user = User::where('email', $request->email)->first();
|
|
|
|
$user->update([
|
|
'password' => Hash::make($request->password),
|
|
'has_password' => true
|
|
]);
|
|
|
|
Auth::setUser($user);
|
|
|
|
$this->createFingerPrint();
|
|
|
|
return response()->json(['message' => 'Update successfully you must be login.'], 200);
|
|
}
|
|
|
|
public function register(Request $request)
|
|
{
|
|
$this->validate($request, [
|
|
'name' => 'required|string|max:225|min:2',
|
|
'username' => ['required', Rule::unique('users', 'username')],
|
|
'email' => ['required', 'email', Rule::unique('users', 'email')],
|
|
'password' => 'required|string|min:6',
|
|
'signature' => 'required|string'
|
|
]);
|
|
|
|
$this->checkValidation($request->email, 'register', $request->signature);
|
|
|
|
$request->merge(['password' => Hash::make($request->password)]);
|
|
|
|
$user = User::create($request->all()+ [
|
|
'has_password' => true
|
|
]);
|
|
|
|
Auth::setUser($user);
|
|
|
|
$this->createFingerPrint();
|
|
|
|
return response()->json(['message' => 'Register successfully you must be login.'], 200);
|
|
}
|
|
|
|
public function createFingerPrint()
|
|
{
|
|
$attributes = [
|
|
'agent' => request()->getAgent(),
|
|
'ip' => request()->getClientIp(),
|
|
'os' => request()->getOS(),
|
|
'latitude' => \request()->getLocation()->getAttribute('lat'),
|
|
'longitude' => \request()->getLocation()->getAttribute('lon'),
|
|
];
|
|
|
|
$values = [
|
|
'token' => Str::random(60)
|
|
];
|
|
|
|
return Auth::user()->fingerprints()->firstOrCreate($attributes, $attributes + $values);
|
|
}
|
|
}
|