['string', 'reg' => '/^([a-z0-9\.]{1,13})$|^(0x[a-z0-9]{40})$|^[a-zA-Z0-9]{34}$/i', 'desc' => 'eos账号|eth账号|tron账号'], ]; Param::checkParam2($rules, $args); $random = Account::getRandom($args['account']); Response::success($random); } /** * 获取随机数【不需要登录】 * @author benzhan */ public function actionRandom2($args) { $rules = [ 'account' => ['string', 'reg' => '/^([a-z0-9\.]{1,13})$|^(0x[a-z0-9]{40})$|^[a-zA-Z0-9]{34}$/i', 'desc' => 'eos账号|eth账号'], ]; Param::checkParam2($rules, $args); $random = Account::getRandom($args['account'], true); Response::success($random); } private function _getUserBaseInfo($user_id) { $objUserInfo = new TableHelper('user_info', 'dw_chat'); $row = $objUserInfo->getRow(['user_id' => $user_id], ['_field' => 'user_id, user_name, nick_name, cover_photo']); return $row; } /** * Eos账号登录【不需要登录】 * @author benzhan */ public function actionEosLogin($args, $orginStr = null) { $rules = [ 'account' => ['string', 'reg' => '/^[a-z0-9\.]{1,13}$/', 'desc' => 'eos账号'], 'pubkey' => ['string', 'nullable' => true, '公钥'], 'authority' => ['string', 'nullable' => true, 'enum' => ['owner', 'active'], '权限'], 'sign' => ['string', 'desc' => '私钥加密后的签名'] ]; Param::checkParam2($rules, $args); $info = User::getInfo(); if ($info) { $info['info'] = $this->_getUserBaseInfo($info['user_id']); return $info; } if (!$args['pubkey'] && $args['authority']) { $args['pubkey'] = $this->_getPublicKey($args['account'], $args['authority']); } if (!$args['pubkey']) { Response::error(CODE_PARAM_ERROR, 'pubkey is empty.'); } $account = $args['account']; if ($orginStr) { $data = $orginStr; } else { $data = Account::getRandom($account); if (!$data) { Response::error(CODE_NO_PERMITION, 'can not find random data, please refresh.'); } } $flag = false; try { $flag = Account::verifyMsg($args['pubkey'], $account, $data, $args['sign']); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } if ($flag) { $user_id = User::login($args['account'], Account::TYPE_EOS); $info = Account::setCookie($user_id); $info['info'] = $this->_getUserBaseInfo($info['user_id']); return $info; } else { if ($orginStr) { return false; } else { Response::error(CODE_NORMAL_ERROR, 'Verify failure, please retry.'); } } } /** * 校验登录 (合约方式 * @author solu * @param $args * @return array */ public function actionEosLogin2($args) { $netIds = Eos::getAllNet(); $rules = [ 'account' => ['string', 'reg' => '/^[a-z0-9\.]{1,13}$/', 'desc' => 'eos账号'], 'access_token' => ['string', 'len' => 36, 'desc' => 'access_token'], 'trx_id' => ['string', 'desc' => '交易id'], 'group_id' => ['int', 'nullable' => true, 'desc' => '群id'], 'net_id' => ['int', 'enum' => $netIds, 'nullable' => true, 'default' => Eos::NET_EOS, 'desc' => '网络类型,1:EOS, 2:MeetOne'], ]; Param::checkParam2($rules, $args); if ($args['net_id'] == Eos::NET_EOS) { $objSync = new Sync_LoginLog(); } else { $objSync = new Sync_LoginLogMeetOne(); } $objLoginLog = new TableHelper('login_log', 'dw_chat'); $_where = ['trx_id' => $args['trx_id']]; $row = $objLoginLog->getRow($_where); $maxTry = 3; $i = 0; // 没有数据请求同步再尝试 while ($i < $maxTry && !$row) { sleep($i + 1); $objSync->pubSubscribe(); $row = $objLoginLog->getRow($_where); $i++; } if (!$row) { Response::error(CODE_NORMAL_ERROR, 'trx_id not in log!'); } $account = $args['account']; $random = Account::getRandom($account); if (!$random) { Response::error(CODE_NORMAL_ERROR, 'can not find random data, please refresh.'); } if ($row['account'] != $account) { Response::error(CODE_NORMAL_ERROR, 'account unmatch'); } if ($random != $row['memo']) { Response::error(CODE_NORMAL_ERROR, 'random unmatch'); } $data = []; try { $data = Account::verifyPlayer($row['account'], $random, $args['access_token'], $args['net_id']); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } // 带群id检测是否加入群 if ($args['group_id']) { try { (new GroupInfo())->joinGroup($data['user_id'], $args['group_id']); } catch (Exception $e) { var_log($e->getMessage()); } } return $data; } private function _getPublicKey($account, $authority) { $accountInfo = EosBase::getAccount($account); $accountInfo = json_decode($accountInfo, true); foreach ($accountInfo['permissions'] as $p) { if ($p['perm_name'] == $authority) { return $p['required_auth']['keys'][0]['key']; } } return null; } /** * Eos账号绑定 * @author benzhan */ public function actionEosBind($args) { $rules = [ 'account' => ['string', 'reg' => '/^[a-z0-9\.]{1,13}$/', 'desc' => 'eos账号'], 'pubkey' => ['string', '公钥'], 'sign' => ['string', 'desc' => '私钥加密后的签名'], ]; Param::checkParam2($rules, $args); $account = $args['account']; $data = Account::getRandom($account); if (!$data) { Response::error(CODE_NO_PERMITION, 'can not find random data, please refresh.'); } $flag = Account::verifyMsg($args['pubkey'], $account, $data, $args['sign']); if ($flag) { $user_id = User::getUserId(); User::bind($user_id, $args['account'], Account::TYPE_EOS); } else { Response::error(CODE_NORMAL_ERROR, 'Verify failure, please retry.'); } } /** * Eos账号绑定(合约方式 * @author solu * @author benzhan */ public function actionEosBind2($args) { $netIds = Eos::getAllNet(); $rules = [ 'account' => ['string', 'reg' => '/^[a-z0-9\.]{1,13}$/', 'desc' => 'eos账号'], 'access_token' => ['string', 'len' => 36, 'desc' => 'access_token'], 'trx_id' => ['string', 'desc' => '交易id'], 'net_id' => ['int', 'enum' => $netIds, 'nullable' => true, 'default' => Eos::NET_EOS, 'desc' => '网络类型,1:EOS, 2:MeetOne'], ]; Param::checkParam2($rules, $args); if ($args['net_id'] == Eos::NET_EOS) { $objSync = new Sync_LoginLog(); } else { $objSync = new Sync_LoginLogMeetOne(); } $objLoginLog = new TableHelper('login_log', 'dw_chat'); $_where = ['trx_id' => $args['trx_id']]; $row = $objLoginLog->getRow($_where); $maxTry = 3; $i = 0; // 没有数据请求同步再尝试 while ($i < $maxTry && !$row) { sleep($i + 1); $objSync->pubSubscribe(); $row = $objLoginLog->getRow($_where); $i++; } if (!$row) { Response::error(CODE_NORMAL_ERROR, 'trx_id not in log!'); } $account = $args['account']; $random = Account::getRandom($account); if (!$random) { Response::error(CODE_NORMAL_ERROR, 'can not find random data, please refresh.'); } if ($row['account'] != $account) { Response::error(CODE_NORMAL_ERROR, 'account unmatch'); } if ($random != $row['memo']) { Response::error(CODE_NORMAL_ERROR, 'random unmatch'); } try { Account::verifyEosOnly($account, $random, $args['access_token']); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } $user_id = User::getUserId(); $accountType = Eos::getNetAccount($args['net_id']); User::bind($user_id, $account, $accountType); } /** * Eth账号登录【不需要登录】 * @author solu */ public function actionEthLogin($args) { $rules = [ 'account' => ['string', 'reg' => '/^0x[a-z0-9]{40}$/i', 'desc' => 'eos账号'], 'sign' => ['string', 'desc' => '私钥加密后的签名'] ]; Param::checkParam2($rules, $args); $info = User::getInfo(); if ($info) { return $info; } $account = $args['account']; $data = Account::getRandom($account); if (!$data) { Response::error(CODE_NO_PERMITION, 'can not find random data, please refresh.'); } $flag = false; try { $flag = Account::verifyEth($args['account'], $data, $args['sign']); } catch (Exception $e) {} if (!$flag) { Response::error(CODE_NORMAL_ERROR, 'Verify failure, please retry.'); } $user_id = User::login($args['account'], Account::TYPE_ETH); return Account::setCookie($user_id); } /** * ETH账号绑定 * @author solu * @param $args */ public function actionEthBind($args) { $rules = [ 'account' => ['string', 'reg' => '/^0x[a-z0-9]{40}$/i', 'desc' => 'eos账号'], 'sign' => ['string', 'desc' => '私钥加密后的签名'] ]; Param::checkParam2($rules, $args); $account = $args['account']; $data = Account::getRandom($account); if (!$data) { Response::error(CODE_NO_PERMITION, 'can not find random data, please refresh.'); } $flag = false; try { $flag = Account::verifyEth($args['account'], $data, $args['sign']); } catch (Exception $e) {} if (!$flag) { Response::error(CODE_NORMAL_ERROR, 'Verify failure, please retry.'); } $user_id = User::getUserId(); User::bind($user_id, $account, Account::TYPE_ETH); } /** * Tron账号登录【不需要登录】 * @param $args * @return array */ public function actionTronLogin($args) { $rules = [ 'account' => ['string', 'reg' => '/^[a-zA-Z0-9]{34}$/', 'desc' => 'tron账号'], 'sign' => ['string', 'desc' => '私钥加密后的签名'] ]; Param::checkParam2($rules, $args); $info = User::getInfo(); if ($info) { return $info; } $account = $args['account']; $data = Account::getRandom($account); if (!$data) { Response::error(CODE_NO_PERMITION, 'can not find random data, please refresh.'); } $flag = false; try { $flag = Account::verifyTron($args['account'], $data, $args['sign']); } catch (Exception $e) {} if (!$flag) { Response::error(CODE_NORMAL_ERROR, 'Verify failure, please retry.'); } $user_id = User::login($args['account'], Account::TYPE_TRON); return Account::setCookie($user_id); } /** * Tron账号绑定 * @author solu * @param $args */ public function actionTronBind($args) { $rules = [ 'account' => ['string', 'reg' => '/^[a-zA-Z0-9]{34}$/', 'desc' => 'tron账号'], 'sign' => ['string', 'desc' => '私钥加密后的签名'] ]; Param::checkParam2($rules, $args); $account = $args['account']; $data = Account::getRandom($account); if (!$data) { Response::error(CODE_NO_PERMITION, 'can not find random data, please refresh.'); } $flag = false; try { $flag = Account::verifyTron($args['account'], $data, $args['sign']); } catch (Exception $e) {} if (!$flag) { Response::error(CODE_NORMAL_ERROR, 'Verify failure, please retry.'); } $user_id = User::getUserId(); User::bind($user_id, $account, Account::TYPE_TRON); } /** * 解绑账号 * @author solu * @param $args */ public function actionUnbind($args) { $typeRule = array_keys(Account::getAllType()); $rules = [ 'type' => ['string', 'enum' => $typeRule, 'desc' => '类型 eos,eth, tron'], ]; Param::checkParam2($rules, $args); $userId = User::getUserId(); try { User::unbind($userId, $args['type']); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } } /** * 修改用户名【只能修改一次】 * @author benzhan */ public function actionChangeUserName($args) { $rules = [ 'user_name' => ['string', 'reg' => '/^[a-zA-Z_0-9]{5,20}$/i', 'desc' => '用户名'], ]; Param::checkParam2($rules, $args); $user_id = User::getUserId(); User::saveInfo($user_id, $args); } /** * 修改昵称 * @author benzhan */ public function actionChangeNickName($args) { $rules = [ 'nick_name' => ['string', 'len' => [1, 20], 'desc' => '用户名'], ]; Param::checkParam2($rules, $args); $user_id = User::getUserId(); User::saveInfo($user_id, $args); User::setUserNameById($user_id, $args['nick_name']); } /** * 修改头像 * @author benzhan */ public function actionChangePhoto($args) { $args = array_merge($args, $_FILES); $rules = [ 'cover_photo' => ['array', 'desc' => '头像文件'], ]; Param::checkParam2($rules, $args); $file = $args['cover_photo']; $cover_photo = ''; try { $cover_photo = (new FileUrl())->getFileUrl($file['tmp_name'], $file['name'], $file['type'], true); } catch (Exception $e) { Response::error($e->getCode(), $e->getMessage()); } $user_id = User::getUserId(); User::saveInfo($user_id, compact('cover_photo')); } /** * 第三方账号的是否可见 * @author benzhan */ public function actionSetVisible($args) { $types = array_keys(Account::getAllType()); $rules = [ 'type' => ['string', 'enum' => $types, 'desc' => '类型'], 'is_visible' => ['int', 'desc' => '是否可见'], ]; Param::checkParam2($rules, $args); $user_id = User::getUserId(); $type = $args['type']; $is_visible = (int) $args['is_visible']; $objUserBindInfo = new TableHelper('user_bind_info', 'dw_chat'); $objUserBindInfo->updateObject(compact('is_visible'), compact('user_id', 'type')); } /** * 用户信息接口 * @author solu * @param $args * @return array */ public function actionInfo($args) { $rules = [ 'target_id' => ['int', 'desc' => '用户id'], 'group_id' => ['int', 'nullable' => true, '群id'], ]; Param::checkParam2($rules, $args); $self = User::getUserId(); $userId = (int)$args['target_id']; $groupId = (int)$args['group_id']; // 如果是自己调用,则刷新token的有效期 if ($userId == $self) { Account::refreshToken(); } return User::getUserInfo($userId, $self, $groupId); } /** * Simplewallet 协议登录 * @param $args * @param string $authority * * @return array|bool|null */ public function actionSimplewallet($args, $authority = 'active') { if (!$args) { $json = file_get_contents('php://input'); $data = json_decode($json, true); $args += $data; } $rules = [ 'account' => ['string', 'desc' => 'Eos账号'], 'chainId' => ['string', 'desc' => '链id'], 'protocol' => ['string', 'desc' => '协议', 'enum' => ['SimpleWallet']], 'ref' => ['string', 'desc' => '来源'], 'sign' => ['string', 'desc' => '签名'], 'timestamp' => ['string', 'desc' => '时间戳'], 'uuID' => ['string', 'desc' => '随机数'], 'version' => ['string', 'desc' => '版本号'], ]; Param::checkParam($rules, $args); $pubkey = $this->_getPublicKey($args['account'], $authority); $newArgs = [ 'account' => $args['account'], 'pubkey' => $pubkey, 'authority' => $authority, 'sign' => $args['sign'], ]; $orginStr = "{$args['timestamp']}{$args['account']}{$args['uuID']}{$args['ref']}"; $info = $this->actionEosLogin($newArgs, $orginStr); if ($info) { $objRedis = dwRedis::init(); $info['account'] = $args['account']; $uuid = $this->_getUuid($args['uuID']); $objRedis->setex($uuid, 60, json_encode($info)); } else if ($authority == 'active') { // 再尝试一次 owner $this->actionSimplewallet($args, 'owner'); } } /** * Simplewallet 协议登录 * @param $args * @param string $authority * * @return array|bool|null */ public function actionSimplewalletCheck($args) { $rules = [ 'uuID' => ['string', 'desc' => '随机数'] ]; Param::checkParam($rules, $args); $objRedis = dwRedis::init(); $uuid = $this->_getUuid($args['uuID']); $json = $objRedis->get($uuid); if ($json) { $info = json_decode($json, true); return $info; } else { Response::error(CODE_NORMAL_ERROR, 'no found'); } } private function _getUuid($uuid) { return "globals:simple_wallet:{$uuid}"; } /** * Telegram登录 * @author solu * @param $args * @return array * @ignore */ public function actionTgLogin($args) { $rules = [ 'id' => ['int', 'desc' => 'telegram user id'], 'first_name' => 'string', 'last_name' => ['string', 'nullable' => true], 'auth_date' => ['int', 'desc' => 'timestamp'], 'hash' => ['string', 'desc' => 'verify hash'], ]; Param::checkParam2($rules, $args); $data = []; try { $data = ThirdApi::checkTelegramAuthorization($args); } catch (Exception $e) { Response::error(CODE_SIGN_ERROR, $e->getMessage()); } $name = $data['first_name']; $args['last_name'] && $name .= "_{$args['last_name']}"; $user_id = User::login($data['id'], Account::TYPE_TG, $name); return Account::setCookie($user_id); } /** * Telegram绑定 * @author solu * @param $args * @ignore */ public function actionTgBind($args) { $rules = [ 'id' => ['int', 'desc' => 'telegram user id'], 'first_name' => 'string', 'last_name' => ['string', 'nullable' => true], 'auth_date' => ['int', 'desc' => 'timestamp'], 'hash' => ['string', 'desc' => 'verify hash'], ]; Param::checkParam2($rules, $args); $data = []; try { $data = ThirdApi::checkTelegramAuthorization($args); } catch (Exception $e) { Response::error(CODE_SIGN_ERROR, $e->getMessage()); } $user_id = User::getUserId(); User::bind($user_id, $data['id'], Account::TYPE_TG); } /** * Telegram登录token * @author solu * @param $args * @return array */ public function actionTgCSRF($args) { $rules = [ 'type' => ['string', 'enum' => ['login', 'bind'], 'desc' => '类型'], ]; Param::checkParam2($rules, $args); $csrf_token = $args['type'] . '-' . uuid(); Telegram::initCSRF($csrf_token); $url = BOT_CHAT_URL . "?start={$csrf_token}"; return compact('csrf_token', 'url'); } /** * Telegram登录(窗口start模式 * @param $args * @return array */ public function actionTgLogin2($args) { $rules = [ 'csrf_token' => 'string', ]; Param::checkParam2($rules, $args); $status = Telegram::getCSRFStatus($args['csrf_token']); $user_id = 0; $token = ''; if ($status > 0) { // 用户已在Telegram确定 $userData = Account::setCookie($status); $user_id = $userData['user_id']; $token = $userData['token']; } return compact('status', 'user_id', 'token'); } /** * Telegram绑定 (窗口start模式 * @param $args * @return array */ public function actionTgBind2($args) { $rules = [ 'csrf_token' => 'string', ]; Param::checkParam2($rules, $args); $user_id = User::getUserId(); $status = Telegram::getCSRFStatus($args['csrf_token']); if ($status > 0) { // 用户已在Telegram确定 User::bind($user_id, $status, Account::TYPE_TG); Telegram::setUserByTG($status, $user_id); } return compact('status'); } /** * 校验登录态 * @author solu * @param $args * @return array */ public function actionCheckLogin($args) { $rules = [ 'user_id' => 'int', 'token' => 'string', ]; Param::checkParam2($rules, $args); $user_id = User::getUserId(); $is_login = $user_id > 0; return compact('is_login'); } }