|
|
<?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); } }
|