<?php
namespace App\Http\Controllers\User;
use Exception;
use Carbon\Carbon;
use App\Models\User;
use Illuminate\Support\Str;
use Jenssegers\Agent\Agent;
use App\Models\UserLoginLog;
use Illuminate\Http\Request;
use App\Models\TemporaryData;
use App\Constants\GlobalConst;
use App\Models\MerchantApiKey;
use Illuminate\Cache\RateLimiter;
use Illuminate\Http\JsonResponse;
use Illuminate\Auth\Events\Lockout;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
class LoginController extends Controller
{
protected $request_data;
protected $lockoutTime = 1;
protected $cache;
/**
* Method for view show login form page
* @param Illuminate\Http\Request $request
*/
public function showLoginPage(Request $request,$order_id){
$page_title = "Login Page";
$data = TemporaryData::where('identifier',$order_id)->first();
if(!$data) return back()->with(['error' => ['Order not found.']]);
if (Carbon::parse($data->data->expiration) < Carbon::now()) {
$data->delete();
return redirect()->away($data->data->cancel_url)->with(['error'=> ['Sorry! Link is expired.']]);
}
if(auth()->check()){
$user = auth()->user();
$update_data = [
'merchant_api_key' => [
'client_id' => $data->data->merchant_api_key->client_id,
'secret_id' => $data->data->merchant_api_key->secret_id,
'env' => $data->data->merchant_api_key->env,
'stripe_secret' => $data->data->merchant_api_key->stripe_secret
],
'merchant_account' => [
'name' => $data->data->merchant_account->name,
'merchant_id' => $data->data->merchant_account->merchant_id
],
'expiration' => $data->data->expiration,
'amount' => $data->data->amount,
'fixed_charge' => $data->data->fixed_charge,
'percent_charge' => $data->data->percent_charge,
'total_charge' => $data->data->total_charge,
'total_payable' => $data->data->total_payable,
'currency' => $data->data->currency,
'success_url' => $data->data->success_url,
'cancel_url' => $data->data->cancel_url,
'token' => $data->data->token
];
$data->update([
'data' => $update_data
]);
$user->update([
'two_factor_verified' => false,
]);
$this->createLoginLog($user);
return redirect()->route('order.checkout.index',$order_id);
}else{
return view('order.auth.login',compact(
'page_title',
'data'
));
}
}
/**
* Method for user login with order id
* @param $order_id
* @param Illuminate\Http\Request $request
*/
public function submit(Request $request,$order_id){
$data = TemporaryData::where('identifier',$order_id)->first();
if(!$data) return back()->with(['error' => ['Data not found!']]);
$this->validateLogin($request);
if (method_exists($this, 'hasTooManyLoginAttempts') &&
$this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
if ($request->hasSession()) {
$request->session()->put('auth.password_confirmed_at', time());
}
return $this->sendLoginResponse($request,$data);
}
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
/**
* Attempt to log the user into the application.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function attemptLogin($request)
{
return $this->guard()->attempt(
$this->credentials($request), $request->boolean('remember')
);
}
/**
* Get the guard to be used during authentication.
*
* @return \Illuminate\Contracts\Auth\StatefulGuard
*/
protected function guard()
{
return Auth::guard("web");
}
/**
* Validate the user login request.
*
* @param \Illuminate\Http\Request $request
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
protected function validateLogin($request)
{
$this->request_data = $request;
$request->validate([
'credentials' => 'required|string',
'password' => 'required|string',
]);
// if user exists with banner
if(User::where($this->username(),$request->credentials)->where('status',GlobalConst::BANNED)->exists()) {
throw ValidationException::withMessages([
'credentials' => 'Your account has been suspended!',
]);
}
}
/**
* Get the login username to be used by the controller.
*
* @return string
*/
public function username()
{
$request = $this->request_data->all();
$credentials = $request['credentials'];
if(filter_var($credentials,FILTER_VALIDATE_EMAIL)) {
return "email";
}
return "username";
}
/**
* Get the needed authorization credentials from the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function credentials(Request $request)
{
$request->merge(['status' => true]);
$request->merge([$this->username() => $request->credentials]);
return $request->only($this->username(), 'password','status');
}
/**
* Send the response after the user was authenticated.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
protected function sendLoginResponse($request,$order)
{
$request->session()->regenerate();
$this->clearLoginAttempts($request);
if ($response = $this->authenticated($request, $this->guard()->user(),$order)) {
return $response;
}
return $request->wantsJson()
? new JsonResponse([], 204)
: redirect()->intended($this->redirectPath());
}
/**
* Clear the login locks for the given user credentials.
*
* @param \Illuminate\Http\Request $request
* @return void
*/
protected function clearLoginAttempts(Request $request)
{
$this->limiter()->clear($this->throttleKey($request));
}
/**
* Fire an event when a lockout occurs.
*
* @param \Illuminate\Http\Request $request
* @return void
*/
protected function fireLockoutEvent($request)
{
event(new Lockout($request));
}
/**
* Get the throttle key for the given request.
*
* @param \Illuminate\Http\Request $request
* @return string
*/
protected function throttleKey(Request $request)
{
return Str::transliterate(Str::lower($request->input($this->username())).'|'.$request->ip());
}
/**
* Get the rate limiter instance.
*
* @return \Illuminate\Cache\RateLimiter
*/
protected function limiter()
{
return app(RateLimiter::class);
}
/**
* Increment the login attempts for the user.
*
* @param \Illuminate\Http\Request $request
* @return void
*/
protected function incrementLoginAttempts($request)
{
$this->limiter()->hit(
$this->throttleKey($request), $this->decayMinutes() * 60
);
}
/**
* Increment the counter for a given key for a given decay time.
*
* @param string $key
* @param int $decaySeconds
* @return int
*/
public function hit($key, $decaySeconds = 60)
{
$key = $this->cleanRateLimiterKey($key);
$this->cache->add(
$key.':timer', $this->availableAt($decaySeconds), $decaySeconds
);
$added = $this->cache->add($key, 0, $decaySeconds);
$hits = (int) $this->cache->increment($key);
if (! $added && $hits == 1) {
$this->cache->put($key, 1, $decaySeconds);
}
return $hits;
}
/**
* Get the number of minutes to throttle for.
*
* @return int
*/
public function decayMinutes()
{
return property_exists($this, 'decayMinutes') ? $this->decayMinutes : 1;
}
/**
* Get the failed login response instance.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*
* @throws \Illuminate\Validation\ValidationException
*/
protected function sendFailedLoginResponse($request)
{
throw ValidationException::withMessages([
"credentials" => [trans('auth.failed')],
]);
}
/**
* The user has been authenticated.
*
* @param \Illuminate\Http\Request $request
* @param mixed $user
* @return mixed
*/
protected function authenticated(Request $request, $user,$order)
{
$order_data = TemporaryData::where('identifier',$order->identifier)->first();
$update_data = [
'merchant_api_key' => [
'client_id' => $order_data->data->merchant_api_key->client_id,
'secret_id' => $order_data->data->merchant_api_key->secret_id,
'env' => $order_data->data->merchant_api_key->env,
'stripe_secret' => $order_data->data->merchant_api_key->stripe_secret,
],
'merchant_account' => [
'name' => $order_data->data->merchant_account->name,
'merchant_id' => $order_data->data->merchant_account->merchant_id
],
'expiration' => $order_data->data->expiration,
'amount' => $order_data->data->amount,
'fixed_charge' => $order_data->data->fixed_charge,
'percent_charge' => $order_data->data->percent_charge,
'total_charge' => $order_data->data->total_charge,
'total_payable' => $order_data->data->total_payable,
'currency' => $order_data->data->currency,
'success_url' => $order_data->data->success_url,
'cancel_url' => $order_data->data->cancel_url,
'token' => $order_data->data->token
];
$order_data->update([
'data' => $update_data
]);
$user->update([
'two_factor_verified' => false,
]);
$this->createLoginLog($user);
$this->refreshMerchant($user);
return redirect()->intended(route('order.checkout.index',$order_data->identifier));
}
/**
* Method for create login logs
*/
protected function createLoginLog($user) {
$client_ip = request()->ip() ?? false;
$location = geoip()->getLocation($client_ip);
$agent = new Agent();
$mac = "";
$data = [
'user_id' => $user->id,
'ip' => $client_ip,
'mac' => $mac,
'city' => $location['city'] ?? "",
'country' => $location['country'] ?? "",
'longitude' => $location['lon'] ?? "",
'latitude' => $location['lat'] ?? "",
'timezone' => $location['timezone'] ?? "",
'browser' => $agent->browser() ?? "",
'os' => $agent->platform() ?? "",
];
try{
UserLoginLog::create($data);
}catch(Exception $e) {
// return false;
}
}
/**
* refresh merchant info
*/
protected function refreshMerchant($user){
$data = MerchantApiKey::where('user_id',$user->id)->first();
if(!$data){
$merchant['user_id'] = $user->id;
$merchant['client_id'] = generate_unique_string_number();
$merchant['secret_id'] = generate_unique_string_number();
$merchant['env'] = global_const()::ENV_SANDBOX;
try{
MerchantApiKey::insert($merchant);
}catch(Exception $e){
throw new Exception("Failed to create merchant! Please try again.");
}
}
}
}
Payment Accept
Our platform simplifies payment acceptance, making transaction management effortless. With secure processing and user-friendly tools, you can easily handle payments from credit cards, debit cards, and digital methods. Our intuitive interface is designed for efficiency, ensuring a seamless experience for both you and your customers. Manage your transactions with ease and confidence.