163 lines
6.2 KiB
PHP
163 lines
6.2 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Sponsor;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\Validator;
|
|
use Illuminate\Support\Str;
|
|
|
|
class SponsorAuthController extends Controller
|
|
{
|
|
/**
|
|
* Register a new Sponsor account.
|
|
*
|
|
* Required fields: full_name, mobile, password, license_file
|
|
* Optional: organization_name, email, nationality, city, address, country_code
|
|
*
|
|
* POST /api/sponsors/register
|
|
*/
|
|
public function register(Request $request)
|
|
{
|
|
$validator = Validator::make($request->all(), [
|
|
'full_name' => 'required|string|max:255',
|
|
'mobile' => 'required|string|max:50|unique:sponsors,mobile',
|
|
'password' => 'required|string|min:6',
|
|
'license_file' => 'required|file|mimes:jpeg,png,jpg,pdf|max:10240',
|
|
'organization_name' => 'nullable|string|max:255',
|
|
'email' => 'nullable|email|max:255|unique:sponsors,email',
|
|
'nationality' => 'nullable|string|max:100',
|
|
'city' => 'nullable|string|max:100',
|
|
'address' => 'nullable|string|max:255',
|
|
'country_code' => 'nullable|string|max:10',
|
|
], [
|
|
'mobile.unique' => 'This mobile number is already registered.',
|
|
'email.unique' => 'This email address is already registered.',
|
|
'license_file.required' => 'Please upload your organization or trade license.',
|
|
]);
|
|
|
|
if ($validator->fails()) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Validation error.',
|
|
'errors' => $validator->errors()
|
|
], 422);
|
|
}
|
|
|
|
try {
|
|
// Auto-generate email if not provided
|
|
$mobileClean = preg_replace('/[^0-9]/', '', $request->mobile);
|
|
$email = $request->email ?? "sponsor.{$mobileClean}@migrant.ae";
|
|
if (!$request->email && Sponsor::where('email', $email)->exists()) {
|
|
$email = "sponsor.{$mobileClean}." . rand(10, 99) . "@migrant.ae";
|
|
}
|
|
|
|
// Store license file
|
|
$destinationPath = public_path('uploads/licenses');
|
|
if (!file_exists($destinationPath)) {
|
|
mkdir($destinationPath, 0755, true);
|
|
}
|
|
|
|
$licenseFile = $request->file('license_file');
|
|
$licenseFileName = time() . '_license_' . preg_replace('/[^a-zA-Z0-9_.-]/', '', $licenseFile->getClientOriginalName());
|
|
$licenseFile->move($destinationPath, $licenseFileName);
|
|
$licensePath = 'uploads/licenses/' . $licenseFileName;
|
|
|
|
$apiToken = Str::random(80);
|
|
|
|
$sponsor = DB::transaction(function () use ($request, $email, $licensePath, $apiToken) {
|
|
return Sponsor::create([
|
|
'full_name' => $request->full_name,
|
|
'organization_name' => $request->organization_name,
|
|
'email' => $email,
|
|
'mobile' => $request->mobile,
|
|
'password' => Hash::make($request->password),
|
|
'country_code' => $request->country_code,
|
|
'nationality' => $request->nationality,
|
|
'city' => $request->city,
|
|
'address' => $request->address,
|
|
'license_file' => $licensePath,
|
|
'status' => 'active',
|
|
'is_verified' => false,
|
|
'subscription_status' => 'none',
|
|
'api_token' => $apiToken,
|
|
]);
|
|
});
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Sponsor account registered successfully. Your license is pending admin review.',
|
|
'data' => [
|
|
'sponsor' => $sponsor->makeHidden(['password', 'api_token']),
|
|
'token' => $apiToken,
|
|
]
|
|
], 201);
|
|
|
|
} catch (\Exception $e) {
|
|
logger()->error('Sponsor Registration Failure: ' . $e->getMessage());
|
|
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'An error occurred during registration. Please try again.',
|
|
'error' => app()->environment('local') ? $e->getMessage() : 'Internal Server Error'
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Authenticate a Sponsor and return their bearer token.
|
|
*
|
|
* POST /api/sponsors/login
|
|
*/
|
|
public function login(Request $request)
|
|
{
|
|
$validator = Validator::make($request->all(), [
|
|
'mobile' => 'required|string',
|
|
'password' => 'required|string',
|
|
]);
|
|
|
|
if ($validator->fails()) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Validation error.',
|
|
'errors' => $validator->errors()
|
|
], 422);
|
|
}
|
|
|
|
$sponsor = Sponsor::where('mobile', $request->mobile)->first();
|
|
|
|
if (!$sponsor || !Hash::check($request->password, $sponsor->password)) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Invalid mobile number or password.'
|
|
], 401);
|
|
}
|
|
|
|
if ($sponsor->status === 'suspended') {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Your account has been suspended. Please contact support.'
|
|
], 403);
|
|
}
|
|
|
|
// Rotate token on each login for security
|
|
$apiToken = Str::random(80);
|
|
$sponsor->update([
|
|
'api_token' => $apiToken,
|
|
'last_login_at' => now(),
|
|
]);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Login successful.',
|
|
'data' => [
|
|
'sponsor' => $sponsor->makeHidden(['password', 'api_token']),
|
|
'token' => $apiToken,
|
|
]
|
|
], 200);
|
|
}
|
|
}
|