initializeMobile($request); if ($response !== null) { return $response; } $username = trim((string) $request->post('username', '')); if ($username === '') { $username = trim((string) $request->post('account', '')); } $password = (string) $request->post('password', ''); $inviteCode = trim((string) $request->post('invite_code', '')); if ($username === '' || $password === '') { return $this->mobileError(1001, 'Missing parameters'); } if ($inviteCode === '') { return $this->mobileError(1001, 'Invite code required'); } if (!preg_match('/^1[3-9]\d{9}$/', $username)) { return $this->mobileError(1003, 'Please enter the correct mobile number'); } $phone = $username; $email = ''; if (User::where('username', $username)->find() || User::where('phone', $username)->find()) { return $this->mobileError(2003, 'Account already registered', [ 'already_registered' => true, ]); } $extend = []; $inviterAdmin = Db::name('admin')->field(['id', 'channel_id'])->where('invite_code', $inviteCode)->find(); if (!$inviterAdmin) { return $this->mobileError(2002, 'Invite code does not exist'); } $extend['register_invite_code'] = $inviteCode; $extend['admin_id'] = $inviterAdmin['id']; $channelId = $inviterAdmin['channel_id'] ?? null; if ($channelId === null || $channelId === '' || (int) $channelId <= 0) { return $this->mobileError(2002, 'Invite code not bound to channel'); } $extend['channel_id'] = (int) $channelId; $channelStatus = Db::name('channel')->where('id', (int) $channelId)->value('status'); if (intval($channelStatus) !== 1) { return $this->mobileError(2002, 'Channel disabled'); } $registered = $this->auth->register($username, $password, $phone, $email, 1, $extend); if (!$registered) { $dup = $this->auth->getRegisterDuplicateKind(); if ($dup === 'username' || $dup === 'email' || $dup === 'phone') { return $this->mobileError(2003, 'Account already registered', [ 'already_registered' => true, ]); } return $this->mobileError(2000, (string) $this->auth->getError()); } $loggedIn = $this->auth->login($username, $password, true); if (!$loggedIn) { return $this->mobileError(2000, 'Registered successfully but login failed'); } $this->bindMobileDeviceSession($request); return $this->mobileSuccess($this->buildLoginPayload()); } public function userLogin(Request $request): Response { $response = $this->initializeMobile($request); if ($response !== null) { return $response; } $username = trim((string) $request->post('username', '')); if ($username === '') { $username = trim((string) $request->post('account', '')); } $password = (string) $request->post('password', ''); if ($username === '' || $password === '') { return $this->mobileError(1001, 'Missing parameters'); } $ok = $this->auth->login($username, $password, true); if (!$ok) { return $this->mobileError(1101, 'Incorrect account or password'); } $this->bindMobileDeviceSession($request); return $this->mobileSuccess($this->buildLoginPayload()); } public function tokenRefresh(Request $request): Response { $response = $this->initializeMobile($request); if ($response !== null) { return $response; } $refreshToken = trim((string) $request->post('refresh_token', '')); if ($refreshToken === '') { return $this->mobileError(1001, 'Missing parameters'); } $tokenData = Token::get($refreshToken); if (!$tokenData || $tokenData['type'] !== UserAuth::TOKEN_TYPE . '-refresh' || $tokenData['expire_time'] < time()) { return $this->mobileError(1101, 'Login status has expired'); } $authToken = trim((string) $request->header('auth-token', '')); $userId = filter_var($tokenData['user_id'] ?? 0, FILTER_VALIDATE_INT); if ($userId === false || $userId <= 0) { return $this->mobileError(1101, 'Login status has expired'); } $deviceError = MobileAuthDeviceService::validateUserDeviceSession($authToken, (int) $userId); if ($deviceError !== null) { return $this->mobileError(1101, $deviceError); } $newToken = Random::uuid(); Token::set($newToken, UserAuth::TOKEN_TYPE, (int) $userId, config('buildadmin.user_token_keep_time', 259200)); return $this->mobileSuccess([ 'user-token' => $newToken, 'expires_in' => config('buildadmin.user_token_keep_time', 259200), ]); } private function bindMobileDeviceSession(Request $request): void { if (!$this->auth->isLogin()) { return; } $authToken = trim((string) $request->header('auth-token', '')); if ($authToken === '') { return; } MobileAuthDeviceService::onUserLogin( (int) $this->auth->id, $authToken, $this->auth->getToken(), $this->auth->getRefreshToken() ); } private function buildLoginPayload(): array { $userInfo = $this->auth->getUserInfo(); return [ 'user-token' => $userInfo['token'] ?? '', 'refresh_token' => $userInfo['refresh_token'] ?? '', 'expires_in' => config('buildadmin.user_token_keep_time', 259200), 'user' => [ 'username' => $userInfo['username'] ?? '', 'uuid' => $userInfo['uuid'] ?? '', 'coin' => $userInfo['coin'] ?? '0.00', 'channel_id' => $userInfo['channel_id'] ?? null, 'risk_flags' => $userInfo['risk_flags'] ?? 0, ], ]; } }