|
|
<?php
namespace App\Http\Controllers;
use App\Models\User; use App\Models\Business; use App\Models\Fingerprint; use Illuminate\Support\Str; use Illuminate\Http\Request; use Illuminate\Validation\Rule; use Illuminate\Http\JsonResponse; use App\Http\Resources\UserResource; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Cache; use Laravel\Socialite\Facades\Socialite; use Illuminate\Session\TokenMismatchException; 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->update([ 'active' => true ]);
Auth::setUser($find_user);
} else {
$user = User::create($user->user + [ 'password' => Hash::make('google-login-user'), 'username' => $user->email, 'active' => true ]);
Auth::setUser($user);
} $finger_print = $this->createFingerPrint(); return redirect('http://localhost:3000/login?token='.$finger_print->token);
} catch (Exception $e) { dd($e->getMessage()); } }
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 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:8' ]);
$request->merge(['password' => Hash::make($request->password)]);
$code_data = ['verification_code' => $this->sendVerificationCode()]; $method_data = ['method' => 'registerMain'];
Cache::put($request->email, $request->all() + $code_data + $method_data, 3600); // remain one hour
return \response()->json([ 'message' => 'Code send for user and user must be verified.'], Response::HTTP_OK);
}
public function registerMain($user_info) { $user = User::create($user_info);
Auth::setUser($user);
return $this->createFingerPrint(); }
public function sendVerificationCode($contact_way = null) { $verification_code = 1234; // rand(10001, 99999)
//send code for user with contact way
return $verification_code; }
public function verification(Request $request) { if (!Cache::has($request->email)) { return \response()->json(['message' => 'Code expired.'], Response::HTTP_BAD_REQUEST); }
$user_info = Cache::get($request->email);
$this->validate($request, [ 'email' => 'required|email', 'verification_code' => 'required|string|min:4|max:4|in:'.$user_info['verification_code'] ]);
Cache::forget($request->email);
return isset($user_info['method']) ? call_user_func('self::'.$user_info['method'], $user_info) : \response()->json(['message' => 'Code verified successfully.'], Response::HTTP_OK,); }
public function forgetPassword(Request $request) { $this->validate($request, [ 'email' => 'required|email|exists:users,email' ]);
$code_data = ['verification_code' => $this->sendVerificationCode()];
Cache::put($request->email, $request->all() + $code_data, 3600); // remain one hour
return \response()->json([ 'message' => 'Code send for user and user must be verified.'], Response::HTTP_OK); }
public function updatePassword(Request $request) { if (!Cache::has($request->email)) { return \response()->json(['message' => 'Code expired.'], Response::HTTP_BAD_REQUEST); }
$this->validate($request, [ 'email' => 'required|email', 'password' => 'required|string|min:8|confirmed', 'verification_code' => 'required|string|min:4|max:4|in:'.Cache::get($request->email)['verification_code'] ]);
$user = User::where('email', $request->email)->first();
$user->update([ 'password' => Hash::make($request->password) ]);
Auth::setUser($user);
return $this->createFingerPrint(); }
/** * @param Request $request * @return mixed * @throws TokenMismatchException */ public function logout(Request $request) { $token = $request->bearerToken();
if (blank($token)) { return new JsonResponse([ 'message' => 'Not authorized request.', 'status' => Response::HTTP_UNAUTHORIZED ]); }
/** @var Fingerprint $token */ $token = Auth::user()->fingerprints()->firstWhere([ 'token' => $token, ]);
if ($token) { return $token->delete(); }
throw new TokenMismatchException('Invalid token!'); }
/** * @param string $token * @throws TokenMismatchException */ public function revoke(string $token) { /** @var Fingerprint $token */ $token = Fingerprint::firstWhere([ 'token' => $token, ]);
if ($token) { return $token->delete(); }
throw new TokenMismatchException(); }
public function auth() { return new UserResource(Auth::user()); }
public function authWithInfo() { return [ 'auth' => new UserResource(Auth::user()), 'businesses' => Auth::user()->businesses->keyBy('id') ->map(fn($b, $bid) => Business::info($bid)) ]; }
public function delete(Request $request) { Auth::user()->fingerprints()->delete(); unset(Auth::user()->token); Auth::user()->delete();
return 'success'; }
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); } }
|