File: /var/www/console.fixgini.com/app/Http/Controllers/Authentication/Pin.php
<?php
namespace App\Http\Controllers\Authentication;
use App\Models\Gig;
use App\Models\Shop;
use App\Models\User;
use App\Models\UserPin;
use App\Models\SellerNin;
use App\Models\UserActivity;
use App\Services\OtpService;
use Illuminate\Http\Request;
use App\Services\ActivityLogger;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Http;
class Pin extends Controller
{
// Set PIN for first timer
public function setupPin(Request $request)
{
try {
$validatedData = $request->validate([
'user_id' => 'required|exists:users,id',
'pin' => 'required|digits:4',
'device_name' => 'required|string',
]);
$hashedPin = Hash::make($validatedData['pin']);
// Update or create the user PIN
$userPin = UserPin::updateOrCreate(
['user_id' => $validatedData['user_id']],
[
'pin' => $hashedPin,
'status' => 'active'
]
);
$user = User::find($validatedData['user_id']);
$user->update([
'is_pin' => 1,
]);
// Log the activite
$device = $validatedData['device_name'];
$activityLogger = app(ActivityLogger::class);
$activityLogger->log('User set PIN from mobile phone (API)', $user->id, $user->role, $device);
return response()->json(['status' => 'success', 'message' => 'PIN set successfully'], 200);
} catch (\Throwable $th) {
Log::info($th->getMessage());
return response()->json(['status' => 'error', 'message' => 'Unable to set PIN. ' . $th->getMessage()], 400);
}
}
// Login PIN
public function loginPin(Request $request)
{
try {
$validatedData = $request->validate([
'pin' => 'required|digits:4',
'user_id' => 'required|exists:users,id',
'device_name' => 'required',
'ip_address' => 'required',
]);
// Check if the user pin exists and is valid
$userPin = UserPin::where('user_id', $validatedData['user_id'])->first();
if (!$userPin || !Hash::check($validatedData['pin'], $userPin->pin)) {
return response()->json(['status' => 'error', 'message' => 'Your PIN in incorrecct'], 401);
}
// Check if the user exists and is active
$user = User::where('id', $validatedData['user_id'])->where('status', 'active')->first();
if ($user) {
// return $user;
$ip = $validatedData['ip_address'];
$location = $this->getLocation($ip);
$activityIp = UserActivity::where('user_id', $user->id)->first();
$location = ($activityIp && $activityIp === $ip) ? $activityIp : $this->getLocation($ip);
//if user city or state is null make the call
if ($user->city == null) {
$location = $this->getLocation($ip);
}
// Update user's location
$user->latitude = $location['latitude'] ?? $user->latitude;
$user->longitude = $location['longitude'] ?? $user->longitude;
$user->save();
// Check if the user has a shop
$shop = Shop::where('user_id', $user->id)->exists();
// Create a token
$token = $user->createToken('api_token')->plainTextToken;
// Log the activity
$device = $validatedData['device_name'];
$activityLogger = app(ActivityLogger::class);
$activityLogger->log('User confirmed and logged in from mobile phone (API)', $user->id, $user->role, $device);
// update device_token
// $this->updateDeviceToken($user, $validatedData['device_token']);
$isNin = SellerNin::where('user_id', $user->id)->exists();
} else {
return response()->json(['status' => 'error', 'message' => 'Your account is inactive'], 404);
}
// Return a successful response
return response()->json([
'status' => 'success',
'message' => 'Welcome back',
'token' => $token,
'is_shop' => $shop ?? [],
'user' => $user,
'is_nin' => $isNin,
], 200);
} catch (\Throwable $th) {
Log::error($th->getMessage());
return response()->json(['status' => 'error', 'message' => 'Unable to confirm PIN. ' . $th->getMessage()], 400);
}
}
// Location
private function getLocation($ip)
{
try {
$clientIp = $ip;
$apiKey = env('IP2LOCATION_API_KEY');
$response = Http::get("https://api.ip2location.io/?key={$apiKey}&ip={$clientIp}&format=json");
if ($response->successful()) {
return $data = $response->json();
}
} catch (\Exception $e) {
Log::error('Location fetching error: ' . $e->getMessage());
}
}
// Forget PIN
public function forgetPin(Request $request)
{
try {
$validatedData = $request->validate([
'user_id' => 'required|exists:users,id',
'password' => 'required',
'email' => 'required|email|exists:users,email',
'device_name' => 'required',
]);
$user = User::find($validatedData['user_id']);
if ($user) {
if (!Hash::check($validatedData['password'], $user->password)) {
return response()->json(['status' => 'error', 'message' => 'Invalid password'], 401);
}
// Email OTP Services
$otpService = app(OtpService::class);
$otpService->sendOtpToEmail($validatedData['email']);
// Log the activity
$device = $validatedData['device_name'];
$activityLogger = app(ActivityLogger::class);
$activityLogger->log('User requested PIN reset from mobile phone (API)', $user->id, $user->role, $device);
return response()->json(['status' => 'success', 'message' => 'Email confirmation code sent successfully to your email.'], 200);
} else {
return response()->json(['status' => 'error', 'message' => 'User not found. Unable to send OTP'], 404);
}
} catch (\Throwable $th) {
Log::info($th->getMessage());
return response()->json(['status' => 'error', 'message' => 'Please try again later ' . $th->getMessage()], 400);
}
}
// Change PIN
public function setNewPin(Request $request)
{
try {
// Validate the input data
$validatedData = $request->validate([
'user_id' => 'required|exists:users,id',
'token' => 'required|numeric|exists:otp_verifications,otp|digits:6',
'new_pin' => 'required|digits:4',
'device_name' => 'required',
]);
// Find the user and their PIN entry
$user = User::find($validatedData['user_id']);
$userPin = UserPin::where('user_id', $validatedData['user_id'])->first();
// Check if the new PIN is the same as the current PIN
if (Hash::check($validatedData['new_pin'], $userPin->pin)) {
return response()->json(['status' => 'error', 'message' => 'You have used this PIN before. Please choose a different PIN.'], 400);
}
// Hash the new PIN and update the record
$newHashedPin = Hash::make($validatedData['new_pin']);
$userPin->update(['pin' => $newHashedPin]);
// Log the activity
$device = $validatedData['device_name'];
$activityLogger = app(ActivityLogger::class);
$activityLogger->log('User changed PIN from mobile phone (API)', $user->id, $user->role, $device);
return response()->json(['status' => 'success', 'message' => 'PIN changed successfully'], 200);
} catch (\Throwable $th) {
Log::info($th->getMessage());
return response()->json(['status' => 'error', 'message' => 'Unable to change PIN. ' . $th->getMessage()], 400);
}
}
}