824 lines
28 KiB
PHP
Executable File
824 lines
28 KiB
PHP
Executable File
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Helpers\MobileNumberHelper;
|
|
use App\Jobs\SendSMSJob;
|
|
use App\Jobs\SendOTPJob;
|
|
use App\Models\AuthLog;
|
|
use App\Models\PackageName;
|
|
use App\Models\Product;
|
|
use App\Models\Transaction;
|
|
use App\Models\User;
|
|
use App\Rules\MobileNumber;
|
|
use App\Services\CafeService;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Support\Str;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Validation\Rule;
|
|
use Laravel\Socialite\Facades\Socialite;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Facades\Password;
|
|
use Illuminate\Auth\Events\PasswordReset;
|
|
|
|
class UserController extends Controller
|
|
{
|
|
public function requestPasswordReset(Request $request)
|
|
{
|
|
$request->validate([
|
|
'email' => 'required|email',
|
|
]);
|
|
|
|
$status = Password::sendResetLink(
|
|
$request->only('email')
|
|
);
|
|
|
|
if ($status === Password::RESET_LINK_SENT) {
|
|
return response()->json(['message' => __($status)]);
|
|
}
|
|
|
|
return response()->json(['message' => __($status)], 400);
|
|
}
|
|
public function showResetForm($token)
|
|
{
|
|
return view('auth.reset-password', ['token' => $token]);
|
|
}
|
|
|
|
public function resetPassword(Request $request)
|
|
{
|
|
$request->validate([
|
|
'email' => 'required|email',
|
|
'token' => 'required|string',
|
|
'password' => 'required|string|confirmed|min:6',
|
|
]);
|
|
|
|
$status = Password::reset(
|
|
$request->only('email', 'password', 'password_confirmation', 'token'),
|
|
function ($user, $password) {
|
|
$user->forceFill([
|
|
'password' => $password,
|
|
])->setRememberToken(Str::random(60));
|
|
|
|
$user->save();
|
|
|
|
event(new PasswordReset($user));
|
|
}
|
|
);
|
|
|
|
if ($status === Password::PASSWORD_RESET) {
|
|
return response()->json(['message' => __($status)]);
|
|
}
|
|
|
|
return response()->json(['message' => __($status)], 400);
|
|
}
|
|
public function resetPasswordInApp(Request $request)
|
|
{
|
|
$request->validate([
|
|
'email' => 'required|email',
|
|
'password' => 'required|string|confirmed|min:6',
|
|
]);
|
|
|
|
$user = User::where('email', $request->email)->first();
|
|
|
|
if (!$user) {
|
|
return response()->json(['message' => 'کاربری با این ایمیل یافت نشد'], 404);
|
|
}
|
|
if (!$user->email_verified_at) {
|
|
return response()->json(['message' => 'ایمیل شما تایید نشده است'], 403);
|
|
}
|
|
// Update password and remember token
|
|
$user->password = $request->password;
|
|
$user->setRememberToken(Str::random(60));
|
|
$user->save();
|
|
|
|
event(new PasswordReset($user));
|
|
|
|
return response()->json(['message' => 'رمز عبور با موفقیت تغییر یافت']);
|
|
}
|
|
|
|
public function login(Request $request)
|
|
{
|
|
$data = $request->validate([
|
|
'auth' => 'string|required',
|
|
'password' => 'string|required',
|
|
'package_name' => 'string|required',
|
|
'fcm_token' => 'string|nullable'
|
|
]);
|
|
|
|
if (!$packageName = PackageName::where('name', $data['package_name'])->first()) {
|
|
return response()->json(['message' => 'package name not found'], 404);
|
|
}
|
|
|
|
$authType = filter_var($data['auth'], FILTER_VALIDATE_EMAIL) ? 'email' : 'mobile';
|
|
if ($authType == 'mobile') {
|
|
$data['auth'] = MobileNumberHelper::formatMobile($data['auth']);
|
|
}
|
|
|
|
$user = User::where($authType, $data['auth'])->first();
|
|
|
|
if (!$user || !Hash::check($data['password'], $user->password)) {
|
|
AuthLog::record(AuthLog::EVENT_LOGIN_FAILED, [
|
|
'user_id' => $user?->id,
|
|
'mobile' => $authType == 'mobile' ? $data['auth'] : $user?->mobile,
|
|
'email' => $authType == 'email' ? $data['auth'] : $user?->email,
|
|
'package_name' => $packageName->name,
|
|
], $request);
|
|
|
|
return response()->json(['message' => 'رمز عبور اشتباه است'], 404);
|
|
}
|
|
|
|
AuthLog::record(AuthLog::EVENT_LOGIN, [
|
|
'user_id' => $user->id,
|
|
'mobile' => $user->mobile,
|
|
'email' => $user->email,
|
|
'package_name' => $packageName->name,
|
|
], $request);
|
|
|
|
// Attach package if not exists
|
|
if (!$user->packageNames()->where('package_names.id', $packageName->id)->exists()) {
|
|
$user->packageNames()->attach($packageName->id, [
|
|
'tries' => $packageName->tries,
|
|
'fcm_token' => $data['fcm_token'] ?? null,
|
|
]);
|
|
} else {
|
|
$user->packageNames()->updateExistingPivot($packageName->id, [
|
|
'fcm_token' => $data['fcm_token'] ?? null,
|
|
]);
|
|
}
|
|
|
|
$token = $user->createToken('token', $user->is_admin ? ['admin'] : ['user'])->plainTextToken;
|
|
|
|
return response()->json([
|
|
'user' => $user,
|
|
'token' => $token,
|
|
]);
|
|
}
|
|
public function resendEmailVerification(Request $request)
|
|
{
|
|
$data = $request->validate([
|
|
'email' => 'required|email',
|
|
'method' => 'string|in:code,link|nullable',
|
|
'package_name' => 'string|required',
|
|
]);
|
|
|
|
$method = $data['method'] ?? 'link';
|
|
$packageNameValue = $data['package_name'];
|
|
unset($data['package_name']);
|
|
|
|
$user = User::where('email', $data['email'])->first();
|
|
// return response()->json(['message' => $user]);
|
|
|
|
if (!$user) {
|
|
return response()->json(['message' => 'User not found'], 404);
|
|
}
|
|
|
|
if ($user->email_verified_at) {
|
|
return response()->json(['message' => 'Email is already verified'], 400);
|
|
}
|
|
|
|
$code = rand(1000, 9999);
|
|
$token = Str::random(64);
|
|
|
|
\DB::table('email_verifications')->where('user_id', $user->id)->delete();
|
|
|
|
\DB::table('email_verifications')->insert([
|
|
'user_id' => $user->id,
|
|
'code' => $code,
|
|
'token' => $token,
|
|
'expires_at' => now()->addMinutes(15),
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
|
|
try {
|
|
if ($method === 'code') {
|
|
\Mail::to($user->email)->send(new \App\Mail\VerifyEmailCodeMail($code));
|
|
} else {
|
|
$verificationUrl = url("api/auth/verify-email-link/{$token}?package={$packageNameValue}");
|
|
\Mail::to($user->email)->send(new \App\Mail\VerifyEmailLinkMail($verificationUrl));
|
|
}
|
|
} catch (\Exception $e) {
|
|
// rollback verification
|
|
\DB::table('email_verifications')->where('user_id', $user->id)->delete();
|
|
|
|
return response()->json([
|
|
'error' => $e->getMessage(),
|
|
'message' => 'ارسال ایمیل با مشکل مواجه شد، لطفا دوباره تلاش کنید'
|
|
], 400);
|
|
}
|
|
|
|
return response()->json(['message' => 'Verification email resent successfully']);
|
|
}
|
|
|
|
public function register(Request $request)
|
|
{
|
|
$data = $request->validate([
|
|
'first_name' => 'string|nullable',
|
|
'last_name' => 'string|nullable',
|
|
'email' => 'email|required_without:mobile',
|
|
'password' => 'string|nullable|required_with:email',
|
|
'mobile' => ['string', new MobileNumber, 'nullable', 'required_without:email'],
|
|
'fcm_token' => 'string|nullable',
|
|
'package_name' => 'string|required',
|
|
'method' => 'string|in:code,link|nullable',
|
|
'birthday' => 'date|nullable',
|
|
'age' => 'integer|nullable|min:0|max:120',
|
|
'gender' => ['integer', 'nullable', Rule::in(User::GENDERS)],
|
|
'referrer_code' => ['string', 'nullable', 'exists:users,referral_code'],
|
|
]);
|
|
|
|
$method = $data['method'] ?? 'link';
|
|
unset($data['method']);
|
|
|
|
// Extract and remove package_name
|
|
$packageNameValue = $data['package_name'];
|
|
unset($data['package_name']);
|
|
|
|
// Resolve referrer code (کد معرف) to the referring user
|
|
$referrerCode = $data['referrer_code'] ?? null;
|
|
unset($data['referrer_code']);
|
|
if ($referrerCode && $referrer = User::where('referral_code', $referrerCode)->first()) {
|
|
$data['referred_by'] = $referrer->id;
|
|
}
|
|
|
|
if (isset($data['mobile'])) {
|
|
$data['mobile'] = MobileNumberHelper::formatMobile($data['mobile']);
|
|
if (User::where('mobile', $data['mobile'])->exists()) {
|
|
return response()->json(['message' => 'Mobile number already exists'], 400);
|
|
}
|
|
}
|
|
|
|
if (isset($data['email']) && User::where('email', $data['email'])->exists()) {
|
|
return response()->json(['message' => 'Email already exists'], 400);
|
|
}
|
|
|
|
$code = rand(1000, 9999);
|
|
$token = Str::random(64);
|
|
// ✅ Check if email can receive a message before creating the user
|
|
// if (isset($data['email'])) {
|
|
// $code = rand(1000, 9999);
|
|
// try {
|
|
// if ($method === 'code') {
|
|
// \Mail::to($data['email'])->send(new \App\Mail\VerifyEmailCodeMail($code));
|
|
// } else {
|
|
// $verificationUrl = url("api/auth/verify-email-link/{$token}?package={$packageNameValue}");
|
|
// \Mail::to($data['email'])->send(new \App\Mail\VerifyEmailLinkMail($verificationUrl));
|
|
// }
|
|
// } catch (\Exception $e) {
|
|
// return response()->json([
|
|
// 'error' => $e->getMessage(),
|
|
// 'message' => 'لطفا آدرس ایمیل خود را بررسی کنید و مجدد تلاش کنید'
|
|
// ], 400);
|
|
// }
|
|
// try {
|
|
// // Try sending email
|
|
// \Mail::to($data['email'])->send(new \App\Mail\VerifyEmailCodeMail($code));
|
|
// } catch (\Exception $e) {
|
|
// return response()->json([
|
|
// 'code' => $e->getCode(),
|
|
// 'error' => $e->getMessage(),
|
|
// 'message' => 'لطفا آدرس ایمیل خود را بررسی کنید و مجدد تلاش کنید',
|
|
|
|
// ], 400);
|
|
// }
|
|
// }
|
|
|
|
// Hash password
|
|
$data['password'] = isset($data['password'])
|
|
? $data['password']
|
|
: Str::random(8);
|
|
|
|
// Create user only if email sending didn't fail
|
|
$user = User::create($data);
|
|
|
|
// Attach package
|
|
if ($packageName = PackageName::where('name', $packageNameValue)->first()) {
|
|
$user->packageNames()->attach($packageName->id, [
|
|
'tries' => $packageName->tries,
|
|
'fcm_token' => $data['fcm_token'] ?? null,
|
|
]);
|
|
}
|
|
|
|
// Save email verification code after user is created
|
|
// if (isset($data['email'])) {
|
|
\DB::table('email_verifications')->where('user_id', $user->id)->delete();
|
|
\DB::table('email_verifications')->insert([
|
|
'user_id' => $user->id,
|
|
'code' => $code,
|
|
'token' => $token,
|
|
'expires_at' => now()->addMinutes(15),
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
// }
|
|
|
|
AuthLog::record(AuthLog::EVENT_REGISTER, [
|
|
'user_id' => $user->id,
|
|
'mobile' => $user->mobile,
|
|
'email' => $user->email,
|
|
'package_name' => $packageNameValue,
|
|
], $request);
|
|
|
|
// Create token
|
|
$token = $user->createToken('token', $user->is_admin ? ['admin'] : ['user'])->plainTextToken;
|
|
|
|
return response()->json([
|
|
'message' => 'User registered successfully.',
|
|
'user' => $user,
|
|
'token' => $token
|
|
]);
|
|
}
|
|
public function verifyEmailCode(Request $request)
|
|
{
|
|
$request->validate([
|
|
'email' => 'required|email',
|
|
'code' => 'required|string',
|
|
]);
|
|
|
|
$user = User::where('email', $request->email)->first();
|
|
if (!$user) {
|
|
return response()->json(['message' => 'User not found'], 404);
|
|
}
|
|
|
|
$record = \DB::table('email_verifications')
|
|
->where('user_id', $user->id)
|
|
->where('code', $request->code)
|
|
->where('expires_at', '>', now())
|
|
->first();
|
|
|
|
if (!$record) {
|
|
return response()->json(['message' => 'Invalid or expired code'], 400);
|
|
}
|
|
|
|
// Mark email as verified
|
|
$user->update(['email_verified_at' => now()]);
|
|
|
|
// Delete verification record
|
|
\DB::table('email_verifications')->where('id', $record->id)->delete();
|
|
$token = $user->createToken('token', $user->is_admin ? ['admin'] : ['user'])->plainTextToken;
|
|
return response()->json(['message' => 'Email verified successfully', 'token' => $token]);
|
|
}
|
|
public function verifyEmailLink(Request $request, $token)
|
|
{
|
|
$record = \DB::table('email_verifications')
|
|
->where('token', $token)
|
|
->where('expires_at', '>', now())
|
|
->first();
|
|
|
|
if (!$record) {
|
|
return response()->json(['message' => 'Invalid or expired token'], 400);
|
|
}
|
|
|
|
$user = User::find($record->user_id);
|
|
if (!$user) {
|
|
return response()->json(['message' => 'User not found'], 404);
|
|
}
|
|
|
|
$user->update(['email_verified_at' => now()]);
|
|
|
|
\DB::table('email_verifications')->where('id', $record->id)->delete();
|
|
|
|
// Optionally redirect to app deep link
|
|
$packageName = $request->query('package');
|
|
if ($packageName && $package = \App\Models\PackageName::where('name', $packageName)->first()) {
|
|
if ($package->web_app_url) {
|
|
return redirect()->away($package->web_app_url . '?verified=1');
|
|
}
|
|
}
|
|
|
|
// $packageName = $request->query('package') ?? 'default';
|
|
$deepLink = "approagency://{$packageName}?verified=1";
|
|
|
|
return view('emails.verified', [
|
|
'status' => 'success',
|
|
'message' => 'ایمیل شما با موفقیت تایید شد',
|
|
'deepLink' => $deepLink,
|
|
]);
|
|
}
|
|
|
|
public function loginOTP(Request $request)
|
|
{
|
|
$data = $request->validate([
|
|
'mobile' => ['string', new MobileNumber, 'required'],
|
|
'package_name' => 'string|required',
|
|
'source' => [Rule::in(PackageName::SOURCES), 'integer'],
|
|
'fcm_token' => 'string',
|
|
]);
|
|
|
|
if (!$packageName = PackageName::where('name', $data['package_name'])->first()) {
|
|
return response()->json([
|
|
'message' => 'package name not found'
|
|
], 404);
|
|
}
|
|
|
|
if (!$user = User::where('mobile', $data['mobile'])->first()) {
|
|
$user = User::create([
|
|
'mobile' => MobileNumberHelper::formatMobile($data['mobile']),
|
|
'password' => config('app.default_password'),
|
|
]);
|
|
}
|
|
if ($data['mobile'] != config('approo.admin_mobile')) {
|
|
$otpToken = rand(pow(10, 4), pow(10, 5) - 1);
|
|
$user->otpTokens()->create([
|
|
'token' => $otpToken
|
|
]);
|
|
|
|
$verify = Str::random(8);
|
|
SendOTPJob::dispatch($data['mobile'], (string)$otpToken);
|
|
|
|
// Billable verification SMS — logged for the admin SMS/login analytics
|
|
AuthLog::record(AuthLog::EVENT_OTP_SENT, [
|
|
'user_id' => $user->id,
|
|
'mobile' => $user->mobile,
|
|
'email' => $user->email,
|
|
'package_name' => $packageName->name,
|
|
'source' => $data['source'] ?? null,
|
|
], $request);
|
|
// SendSMSJob::dispatch([
|
|
// 'mobile' => $data['mobile'],
|
|
// 'message' => "کد ورود به برنامه: $otpToken
|
|
// @{$packageName->web_app_url} #$otpToken
|
|
// لغو 11"
|
|
// ]);
|
|
}
|
|
|
|
if (!$user->packageNames()->where('package_names.id', $packageName->id)->exists()) {
|
|
$user->packageNames()->attach($packageName->id, [
|
|
'tries' => $packageName->tries,
|
|
'source' => $data['source'] ?? 0,
|
|
'fcm_token' => $data['fcm_token'] ?? null,
|
|
]);
|
|
} else {
|
|
$user->packageNames()->updateExistingPivot($packageName->id, [
|
|
'fcm_token' => $data['fcm_token'] ?? null,
|
|
]);
|
|
}
|
|
|
|
return response()->json([
|
|
'message' => 'otp sent',
|
|
'verify_code' => $verify ?? null
|
|
]);
|
|
}
|
|
|
|
public function checkOTP(Request $request)
|
|
{
|
|
$data = $request->validate([
|
|
'mobile' => ['string', new MobileNumber, 'required'],
|
|
'token' => 'string|required',
|
|
]);
|
|
|
|
if (!$user = User::where('mobile', $data['mobile'])->first()) {
|
|
AuthLog::record(AuthLog::EVENT_OTP_FAILED, [
|
|
'mobile' => MobileNumberHelper::formatMobile($data['mobile']),
|
|
], $request);
|
|
|
|
return response()->json([
|
|
'message' => 'user not found'
|
|
], 404);
|
|
}
|
|
|
|
$otpToken = $user->otpTokens()->where('token', $data['token'])->where('created_at', '>', now()->subMinutes(15))->first();
|
|
if (!$otpToken && !($data['mobile'] == config('approo.admin_mobile') && $data['token'] == config('approo.admin_otp'))) {
|
|
AuthLog::record(AuthLog::EVENT_OTP_FAILED, [
|
|
'user_id' => $user->id,
|
|
'mobile' => $user->mobile,
|
|
'email' => $user->email,
|
|
], $request);
|
|
|
|
return response()->json([
|
|
'message' => 'token not valid'
|
|
], 400);
|
|
}
|
|
$otpToken?->delete();
|
|
|
|
AuthLog::record(AuthLog::EVENT_OTP_VERIFIED, [
|
|
'user_id' => $user->id,
|
|
'mobile' => $user->mobile,
|
|
'email' => $user->email,
|
|
], $request);
|
|
|
|
$token = '';
|
|
if ($user->is_admin) {
|
|
$token = $user->createToken('token', ['admin'])->plainTextToken;
|
|
} else {
|
|
$token = $user->createToken('token', ['user'])->plainTextToken;
|
|
}
|
|
|
|
return response()->json([
|
|
'user' => $user,
|
|
'token' => $token,
|
|
]);
|
|
}
|
|
public function requestMobileVerification(Request $request)
|
|
{
|
|
$data = $request->validate([
|
|
'mobile' => ['required', 'string', new MobileNumber],
|
|
]);
|
|
|
|
$user = auth()->user();
|
|
$mobile = MobileNumberHelper::formatMobile($data['mobile']);
|
|
|
|
// چک اینکه موبایل مال یوزر دیگه نباشه
|
|
if (User::where('mobile', $mobile)
|
|
->where('id', '!=', $user->id)
|
|
->exists()) {
|
|
return response()->json([
|
|
'message' => 'mobile already taken'
|
|
], 400);
|
|
}
|
|
|
|
// حذف otp های قبلی
|
|
$user->otpTokens()->delete();
|
|
|
|
$otp = rand(10000, 99999);
|
|
|
|
$user->otpTokens()->create([
|
|
'token' => $otp
|
|
]);
|
|
|
|
SendOTPJob::dispatch($mobile, (string)$otp);
|
|
|
|
// Billable verification SMS
|
|
AuthLog::record(AuthLog::EVENT_MOBILE_OTP_SENT, [
|
|
'user_id' => $user->id,
|
|
'mobile' => $mobile,
|
|
'email' => $user->email,
|
|
], $request);
|
|
|
|
return response()->json([
|
|
'message' => 'otp sent successfully'
|
|
]);
|
|
}
|
|
public function confirmMobileVerification(Request $request)
|
|
{
|
|
$data = $request->validate([
|
|
'mobile' => ['required', 'string', new MobileNumber],
|
|
'token' => 'required|string'
|
|
]);
|
|
|
|
$user = auth()->user();
|
|
$mobile = MobileNumberHelper::formatMobile($data['mobile']);
|
|
|
|
$otp = $user->otpTokens()
|
|
->where('token', $data['token'])
|
|
->where('created_at', '>', now()->subMinutes(5))
|
|
->first();
|
|
|
|
if (!$otp) {
|
|
AuthLog::record(AuthLog::EVENT_MOBILE_VERIFY_FAILED, [
|
|
'user_id' => $user->id,
|
|
'mobile' => $mobile,
|
|
'email' => $user->email,
|
|
], $request);
|
|
|
|
return response()->json([
|
|
'message' => 'invalid or expired token'
|
|
], 400);
|
|
}
|
|
|
|
$otp->delete();
|
|
|
|
$user->update([
|
|
'mobile' => $mobile,
|
|
'mobile_verified_at' => now(),
|
|
]);
|
|
|
|
AuthLog::record(AuthLog::EVENT_MOBILE_VERIFIED, [
|
|
'user_id' => $user->id,
|
|
'mobile' => $mobile,
|
|
'email' => $user->email,
|
|
], $request);
|
|
|
|
return response()->json([
|
|
'message' => 'mobile verified successfully'
|
|
]);
|
|
}
|
|
public function updateProfile(Request $request)
|
|
{
|
|
$data = $request->validate([
|
|
'first_name' => 'string|nullable',
|
|
'last_name' => 'string|nullable',
|
|
'birthday' => 'date|nullable',
|
|
'age' => 'integer|nullable|min:0|max:120',
|
|
'gender' => ['integer', 'nullable', Rule::in(User::GENDERS)],
|
|
'email' => 'email|nullable',
|
|
'mobile' => [new MobileNumber, 'string'],
|
|
'avatar' => 'image',
|
|
'referrer_code' => ['string', 'nullable', 'exists:users,referral_code'],
|
|
]);
|
|
|
|
// referrer_code (کد معرف) is not a column — resolve it to referred_by below
|
|
$referrerCode = $data['referrer_code'] ?? null;
|
|
unset($data['referrer_code']);
|
|
|
|
$packageNameData = $request->validate([
|
|
'package_name' => 'string',
|
|
'fcm_token' => 'string',
|
|
]);
|
|
|
|
if (isset($data['email'])) {
|
|
$user = User::where('email', $data['email'])->first();
|
|
if ($user && $data['email'] != auth()->user()->email) {
|
|
return response()->json([
|
|
'message' => 'user with given email exists'
|
|
], 400);
|
|
}
|
|
}
|
|
|
|
if (isset($data['mobile'])) {
|
|
$user = User::where('mobile', $data['mobile'])->first();
|
|
if ($user && $data['mobile'] != auth()->user()->mobile) {
|
|
return response()->json([
|
|
'message' => 'user with given email exists'
|
|
], 400);
|
|
}
|
|
}
|
|
if (isset($packageNameData['package_name']) && !$packageName = PackageName::where('name', $packageNameData['package_name'])->first()) {
|
|
return response()->json([
|
|
'message' => 'package name not found'
|
|
], 404);
|
|
}
|
|
|
|
$user = auth()->user();
|
|
if (isset($data['avatar'])) {
|
|
Storage::disk('public')->put("avatars/$user->uuid.png", file_get_contents($data['avatar']->path()));
|
|
$data['avatar'] = "storage/avatars/$user->uuid.png";
|
|
}
|
|
|
|
// Set the referrer (کد معرف) once: only if not already referred, and never self-referral
|
|
if ($referrerCode && !$user->referred_by) {
|
|
$referrer = User::where('referral_code', $referrerCode)->first();
|
|
if ($referrer && $referrer->id === $user->id) {
|
|
return response()->json(['message' => 'you cannot use your own referral code'], 400);
|
|
}
|
|
if ($referrer) {
|
|
$data['referred_by'] = $referrer->id;
|
|
}
|
|
}
|
|
|
|
$user->update($data);
|
|
|
|
if ($packageName ?? null) {
|
|
$user->packageNames()->updateExistingPivot($packageName->id, [
|
|
'fcm_token' => $packageNameData['fcm_token'] ?? null,
|
|
]);
|
|
}
|
|
|
|
return response()->json([
|
|
'user' => $user,
|
|
'message' => 'user updated'
|
|
]);
|
|
}
|
|
|
|
public function logout(Request $request)
|
|
{
|
|
$request->user()->currentAccessToken()->delete();
|
|
|
|
return response()->json([
|
|
'message' => 'user logged out'
|
|
]);
|
|
}
|
|
|
|
public function status(Request $request)
|
|
{
|
|
$data = $request->validate([
|
|
'package_name' => 'string|required'
|
|
]);
|
|
|
|
if (!$packageName = PackageName::with('cafeConfig')->where('name', $data['package_name'])->first()) {
|
|
return response()->json([
|
|
'message' => 'package name not found'
|
|
], 404);
|
|
}
|
|
|
|
$user = auth()->user();
|
|
if ($user->mobile == config('approo.admin_mobile')) {
|
|
$user['products'] = Product::where('package_name_id', $packageName->id)->get();
|
|
} else {
|
|
// if ($packageName->cafeConfig) {
|
|
// $user['products'] = $user->products()->where('package_name_id', $packageName->id)->get();
|
|
// foreach ($user['products'] as $key => $product) {
|
|
// $service = new CafeService($packageName->cafeConfig);
|
|
// if ($product->pivot->gateway == Transaction::GATEWAYS['cafe'] && $product->pivot->purchase_token && $product->type != Product::TYPES['permanent']) {
|
|
// $activeSubscriptions = $service->checkSubscription($product, $product->pivot->purchase_token);
|
|
// if ($activeSubscriptions) {
|
|
// $expire = Carbon::createFromTimestamp($activeSubscriptions[0]['validUntilTimestampMsec'] / 1000);
|
|
// $user->products()->updateExistingPivot($product, ['expire_at' => $expire->format('Y-m-d H:i:s')]);
|
|
// } else {
|
|
// $user->products()->updateExistingPivot($product, ['expire_at' => now()->format('Y-m-d H:i:s')]);
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
$user['products'] = $user->products()
|
|
->where('package_name_id', $packageName->id)
|
|
->where(fn($q) => $q->where('user_product.expire_at', '>', now()->addHour())->orWhere('user_product.expire_at', null))
|
|
->get();
|
|
|
|
$user['package_name'] = $user->packageNames()
|
|
->where('package_names.id', $packageName->id)
|
|
->first();
|
|
}
|
|
|
|
// Expose the referrer's uuid so downstream apps can resolve the
|
|
// referral relationship (کد معرف) against their own local user.
|
|
$user['referrer_uuid'] = $user->referred_by ? optional($user->referrer)->uuid : null;
|
|
|
|
return $user;
|
|
}
|
|
|
|
public function try(Request $request, $name)
|
|
{
|
|
$user = auth()->user();
|
|
|
|
if (!$packageName = $user->packageNames()->where('name', $name)->first()) {
|
|
return response()->json([
|
|
'message' => 'package name not found'
|
|
], 404);
|
|
}
|
|
|
|
if ($packageName->pivot->tries <= 0) {
|
|
return response()->json([
|
|
'message' => 'no more tries'
|
|
], 400);
|
|
}
|
|
|
|
$packageName->pivot->tries->decrement();
|
|
|
|
return response()->json([
|
|
'message' => 'success'
|
|
]);
|
|
}
|
|
|
|
public function googleLogin(Request $request)
|
|
{
|
|
$data = $request->validate([
|
|
'access_token' => 'string|required',
|
|
'package_name' => 'string|required',
|
|
]);
|
|
|
|
if (!$packageName = PackageName::where('name', $data['package_name'])->first()) {
|
|
return response()->json([
|
|
'message' => 'package name not found'
|
|
], 404);
|
|
}
|
|
|
|
$response = Http::get("https://www.googleapis.com/oauth2/v3/userinfo", [
|
|
'access_token' => $data['access_token']
|
|
])->json();
|
|
|
|
if (!isset($response['email'])) {
|
|
return response()->json([
|
|
'message' => 'invalid token'
|
|
], 400);
|
|
}
|
|
|
|
$user = User::where('email', $response['email'])->first();
|
|
|
|
if (!$user) {
|
|
$user = User::create([
|
|
'email' => $response['email'],
|
|
'first_name' => $response['given_name'] ?? null,
|
|
'last_name' => $response['family_name'] ?? null,
|
|
'password' => config('app.default_password'),
|
|
'email_verified_at' => now(),
|
|
]);
|
|
|
|
$user->packageNames()->attach($packageName->id, [
|
|
'tries' => $packageName->tries,
|
|
'source' => $data['source'] ?? 0,
|
|
]);
|
|
} else {
|
|
if (!$user->email_verified_at) {
|
|
$user->update([
|
|
'email_verified_at' => now(),
|
|
]);
|
|
}
|
|
|
|
if (!$user->packageNames()->where('package_names.id', $packageName->id)->exists()) {
|
|
$user->packageNames()->attach($packageName->id, [
|
|
'tries' => $packageName->tries,
|
|
'source' => $data['source'] ?? 0,
|
|
]);
|
|
}
|
|
}
|
|
|
|
AuthLog::record(AuthLog::EVENT_GOOGLE_LOGIN, [
|
|
'user_id' => $user->id,
|
|
'mobile' => $user->mobile,
|
|
'email' => $user->email,
|
|
'package_name' => $packageName->name,
|
|
], $request);
|
|
|
|
$token = $user->createToken('token', ['user'])->plainTextToken;
|
|
|
|
return response()->json([
|
|
'user' => $user,
|
|
'token' => $token,
|
|
]);
|
|
}
|
|
|
|
}
|