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(\request('email'), 'register')]; $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, $type) { $verification_code = rand(10001, 99999); Notification::route('mail', $contact_way)->notify( new MailNotification([ 'greeting' => __('notification.auth.verification.greeting'), 'subject' => __('notification.auth.verification.subject'), 'body' => __('notification.auth.verification.body', ['code' => $verification_code]), 'link' => __('notification.auth.verification.link', ['email' => $contact_way, 'type' => $type]), ])); 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); if (isset($user_info['method'])) { Cache::forget($request->email); return call_user_func('self::'.$user_info['method'], $user_info); } return \response()->json(['message' => 'Code verified successfully.'], Response::HTTP_OK,); // 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(\request('email', 'forget'))]; 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); Cache::forget($request->email); 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 updateFcmToken(Request $request) { Auth::user()->fingerprints()->where( [ ['agent', request()->getAgent()], ['ip', request()->getClientIp()], ['os', request()->getOS()], ['latitude', \request()->getLocation()->getAttribute('lat')], ['longitude', \request()->getLocation()->getAttribute('lon')], ] )->firstOrFail()->update([ 'fcm_token' => $request->fcm_token ]); return $this->authWithInfo(); } 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); } }