diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 11ce0d209..4d72fd2f8 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -941,12 +941,12 @@ "source": { "type": "git", "url": "https://github.com/zoujingli/ThinkLibrary.git", - "reference": "09c2992650ebd84dfb1de2e19a458119e219abda" + "reference": "a7bf1dc5a4a4bcddcfcdf9f8e7472dbc07890f83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/09c2992650ebd84dfb1de2e19a458119e219abda", - "reference": "09c2992650ebd84dfb1de2e19a458119e219abda", + "url": "https://api.github.com/repos/zoujingli/ThinkLibrary/zipball/a7bf1dc5a4a4bcddcfcdf9f8e7472dbc07890f83", + "reference": "a7bf1dc5a4a4bcddcfcdf9f8e7472dbc07890f83", "shasum": "", "mirrors": [ { @@ -963,7 +963,7 @@ "ext-mbstring": "*", "topthink/framework": "^6.0" }, - "time": "2020-10-29T06:49:48+00:00", + "time": "2020-10-31T06:54:57+00:00", "type": "library", "extra": { "think": { diff --git a/vendor/services.php b/vendor/services.php index 79be9f76c..a1b49b68c 100644 --- a/vendor/services.php +++ b/vendor/services.php @@ -1,5 +1,5 @@ 'think\\admin\\Library', diff --git a/vendor/zoujingli/think-library/src/command/Install.php b/vendor/zoujingli/think-library/src/command/Install.php index ddf0b583a..ac1df3f1c 100644 --- a/vendor/zoujingli/think-library/src/command/Install.php +++ b/vendor/zoujingli/think-library/src/command/Install.php @@ -65,10 +65,8 @@ class Install extends Command 'config' => [ 'rules' => [ 'config/app.php', - 'config/cache.php', 'config/log.php', 'config/route.php', - 'config/session.php', 'config/trace.php', 'config/view.php', 'public/index.php', diff --git a/vendor/zoujingli/think-library/src/multiple/Multiple.php b/vendor/zoujingli/think-library/src/multiple/Multiple.php index 07cef4341..9f2fbdb4a 100644 --- a/vendor/zoujingli/think-library/src/multiple/Multiple.php +++ b/vendor/zoujingli/think-library/src/multiple/Multiple.php @@ -72,22 +72,13 @@ class Multiple }); } - /** - * 获取路由目录 - * @return string - */ - protected function getRoutePath(): string - { - return $this->app->getAppPath() . 'route' . DIRECTORY_SEPARATOR; - } - /** * 解析多应用 * @return bool */ protected function parseMultiApp(): bool { - $scriptName = $this->getScriptName(); + $scriptName = $this->scriptName(); $defaultApp = $this->app->config->get('app.default_app') ?: 'index'; if ($this->name || ($scriptName && !in_array($scriptName, ['index', 'router', 'think']))) { $appName = $this->name ?: $scriptName; @@ -131,6 +122,16 @@ class Multiple $appName = $map['*']; } else { $appName = $name ?: $defaultApp; + if (stripos($appName, 'addons-') !== 0) { + if (!is_dir($this->path ?: $this->app->getBasePath() . $appName)) { + if ($this->app->config->get('app.app_express', false)) { + $this->setApp($defaultApp); + return true; + } else { + return false; + } + } + } } if ($name) { $this->app->request->setRoot('/' . $name); @@ -143,39 +144,25 @@ class Multiple } /** - * 获取当前运行入口名称 - * @codeCoverageIgnore - * @return string - */ - protected function getScriptName(): string - { - if (isset($_SERVER['SCRIPT_FILENAME'])) { - $file = $_SERVER['SCRIPT_FILENAME']; - } elseif (isset($_SERVER['argv'][0])) { - $file = realpath($_SERVER['argv'][0]); - } - return isset($file) ? pathinfo($file, PATHINFO_FILENAME) : ''; - } - - /** - * 设置应用 + * 设置应用参数 * @param string $appName 应用名称 */ - protected function setApp(string $appName): void + private function setApp(string $appName): void { + $space = $this->app->config->get('app.app_namespace') ?: 'app'; if (stripos($appName, 'addons-') === 0) { - [, $appName] = explode('addons-', $appName, 2); - $this->app->setNamespace($this->app->config->get('app.app_namespace') ?: "app\\addons\\{$appName}"); + $appName = substr($appName, strlen('addons-')); + $this->app->setNamespace("{$space}\\addons\\{$appName}"); $appPath = $this->path ?: $this->app->getBasePath() . 'addons' . DIRECTORY_SEPARATOR . $appName . DIRECTORY_SEPARATOR; } else { + $this->app->setNamespace("{$space}\\{$appName}"); $appPath = $this->path ?: $this->app->getBasePath() . $appName . DIRECTORY_SEPARATOR; - $this->app->setNamespace($this->app->config->get('app.app_namespace') ?: "app\\{$appName}"); } $this->app->setAppPath($appPath); $this->app->http->name($appName); if (is_dir($appPath)) { $this->app->setRuntimePath($this->app->getRuntimePath() . $appName . DIRECTORY_SEPARATOR); - $this->app->http->setRoutePath($this->getRoutePath()); + $this->app->http->setRoutePath($this->app->getAppPath() . 'route' . DIRECTORY_SEPARATOR); $this->loadApp($appPath); } } @@ -185,7 +172,7 @@ class Multiple * @param string $appPath 应用路径 * @return void */ - protected function loadApp(string $appPath): void + private function loadApp(string $appPath): void { if (is_file($appPath . 'common.php')) { include_once $appPath . 'common.php'; @@ -203,7 +190,21 @@ class Multiple if (is_file($appPath . 'provider.php')) { $this->app->bind(include $appPath . 'provider.php'); } - // 加载应用默认语言包 $this->app->loadLangPack($this->app->lang->defaultLangSet()); } + + /** + * 获取当前运行入口名称 + * @codeCoverageIgnore + * @return string + */ + private function scriptName(): string + { + if (isset($_SERVER['SCRIPT_FILENAME'])) { + $file = $_SERVER['SCRIPT_FILENAME']; + } elseif (isset($_SERVER['argv'][0])) { + $file = realpath($_SERVER['argv'][0]); + } + return isset($file) ? pathinfo($file, PATHINFO_FILENAME) : ''; + } } \ No newline at end of file diff --git a/vendor/zoujingli/think-library/src/service/ModuleService.php b/vendor/zoujingli/think-library/src/service/ModuleService.php index 1b4c46e6f..c1fb51653 100644 --- a/vendor/zoujingli/think-library/src/service/ModuleService.php +++ b/vendor/zoujingli/think-library/src/service/ModuleService.php @@ -192,15 +192,15 @@ class ModuleService extends Service */ public function checkAllowDownload(string $name): bool { - // 禁止目录级别上跳 + // 禁止目录上跳级别 if (stripos($name, '..') !== false) { return false; } - // 禁止下载数据库配置文件 - if (stripos(strtr($name, '\\', '/'), 'config/database') !== false) { + // 阻止可能存在敏感信息的文件被下载 + if (preg_match('#config[\\\\/]+(filesystem|database|session|cache)#i', $name)) { return false; } - // 检查允许下载的文件规则 + // 检查允许下载的文件规则列表 foreach ($this->_getAllowDownloadRule() as $rule) { if (stripos($name, $rule) === 0) return true; } diff --git a/vendor/zoujingli/think-library/src/service/NodeService.php b/vendor/zoujingli/think-library/src/service/NodeService.php index e1eebeafa..ec7576c58 100644 --- a/vendor/zoujingli/think-library/src/service/NodeService.php +++ b/vendor/zoujingli/think-library/src/service/NodeService.php @@ -73,12 +73,14 @@ class NodeService extends Service } switch (count($attrs = explode('/', $node))) { case 2: - return $this->getCurrent('module') . '/' . strtolower($node); + $suffix = $this->nameTolower($attrs[0]) . '/' . $attrs[1]; + return $this->getCurrent('module') . '/' . strtolower($suffix); case 1: return $this->getCurrent('controller') . '/' . strtolower($node); + default: + $attrs[1] = $this->nameTolower($attrs[1]); + return strtolower(join('/', $attrs)); } - $attrs[1] = $this->nameTolower($attrs[1]); - return strtolower(join('/', $attrs)); } /** diff --git a/vendor/zoujingli/think-library/src/service/ZtSmsService.php b/vendor/zoujingli/think-library/src/service/ZtSmsService.php index 91e91b29a..19d768011 100644 --- a/vendor/zoujingli/think-library/src/service/ZtSmsService.php +++ b/vendor/zoujingli/think-library/src/service/ZtSmsService.php @@ -27,6 +27,12 @@ use think\admin\Service; */ class ZtSmsService extends Service { + /** + * 接口地址 + * @var string + */ + private $api = 'https://api.mix2.zthysms.com'; + /** * 子账号名称 * @var string @@ -68,12 +74,13 @@ class ZtSmsService extends Service * 验证手机短信验证码 * @param string $code 验证码 * @param string $phone 手机号验证 - * @param string $tplcode + * @param string $template 模板编码 * @return boolean */ - public function checkVerifyCode(string $code, string $phone, string $tplcode = 'ztsms.register_verify'): bool + public function checkVerifyCode(string $code, string $phone, string $template = 'ztsms.register_verify'): bool { - $cache = $this->app->cache->get($ckey = md5("code-{$tplcode}-{$phone}"), []); + $ckey = md5("code-{$template}-{$phone}"); + $cache = $this->app->cache->get($ckey, []); if (is_array($cache) && isset($cache['code']) && $cache['code'] == $code) { $this->app->cache->delete($ckey); return true; @@ -86,33 +93,33 @@ class ZtSmsService extends Service * 验证手机短信验证码 * @param string $phone 手机号码 * @param integer $wait 等待时间 - * @param string $tplcode 模板编号 + * @param string $template 模板编码 * @return array * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ - public function sendVerifyCode(string $phone, int $wait = 120, string $tplcode = 'ztsms.register_verify'): array + public function sendVerifyCode(string $phone, int $wait = 120, string $template = 'ztsms.register_verify'): array { - $content = sysconf($tplcode) ?: '您的短信验证码为{code},请在十分钟内完成操作!'; - $cache = $this->app->cache->get($ckey = md5("code-{$tplcode}-{$phone}"), []); + $time = time(); + $ckey = md5("code-{$template}-{$phone}"); + $cache = $this->app->cache->get($ckey, []); // 检查是否已经发送 - if (is_array($cache) && isset($cache['time']) && $cache['time'] > time() - $wait) { - $dtime = ($cache['time'] + $wait < time()) ? 0 : ($wait - time() + $cache['time']); + if (is_array($cache) && isset($cache['time']) && $cache['time'] + $wait > $time) { + $dtime = $cache['time'] + $wait < $time ? 0 : $cache['time'] + $wait - $time; return [1, '短信验证码已经发送!', ['time' => $dtime]]; } // 生成新的验证码 - [$code, $time] = [rand(100000, 999999), time()]; + $code = rand(100000, 999999); $this->app->cache->set($ckey, ['code' => $code, 'time' => $time], 600); // 尝试发送短信内容 - [$state] = $this->timeSend($phone, preg_replace_callback("|{(.*?)}|", function ($matches) use ($code) { - return $matches[1] === 'code' ? $code : $matches[1]; - }, $content)); - if ($state) return [1, '短信验证码发送成功!', [ - 'time' => ($time + $wait < time()) ? 0 : ($wait - time() + $time)], - ]; else { + $content = sysconf($template) ?: '您的验证码为{code},请在十分钟内完成操作!'; + [$state] = $this->timeSend($phone, str_replace('{code}', $code, $content)); + if ($state) { + return [1, '短信验证码发送成功!', ['time' => $wait]]; + } else { $this->app->cache->delete($ckey); - return [0, '短信发送失败,请稍候再试!', []]; + return [0, '短信发送失败,请稍候再试!', ['time' => 0]]; } } @@ -124,39 +131,35 @@ class ZtSmsService extends Service */ public function signAdd(array $signs = [], string $remark = ''): array { - foreach ($signs as $key => $sign) { - if (strpos($sign, '】') === false) $signs[$key] = $sign . '】'; - if (strpos($sign, '【') === false) $signs[$key] = '【' . $sign; - } - $data = ['sign' => $signs, 'remark' => $remark]; - return $this->doRequest('https://api.mix2.zthysms.com/sms/v1/sign', $data); + foreach ($signs as $key => $name) $signs[$key] = $this->_singName($name); + return $this->doRequest('/sms/v1/sign', ['sign' => $signs, 'remark' => $remark]); } /** * 查询短信签名 - * @param string $sign 短信签名 + * @param string $name 短信签名 * @return array */ - public function signGet(string $sign): array + public function signGet(string $name): array { - if (strpos($sign, '】') === false) $sign = $sign . '】'; - if (strpos($sign, '【') === false) $sign = '【' . $sign; - return $this->doRequest('https://api.mix2.zthysms.com/sms/v1/sign/query', ['sign' => $sign]); + return $this->doRequest('/sms/v1/sign/query', [ + 'sign' => $this->_singName($name), + ]); } /** * 报备短信模板 - * @param string $temName 模板名称 - * @param integer $temType 模板类型(1验证码,2行业通知,3营销推广) - * @param string $temContent 模板内容 - * @param array $paramJson 变量格式 + * @param string $name 模板名称 + * @param integer $type 模板类型(1验证码, 2行业通知, 3营销推广) + * @param string $content 模板内容 + * @param array $params 模板变量 * @param string $remark 模板备注 * @return array */ - public function tplAdd(string $temName, int $temType, string $temContent, array $paramJson = [], string $remark = ''): array + public function tplAdd(string $name, int $type, string $content, array $params = [], string $remark = ''): array { - return $this->doRequest('https://api.mix2.zthysms.com/sms/v2/template', [ - 'temName' => $temName, 'temType' => $temType, 'temContent' => $temContent, 'paramJson' => $paramJson, 'remark' => $remark, + return $this->doRequest('/sms/v2/template', [ + 'temName' => $name, 'temType' => $type, 'temContent' => $content, 'paramJson' => $params, 'remark' => $remark, ]); } @@ -167,7 +170,7 @@ class ZtSmsService extends Service */ public function tplGet(string $temId): array { - return $this->doRequest('https://api.mix2.zthysms.com/sms/v2/template/query', ['temId' => $temId]); + return $this->doRequest('/sms/v2/template/query', ['temId' => $temId]); } /** @@ -179,10 +182,8 @@ class ZtSmsService extends Service */ public function tplSend(string $tpId, string $sign, array $records): array { - if (strpos($sign, '】') === false) $sign = $sign . '】'; - if (strpos($sign, '【') === false) $sign = '【' . $sign; - return $this->doRequest('https://api.mix2.zthysms.com/v2/sendSmsTp', [ - 'tpId' => $tpId, 'records' => $records, 'signature' => $sign, + return $this->doRequest('/v2/sendSmsTp', [ + 'tpId' => $tpId, 'records' => $records, 'signature' => $this->_singName($sign), ]); } @@ -197,7 +198,7 @@ class ZtSmsService extends Service { $data = ['mobile' => $mobile, 'content' => $content]; if ($time > 0) $data['time'] = $time; - return $this->doRequest('https://api.mix2.zthysms.com/v2/sendSms', $data); + return $this->doRequest('/v2/sendSms', $data); } /** @@ -207,7 +208,7 @@ class ZtSmsService extends Service */ public function batchSend(array $records): array { - return $this->doRequest('https://api.mix2.zthysms.com/v2/sendSmsPa', ['records' => $records]); + return $this->doRequest('/v2/sendSmsPa', ['records' => $records]); } /** @@ -215,22 +216,34 @@ class ZtSmsService extends Service */ public function balance(): array { - [$state, $result, $message] = $this->doRequest('https://api.mix2.zthysms.com/v2/balance', []); + [$state, $result, $message] = $this->doRequest('/v2/balance', []); return [$state, $state ? $result['sumSms'] : 0, $message]; } + /** + * 短信签名内容处理 + * @param string $name + * @return string + */ + private function _singName(string $name): string + { + if (strpos($name, '】') === false) $name = $name . '】'; + if (strpos($name, '【') === false) $name = '【' . $name; + return $name; + } + /** * 执行网络请求 - * @param string $url 接口请求地址 + * @param string $uri 接口请求地址 * @param array $data 接口请求参数 * @return array */ - private function doRequest(string $url, array $data): array + private function doRequest(string $uri, array $data): array { $encode = md5(md5($this->password) . ($tkey = time())); $options = ['headers' => ['Content-Type:application/json;charset="UTF-8"']]; $extends = ['username' => $this->username, 'password' => $encode, 'tKey' => $tkey]; - $result = json_decode(HttpExtend::post($url, json_encode(array_merge($data, $extends)), $options), true); + $result = json_decode(HttpExtend::post($this->api . $uri, json_encode(array_merge($data, $extends)), $options), true); if (empty($result['code'])) { return [0, [], '接口请求网络异常']; } elseif (intval($result['code']) === 200) {