Compare commits

..

9 Commits

Author SHA1 Message Date
MI15\Win
131d0d664b v2.1.12-20240308 2024-03-11 16:32:35 +08:00
MI15\Win
004273c0c4 v2.1.11-20240119 2024-01-21 01:31:42 +08:00
MI15\Win
851ff8285c v2.1.09-20231220 2023-12-21 23:02:38 +08:00
MI15\Win
b856c288b9 v2.1.08-20231219 2023-12-21 01:36:27 +08:00
MI15\Win
f2ce9c4eef v2.1.07-20231130 2023-12-01 00:14:39 +08:00
MI15\Win
01fdca800b v2.1.06-20231113 2023-11-14 01:25:59 +08:00
MI15\Win
77f357061a v2.1.05-20231106 2023-11-07 23:07:03 +08:00
MI15\Win
3ece39150c v2.1.04-20231029 2023-10-30 01:40:27 +08:00
MI15\Win
68464e34f9 v2.1.03-20231019 2023-10-20 00:34:17 +08:00
41 changed files with 551 additions and 175 deletions

View File

@@ -25,11 +25,12 @@ TwoNav 是一款开源的书签(导航)管理程序,界面简洁,安装
- [https://github.com/tznb1/TwoNav](https://github.com/tznb1/TwoNav)
### 技术支持
- QQ: 271152681
- QQ群: 695720839
- 技术支持QQ: 271152681
- 授权版QQ群: 695720839
- 免费版QQ群: 621815595
### 运行环境
* PHP: 7.3 - 8.2
* PHP: 7.3 - 8.2
* 数据库: SQLite3 或 MySQL > 5.6.0
### 功能特色

View File

@@ -35,28 +35,19 @@ if($db_config['type'] == 'sqlite'){
$global_config = unserialize( get_db("global_config", "v", ["k" => "o_config"]) ); //全局配置
$c = Get('c');
$libs = $global_config['Libs'];
$layui['js'] = $libs.'/Layui/v2.8.17/layui.js';
$layui['css'] = $libs.'/Layui/v2.8.17/css/layui.css';
$layui['js'] = $libs.'/Layui/v2.9.7/layui.js';
$layui['css'] = $libs.'/Layui/v2.9.7/css/layui.css';
$global_config['static_link'] = isset($global_config['static_link']) ? $global_config['static_link'] : 0;
define('libs',$global_config['Libs']);
define('SysVer',Get_Version());
define('Debug',$global_config['Debug'] == 1);
define('static_link',$global_config['static_link'] > 0);
if(!in_array($c,[$global_config["Register"],'ico','icon'])){
if(!in_array($c,[$global_config["Register"],'ico','icon','auth'])){
if($global_config['static_link'] > 0 && !empty($UUID)){
$_GET['u'] = $global_config['static_link'] == 2 ? get_db("global_user", "User", ["ID"=>$UUID]) : $UUID;
}
$u = Get('u');
if(empty($u) && $global_config['Sub_domain'] == 1 && is_subscribe('bool')){
$cut = explode('.',$_SERVER["HTTP_HOST"]);
if(count($cut) == 3){
$USER_DB = get_db("global_user", "*", ["User"=>reset($cut)]);
if(!empty($USER_DB) && check_purview('Sub_domain',1)){
$_COOKIE['Default_User'] = $USER_DB['User'];unset($cut);
}
}
}
$u = !empty($u)?$u:(!empty($_COOKIE['Default_User'])?$_COOKIE['Default_User']:(!empty($global_config['Default_User'])?$global_config['Default_User']:'admin'));//优先级:Get>Host>Cookie>默认用户>admin
$USER_DB = get_db("global_user", "*", ["User"=>$u]);
//没找到账号显示404
@@ -83,7 +74,7 @@ if(empty($c) || $c == 'index'){
require "./system/Register.php";//注册
}elseif($c == $global_config['Login'] || $c == $USER_DB['Login']){
require "./system/login.php";//登陆
}elseif(in_array($c,['admin','click','api','ico','icon','verify'])){
}elseif(in_array($c,['admin','click','api','ico','icon','verify','auth'])){
require "./system/{$c}.php";
}elseif(in_array($c,['apply','guestbook','article','sitemap'])){
if($global_config['Maintenance'] != 0){Amsg(-1,'网站正在进行维护,请稍后再试!');}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

Before

Width:  |  Height:  |  Size: 322 KiB

After

Width:  |  Height:  |  Size: 322 KiB

File diff suppressed because one or more lines are too long

View File

@@ -97,6 +97,7 @@ if(!empty($_GET['type'])){
msg(-1,'密码不能为空');
}
$RegTime = get_db('global_user','RegTime',['ID'=>$_POST['ID']]);
delete_db( "user_login_info", ["uid"=>$_POST['ID']] );
update_db('global_user',['Password'=>Get_MD5_Password($_POST['new_pwd'],$RegTime)],["ID" => $_POST['ID'] ],[1,'修改成功']);
}elseif($_GET['type'] == 'set_root'){
update_db('global_user',['UserGroup'=>'root'],["ID" => $_POST['ID'] ],[1,'修改成功']);
@@ -227,7 +228,7 @@ function echo_Atool(){
<head>
<meta charset="UTF-8">
<title>ATool 工具箱</title>
<link rel="stylesheet" href="../static/Layui/v2.8.17/css/layui.css">
<link rel="stylesheet" href="../static/Layui/v2.9.7/css/layui.css">
<style>
html, body {min-width: 1200px;background-color: #fff;position: relative;}
.page-wrapper {width: 1200px;margin: 0 auto;padding: 0 15px;}
@@ -279,7 +280,7 @@ function echo_Atool(){
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="del_otp" title="移除OTP登录验证">删OTP</a>
</div>
</script>
<script src="../static/Layui/v2.8.17/layui.js"></script>
<script src="../static/Layui/v2.9.7/layui.js"></script>
<script src="../static/jquery/jquery-3.6.0.min.js"></script>
<script src="../static/jquery/jquery.md5.js"></script>
<script src="../templates/admin/js/public.js?v=<?php echo time();?>"></script>
@@ -416,7 +417,7 @@ function echo_verify(){ ?>
<head>
<meta charset="UTF-8">
<title>ATool 工具箱</title>
<link rel="stylesheet" href="../static/Layui/v2.8.17/css/layui.css">
<link rel="stylesheet" href="../static/Layui/v2.9.7/css/layui.css">
<link rel="stylesheet" href="../static/Other/login.css">
</head>
<body>
@@ -441,7 +442,7 @@ function echo_verify(){ ?>
</div>
</div>
<script src = "../static/jquery/jquery-3.6.0.min.js"></script>
<script src = "../static/Layui/v2.8.17/layui.js"></script>
<script src = "../static/Layui/v2.9.7/layui.js"></script>
<script src = '../static/jquery/jquery.md5.js'></script>
<script>
layui.use(['form','jquery'], function () {

View File

@@ -72,7 +72,7 @@ if(!empty($regcode_info['u_group'])){
}
//读取用户组信息,如果用户组不存在则设为默认用户组
if($UserGroup != 'default'){
if(!in_array($UserGroup,['default','root','visitor'])){
$Group = get_db('user_group','*',['code' => $UserGroup]);
if(empty( $Group )){
$UserGroup = 'default';

View File

@@ -69,7 +69,7 @@ if($page == 'config_home'){
msg(-1,"参数错误");
}
if(in_array($_GET['fn'],['guide','register'])){
$theme_config_db = get_db('user_config','v',['k'=>'theme_'.$theme,'uid'=>UID]);
$theme_config_db = get_db('global_config','v',['k'=>"theme_{$_GET['fn']}_{$theme}"]);
}else{
$theme_config_db = get_db('user_config','v',['t'=>'theme_'.$_GET['fn'],'k'=>$theme,'uid'=>UID]);
}

View File

@@ -378,7 +378,7 @@ function write_link(){
//检测链接是否合法
check_link($fid,$title,$url,$_POST['url_standby']);
//检查链接是否已存在
if(get_db('user_links','lid',['uid'=>UID ,"url" => $url])){
if(empty(get_db('user_config','v',['uid'=>UID ,'t'=>'config','k'=>'repeat_url'])) && has_db('user_links',['uid'=>UID ,"url" => $url])){
msg(-1,'链接已存在!');
}
//描述长度检测
@@ -581,7 +581,9 @@ function write_link(){
msg(-1,'关键字长度不能大于'.$length_limit['l_key'].'个字节');
}
//检查链接是否已存在
if(has_db('user_links',['uid'=>UID ,'lid[!]'=>$lid, "url" => $url])){msg(-1,'链接已存在!');}
if(empty(get_db('user_config','v',['uid'=>UID ,'t'=>'config','k'=>'repeat_url'])) && has_db('user_links',['uid'=>UID ,'lid[!]'=>$lid, "url" => $url])){
msg(-1,'链接已存在!');
}
//检查链接ID是否存在
if(!has_db('user_links',['uid'=>UID ,'lid'=>$lid])){msg(-1,'链接ID不存在!');}
@@ -812,6 +814,7 @@ function write_site_setting(){
'link_model'=>['v'=>['direct','Privacy','Privacy_js','Privacy_meta','301','302','Transition'],'msg'=>'链接模式参数错误'],
'main_link_priority'=>['int'=>true,'min'=>0,'max'=>3,'msg'=>'主链优先参数错误'],
'link_icon'=>['int'=>true,'min'=>0,'max'=>30,'msg'=>'链接图标参数错误'],
'repeat_url'=>['int'=>true,'min'=>0,'max'=>1,'msg'=>'重复链接参数错误'],
'site_icon'=>['empty'=>true],
'top_link'=>['int'=>true,'min'=>0,'max'=>100,'msg'=>'热门链接参数错误'],
'new_link'=>['int'=>true,'min'=>0,'max'=>100,'msg'=>'最新链接参数错误'],
@@ -837,6 +840,7 @@ function write_site_setting(){
@unlink($site['site_icon_file']);
$s_site['site_icon_file'] = '';
}
write_user_config('repeat_url',$_POST['repeat_url'],'config','重复链接');
update_db("user_config",["v"=>$s_site],["k"=>'s_site',"uid"=>UID],[1,'保存成功']);
}
//写过渡页配置
@@ -1132,7 +1136,10 @@ function read_theme(){
msgA(['code'=>1,'data'=>$themes,'current'=>$current,'referrer'=>($data['referrer'] ?? '')]);
}
function msg_tip(){
msg(-1,'免费版不支持此功能,购买授权版<br /> <a href="https://gitee.com/tznb/TwoNav/wikis/pages?sort_id=7968669&doc_id=3767990" target="_blank" style="color: #1e9fff;">点击此处前往购买页面</a>');
if(is_subscribe()){
msg(-1,'请前往概要页面更新系统,未提示更新则尝试刷新页面<br />更新后即可解锁全部功能,如有疑问请联系客服');
}
msg(-1,'免费版不支持此功能<br /> <a href="https://gitee.com/tznb/TwoNav/wikis/pages?sort_id=7968669&doc_id=3767990" target="_blank" style="color: #1e9fff;">点击此处前往购买页面</a>');
}
//主题下载/更新/删除
@@ -1194,9 +1201,17 @@ function write_theme(){
}
}else{
$s_templates[$fn] = $name;
if($fn == 'transit'){
$site = unserialize(get_db('user_config','v',['uid'=>UID,'k'=>'s_site']));
if($site['link_model'] != 'Transition'){
$site['link_model'] = 'Transition';
update_db("user_config",["v"=>$site],["k"=>'s_site',"uid"=>UID]);
$msg = ',已同步链接模式为过渡页面';
}
}
}
//更新数据
update_db('user_config',['v'=>$s_templates],['uid'=>UID,'k'=>'s_templates'],[1,'设置成功']);
update_db('user_config',['v'=>$s_templates],['uid'=>UID,'k'=>'s_templates'],[1,"设置成功{$msg}"]);
//配置主题信息
}elseif($_GET['type'] == 'config'){
@@ -1495,6 +1510,8 @@ function read_data(){
$log .= in_array("Phar",$ext) ? "" : "Phar不支持 (在线更新/主题下载)\n";
$log .= in_array("hash",$ext) ? "" : "hash不支持 (书签分享/生成注册码)\n";
$log .= in_array("session",$ext) ? "" : "session不支持 (影响较大)\n";
$log .= in_array("intl",$ext) ? "" : "intl不支持 (使用中文域名时可能会导致异常)\n";
$log .= $GLOBALS['global_config']['offline'] == '1' ? "离线模式:已开启,会导致无法更新系统/下载主题模板等\n" : "";
$log .= "可用模块:".implode("&#12288;",$ext)."\n";
$updatadb_logs = select_db('updatadb_logs','file_name',['file_name[!]'=>'install.sql']);
$log .= "数据库更新记录:".(empty($updatadb_logs)?'无':"\n".implode("\n",$updatadb_logs))."\n";
@@ -1539,12 +1556,10 @@ function read_data(){
$date = date('Ymd', strtotime("-$i days"));
$dates[] = $date;
}
$dates = array_reverse($dates);
$day_data = [];
foreach ($dates as $date) {
$list = get_db('user_count', 'e', ['uid' => UID, 'k' => $date, 't' => 'ip_list']);
$list = unserialize($list);
$list = select_db('user_count','e',['uid'=>UID,'k'=>$date,'t'=>'access_ip']);
$day_data[$date] = empty($list) ? [] : $list ;
}
msgA(['code'=>1,'data'=>$day_data]);
@@ -1634,9 +1649,8 @@ function other_get_link_info(){
msg(-1010,'URL不能为空!');
}elseif(!preg_match("/^(http:\/\/|https:\/\/).*/",$url)){
msg(-1010,'只支持识别http/https协议的链接!');
}elseif( !filter_var($url, FILTER_VALIDATE_URL) ) {
msg(-1010,'URL无效!');
}
$url = process_url_idn($url);
//获取网站标题 (HTML/JS跳转无法识别)
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $url);

View File

@@ -402,6 +402,7 @@ function other_root(){
delfile($dir,30);
$size = $_SESSION['CleanCacheSize'];
unset($_SESSION['CleanCacheSize']);
clean_cache();
if($size == 0){
msg(1,'暂无可清理缓存');
}
@@ -455,7 +456,8 @@ function other_services(){
'order_id' => isset($_POST['order_id']) ? $_POST['order_id'] : "",
'sysver' => SysVer,
'ip' => Get_IP(),
'method' => $_GET['type']
'method' => $_GET['type'],
'sys' => $_POST['sys']
];
$overtime = !isset($global_config['Update_Overtime']) ? 3 : ($global_config['Update_Overtime'] < 3 || $global_config['Update_Overtime'] > 60 ? 3 : $global_config['Update_Overtime']);
// 判断操作类型
@@ -465,11 +467,12 @@ function other_services(){
msg(-1,'请求官方服务器失败,请稍后再试');
}
$data = json_decode($Res["content"], true);
$msg = $data['msg'];
// 如果是保存设置
if($_GET['type'] == 'save_key'){
$data = $data['data'];
if(!isset($data['order_id']) || empty($data['order_id'])){
msg(-1,'保存失败,请核对信息是否有误');
msg(-1,empty($msg) ? '保存失败,请核对信息是否有误<br />' : $msg);
}
//判断是否为IP
if(preg_match("/^(\d+\.\d+\.\d+\.\d+):*\d*$/",$domain,$host)) {
@@ -512,11 +515,14 @@ function other_services(){
//如果不为空,则解析数据
if(!empty($Notice)){
$data = json_decode($Notice, true);
$cache_time = 60; //缓存时间(秒);
$cache_time = Debug ? 0 : 60; //缓存时间(秒);
$reload = time() > $data["download_time"] + $cache_time; //是否更新
}else{
$reload = true; //需要刷新
}
if($GLOBALS['global_config']['offline'] == '1'){
msgA(['code'=>200,'message'=>"已开启离线模式,无法获取最新动态/官方公告/下载模板/更新系统等。"]);
}
// 判断是否刷新数据
if(!$global_config['offline'] && $reload){
if(is_subscribe('bool')){
@@ -529,9 +535,16 @@ function other_services(){
$new_data['download_time'] = time();
$new_data['version'] = version_compare($new_data['version'],SysVer,'<') ? SysVer : $new_data['version'];
write_global_config('notice',json_encode($new_data),'官方公告(缓存)');
write_global_config('sys_switch',"{$new_data['sys_switch']}",'sys_switch');
$data = $new_data;
}
}
//时间检测
if(isset($_GET['t']) && !empty($_GET['t'])){
if (abs( time() - $_GET['t'] ) > 300) {
$data['message'] .= "<br /><span style=\"color: #ff5722;\" >检测到客户端时间与服务器时间存在较大差异<br />这会导致部分功能无法正常使用<br />请及时校对服务器或客户端时间</span>";
}
}
msgA($data);
}
}

90
system/auth.php Normal file
View File

@@ -0,0 +1,90 @@
<?php if(!defined('DIR')){header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit;}
// 鉴权接口: 账号登录
//忽略GET/POST以外的请求
if(!in_array($_SERVER['REQUEST_METHOD'],['GET','POST'])){
exit;
}
if(!isset($auth_mode)){
$auth_mode = $_GET['mode'];
}
//账号登录
if($auth_mode == 'uname'){
$username = $_POST['username'];
$password = $_POST['password'];
$log = ["uid" => '',"user"=>$username,"ip"=>Get_IP(),"time"=>time(),"type" => 'login',"content"=>Get_Request_Content(),"description"=>""];
//密码长度
if(strlen($password)!==32){
$log['description'] = '请求登录>密码错误(长度应该是32位的MD5)';
insert_db("user_log",$log);
msg(-1,'账号或密码错误');
}
//浏览器UA
if(strlen($_SERVER['HTTP_USER_AGENT']) > 1024){
$log['description'] = '请求登录>浏览器UA长度>1024';
insert_db("user_log",$log);
msg(-1,"浏览器UA长度异常,请更换浏览器!");
}
//读取资料
$USER_DB = get_db("global_user", "*", ["OR"=>['User'=>$username,'Email'=>$username]]);
if(empty($USER_DB)){
$log['description'] = '请求登录>账号不存在';
insert_db("user_log",$log);
msg(-1,'账号不存在');
}
$log['uid'] = $USER_DB['ID'];
//登录入口
session_start();
if($_SESSION['login'] != $global_config["Login"] && $_SESSION['login'] != $USER_DB['Login'] ){
$log['description'] = '请求登录>登录入口错误';
insert_db("user_log",$log);
msg(-1,"请求失败,请刷新登录页面再试");
}
//双重验证
$LoginConfig = unserialize( $USER_DB['LoginConfig'] );
if(!empty($LoginConfig['totp_key'])){
if(empty($_POST['otp_code'])){
msgA(['code'=>2]);
}
require DIR . '/system/Authenticator.php';
$totp = new PHPGangsta_GoogleAuthenticator();
$checkResult = $totp->verifyCode($LoginConfig['totp_key'], $_POST['otp_code'], 2);
if(!$checkResult){
$log['description'] = '请求登录>动态口令错误';
insert_db("user_log",$log);
msgA(['code'=>-1,'msg'=>'动态口令错误']);
}
}
//验证密码
if(Get_MD5_Password($password,$USER_DB["RegTime"]) === $USER_DB["Password"]){
$log['description'] = '请求登录>登录成功';
insert_db("user_log",$log);
//保持登录
$keep_login = isset($_POST['keep']) && $_POST['keep'] == 'on';
if($keep_login == true){
$LoginConfig['Session'] = ($LoginConfig['Session'] > 0 ? $LoginConfig['Session'] : 7 );
}else{
$LoginConfig['Session'] = 0;
}
$USER_DB['LoginConfig'] = serialize($LoginConfig);
//设置Cookie
Set_key($USER_DB);
if(empty($LoginConfig['login_page']) || $LoginConfig['login_page'] == 'admin'){
$url = "./?c=admin&u={$USER_DB['User']}";
}elseif($LoginConfig['login_page'] == 'index'){
$url = "./?c=index&u={$USER_DB['User']}";
}else{
$url = preg_match('/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i',$_SERVER['HTTP_USER_AGENT']) ? "./?c=index&u={$USER_DB['User']}" : "./?c=admin&u={$USER_DB['User']}";
}
//默认页面
if(!empty($global_config['default_page'])){
setcookie('Default_User', $USER_DB['User'], strtotime("+360 day"),"/",'',false,false);
}
msgA(['code'=>1,'msg'=>'登录成功','url'=>$url]);
}else{
$log['description'] = '请求登录>账户或密码错误';
insert_db("user_log",$log);
msg(-1,"账户或密码错误");
}
}

View File

@@ -86,7 +86,9 @@ if(!empty($link['url_standby']) || $site['link_model'] == 'Transition'){
if(!empty($link['url_standby'])) {
$link['url_standby'] = unserialize($link['url_standby']);
//主链优先模式
if(!empty($site['main_link_priority']) && $site['link_model'] != 'Transition'){
if($site['main_link_priority'] == '3'){
$site['link_model'] = $site['link_model'] == 'direct' ? '302' : $site['link_model'];
}elseif($site['main_link_priority'] > 0 && $site['link_model'] != 'Transition'){
$code = get_http_code($link['url'],3,($site['main_link_priority'] == 1));
if(in_array(intval($code),[200,301,302,401]) ){
$site['link_model'] = $site['link_model'] == 'direct' ? '302' : $site['link_model'];
@@ -110,9 +112,11 @@ if ($site['link_model'] == '302'){ //302重定向(临时)
exit;
}elseif($site['link_model'] == 'Privacy'){ //隐私保护_header
header("Content-type: text/html; charset=utf-8");
if(preg_match('/[\x{4e00}-\x{9fa5}]/u', $link['url']) > 0){
exit ('<html lang="zh-ch"><head><title>正在保护您的隐私..</title><meta name="referrer" content="same-origin"><script>window.location.href="'.$link['url'].'"</script></head>');
}
header("Refresh:0;url=".$link['url']);
echo '<html lang="zh-ch"><head><title>正在保护您的隐私..</title><meta name="referrer" content="same-origin"></head>';
exit;
exit ('<html lang="zh-ch"><head><title>正在保护您的隐私..</title><meta name="referrer" content="same-origin"></head>');
}elseif($site['link_model'] == 'Privacy_js'){ //隐私保护_js
header("Content-type: text/html; charset=utf-8");
echo '<html lang="zh-ch"><head><title>正在保护您的隐私..</title><meta name="referrer" content="same-origin"><script>window.location.href="'.$link['url'].'"</script></head>';

View File

@@ -4,8 +4,8 @@ if(!defined('DIR')){header('HTTP/1.1 404 Not Found');header("status: 404 Not Fou
//初始化
session_name('TwoNav_initial');
session_start();
$layui['js'] = './static/Layui/v2.8.17/layui.js';
$layui['css'] = './static/Layui/v2.8.17/css/layui.css';
$layui['js'] = './static/Layui/v2.9.7/layui.js';
$layui['css'] = './static/Layui/v2.9.7/css/layui.css';
//判断请求类型
if($_SERVER['REQUEST_METHOD'] === 'POST'){
@@ -150,7 +150,7 @@ $db_config = array(
// mysql
if($_POST['db_type'] === 'mysql' || $_POST['db_type'] === 'mariadb'){
if( !isset($_POST['db_host']) || !isset($_POST['db_port']) || !isset($_POST['db_name']) || !isset($_POST['db_user']) || !isset($_POST['db_password']) ){
msg(-1,'MySQL配置错误,请检查..');
msg(-1,'数据库配置错误,请检查..');
}
require (DIR.'/system/Medoo.php'); //载入框架
@@ -164,13 +164,15 @@ $db_config = array(
'password' => $_POST['db_password'],
'charset' => 'utf8mb4'
]);
$ver = $db->info ()['version'];
if($_POST['db_type'] === 'mysql'){
if(version_compare($db->info ()['version'],'5.6.0','<')){
msg(-1,'MySQL数据库版本不能低于5.6,当前版本:'.$db->info ()['version']);
if(version_compare($ver,'5.6.0','<')){
msg(-1,'MySQL数据库版本不能低于5.6,当前版本:'.$ver);
}
}else{
if(version_compare($db->info ()['version'],'10.1.0','<')){
msg(-1,'MariaDB数据库版本不能低于10.1,当前版本:'.$db->info ()['version']);
preg_match('/(\d+\.\d+\.\d+)-MariaDB/', $ver, $matches);
if(version_compare($matches[1],'10.1.0','<')){
msg(-1,'MariaDB数据库版本不能低于10.1,当前版本:'.$ver);
}
}
}catch (Exception $e) {
@@ -310,10 +312,10 @@ function Write_Config(){
$o_config['global_header'] = '';
$o_config['global_footer'] = '';
$o_config['api_extend'] = 0;
$o_config['apply'] = 0;
$o_config['guestbook'] = 0;
$o_config['apply'] = 1;
$o_config['guestbook'] = 1;
$o_config['link_extend'] = 0;
$o_config['article'] = 0;
$o_config['article'] = 1;
$o_config['c_name'] = 0;
$o_config['c_desc'] = 0;
$o_config['l_name'] = 0;

View File

@@ -2,6 +2,8 @@
//如果是Get请求则载入登录模板
if($_SERVER['REQUEST_METHOD'] === 'GET'){
session_start();
$_SESSION['login'] = $c;
require DIR."/system/templates.php";
require $index_path;
exit;

View File

@@ -291,8 +291,9 @@ function Set_key($USER_DB){
$LoginConfig = unserialize($USER_DB['LoginConfig']);
$session = $LoginConfig['Session']; //保持时间(单位天)
$Expire = Get_ExpireTime($session); //计算到期时间戳
$real_Expire = ($Expire == 0) ? time() + 86400 : $Expire;
$time = time(); //取当前时间
$key = Getkey($USER_DB['User'],Get_MD5_Password($USER_DB["Password"],$USER_DB["RegTime"]),$Expire,$LoginConfig['KeySecurity'],$time);
$key = Getkey($USER_DB['User'],Get_MD5_Password($USER_DB["Password"],$USER_DB["RegTime"]),$real_Expire,$LoginConfig['KeySecurity'],$time);
setcookie($USER_DB['User'].'_key', $key, $session == 0 ? 0 : $Expire,"/",'',false,$LoginConfig['HttpOnly']==1);
insert_db("user_login_info", [
"uid" => $USER_DB['ID'],
@@ -301,8 +302,8 @@ function Set_key($USER_DB){
"ua"=>$_SERVER['HTTP_USER_AGENT'],
"login_time"=>$time,
"last_time"=>$time,
"expire_time"=>$Expire,
"cookie_key"=>md5($key)]); //不记录用户真实key,同时防止Cookie攻击
"expire_time"=>$real_Expire,
"cookie_key"=>md5($key)]);
return $key;
}
@@ -503,15 +504,18 @@ function Get_IP() {
$ip = getenv('HTTP_CLIENT_IP');
}elseif(getenv('HTTP_X_FORWARDED_FOR')) {
$ip = getenv('HTTP_X_FORWARDED_FOR');
} elseif (getenv('HTTP_X_FORWARDED')) {
}elseif (getenv('HTTP_X_FORWARDED')) {
$ip = getenv('HTTP_X_FORWARDED');
} elseif (getenv('HTTP_FORWARDED_FOR')) {
}elseif (getenv('HTTP_FORWARDED_FOR')) {
$ip = getenv('HTTP_FORWARDED_FOR');
} elseif (getenv('HTTP_FORWARDED')) {
}elseif (getenv('HTTP_FORWARDED')) {
$ip = getenv('HTTP_FORWARDED');
}else{
$ip = $_SERVER['REMOTE_ADDR'];
}
}
if(strpos($ip, ',') != false) {
$ip = reset(explode(",", $ip));
}
return $ip;
}
@@ -732,8 +736,8 @@ function send_email($config){
//统计访问ip数
function count_ip(){
$ip = Get_IP(); $k = date('Ymd'); $t = 'access_ip';
if(!has_db('user_count',['uid'=>UID,'k'=>$k,'t'=>$t,'v'=>$ip])){
insert_db("user_count",['uid'=>UID,'k'=>$k,'t'=>$t,'v'=>$ip]);
if(!has_db('user_count',['uid'=>UID,'k'=>$k,'t'=>$t,'e'=>$ip])){
insert_db("user_count",['uid'=>UID,'k'=>$k,'t'=>$t,'e'=>$ip,'v'=>0]);
write_user_count($k,'ip_count');//访问ip数+1
}
}
@@ -771,4 +775,12 @@ function get_OEM(){
//返回404
function Not_Found() {
header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit;
}
function process_url_idn($url) {
$parsed_url = parse_url($url);
if(!preg_match('/[\x{4e00}-\x{9fa5}]/u', $parsed_url['host'])){
return $url;
}
return substr_replace($url, idn_to_ascii($parsed_url['host']), strpos($url, "//") + 2, strlen($parsed_url['host']));
}

View File

@@ -1 +1 @@
v2.1.02-20231012
v2.1.12-20240308

View File

@@ -35,6 +35,7 @@
<dl class="layui-nav-child">
<dd><a href="javascript:;" layuimini-content-href="LoginDevice" data-title="登录设备">登录设备</a></dd>
<dd><a href="javascript:;" layuimini-content-href="SecuritySetting" data-title="安全设置">安全设置</a></dd>
<dd><a href="javascript:;" layuimini-content-href="AccessRestrictions" data-title="访问限制">访问限制</a></dd>
<dd><a href="javascript:;" layuimini-content-href="UserPassword" data-title="修改密码">修改密码</a></dd>
<dd><hr></dd>
<dd><a href="javascript:;" id="logout">退出登录</a></dd>

View File

@@ -73,6 +73,7 @@
//分类切换按钮
$("#btn-type").text(type == '&type=all' ?'收起':'展开');
//将一级分类加入下拉框
let old_val = $("#fid").val();
$("#fid").empty();
$("#fid").append("<option value=\"0\">无</option>");
for (i = 0; i < count; i++) {
@@ -80,6 +81,8 @@
$("#fid").append("<option value=\""+res.data[i].cid+"\">"+res.data[i].name+"</option>");
}
}
$("#fid").val(old_val);
form.render('select');
limit = false; //取消修改限制
layer.closeAll('loading'); //关闭加载层
//加载加密分组数据

View File

@@ -8,15 +8,23 @@ layui.use(['layer','miniTab'], function(){
// 获取最新信息
$.post(get_api('other_services','get_notice'),function(data,status){
console.log(data );
$.post(get_api('other_services','get_notice') + '&t=' + Math.round(new Date() / 1000),function(data,status){
if(data.code == 200) {
$("#new_ver a").text(data.version);
$('#notice_link').text('');
data.notice.forEach(notice => {
$('#notice_link').append(`<div class="layuimini-notice"><div class="layuimini-notice-title"><a href="${notice.url}" target="_blank">${notice.title}</a></div></div>`);
});
$('#notice_text').html(data.message);
if (Array.isArray(data.notice) && data.notice.length > 0) {
data.notice.forEach(notice => {
$('#notice_link').append(`<div class="layuimini-notice"><div class="layuimini-notice-title"><a href="${notice.url}" target="_blank">${notice.title}</a></div></div>`);
});
}else{
$('.notice1').remove();
}
if(data.message.length > 0){
$('#notice_text').html(data.message);
}else{
$('.notice2').remove();
}
}
init_update();
$(".update").remove();

View File

@@ -474,6 +474,7 @@ layui.use(['form','table','dropdown','miniTab'], function () {
//手机端操作
function load_dropdown(){
var data = [];
data.push({'title':'删除选中','id':'batch_del'});
$(".layui-btn-normal.layui-hide-xs").each(function(){
data.push({'title':$(this).text(),'id':$(this).attr('lay-event')});
});

View File

@@ -104,6 +104,9 @@ layui.use(function(){
$.post(`./index.php?c=api&method=read_theme&dir=${dir}&u=${u}&cache=${cache ? 'no':'yes'}`, function (r, status) {
layer.closeAll();
if (r.code == 1) {
if(r.referrer.length > 0){
$('meta[name="referrer"]').replaceWith(`<meta name="referrer" content="${r.referrer}">`);
}
datas = r.data;
render_data(r);
} else {
@@ -163,15 +166,12 @@ layui.use(function(){
current2.css('color','#03a9f4');
current2.prepend('<i class="layui-icon layui-icon-cellphone" title="移动终端正在使用此主题"> ');
$(`#col_${d.current.home_pad}`).prependTo($row);
//if(current1.is(current2)){ $("#set:first").remove(); }
}else{
if(d.current[active] !== null && d.current[active] !== undefined && d.current[active].length > 0){
var current = $(`#t_${d.current[active]}`);
current.css('color','#03a9f4');
current.prepend('<i class="fa fa-magic" style="color: #03a9f4;" title="正在使用"></i> ');
$(`#col_${d.current[active]}`).prependTo($row);
//$("#set:first").remove();
}
}
$(`#col_default`).prependTo($row);
@@ -292,7 +292,7 @@ layui.use(function(){
$.post(get_api('write_theme','set'),{type:type,name:name,fn:fn},function(data,status){
if( data.code == 1 ) {
layer.msg(data.msg, {icon: 1});
setTimeout(() => {load_data(active);}, 800);
setTimeout(() => {load_data(active);}, (data.msg == '设置成功' ? 800 : 2000));
}else{
layer.msg(data.msg, {icon: 5});
}
@@ -302,6 +302,5 @@ layui.use(function(){
//主题详情
function theme_detail(data){
layer.open({type: 1,scrollbar: false,maxmin: false,shadeClose: true,resize: false,title: data.name + ' - 主题详情',area: ['60%', '59%'],content: '<body class="layui-fluid"><div class="layui-row" style = "margin-top :1em;"><div class="layui-col-sm9" style = "border-right:1px solid #e2e2e2;"><div style = "margin-left:1em;margin-right:1em;"><img src="'+data.screenshot+'" alt="" style = "max-width:100%;"></div></div><div class ="layui-col-sm3"><div style = "margin-left:1em;margin-right:1em;"><h1>'+data.name+'</h1><p>描述:'+data.description+'</p><p>版本:'+data.version+'</p><p>更新时间:'+data.update+'</p><p>作者:'+data.author+'</p><p >主页:<a style = "color:#01AAED;" href="'+data.homepage+'" target="_blank" rel = "nofollow">访问主页</a></p></div></div></div></body>'});
}
});

View File

@@ -0,0 +1,71 @@
<?php $title='访问限制'; require 'header.php';?>
<style>
.layui-btn-container .layui-btn{border-width: 1px; border-style: solid; border-color: #FF5722!important; color: #FF5722!important;background: none;height: 30px; line-height: 30px; padding: 0 10px; font-size: 12px;}
</style>
<body>
<div class="layuimini-container">
<div class="layuimini-main">
<form class="layui-form" lay-filter="form">
<div class="layui-form layuimini-form layui-form-pane">
<blockquote class="layui-elem-quote layui-text" style="">
此功能<a href="https://gitee.com/tznb/TwoNav/wikis/pages?sort_id=7968669&doc_id=3767990" target="_blank">授权用户</a>专享
</blockquote>
<blockquote class="layui-elem-quote layui-text" style="">白名单模式 > 除了名单中的账号和分组一律不可访问您的主页<br />黑名单模式 > 黑名单中的账号和分组不可访问您的主页<br />匹配优先级: 用户组名单 > 账号名单<br />使用黑白名单模式时,未登录账号不可访问您的主页<br />名单中多个账号或分组时用半角的逗号,间隔<br />新增功能,难免会有BUG,如有遇到请反馈并关闭该功能</blockquote>
<div class="layui-form-item">
<label class="layui-form-label">访问限制</label>
<div class="layui-input-inline" >
<select name="mode">
<option value="0" selected="">无限制</option>
<option value="white">白名单模式</option>
<option value="black">黑名单模式</option>
</select>
</div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">用户组名单</label>
<div class="layui-input-block">
<textarea name="users_list" class="layui-textarea" placeholder='填写用户组代号,例如: group1,group2,group3'></textarea>
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">账号名单</label>
<div class="layui-input-block">
<textarea name="user_list" class="layui-textarea" placeholder='填写用户账号,例如: user1,user2,user3'></textarea>
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">限制提示</label>
<div class="layui-input-block">
<textarea name="prompt" class="layui-textarea" placeholder='留空时: 显示引导页
以http开头时: 跳转到url
其他内容则直接显示'></textarea>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block"><button class="layui-btn layui-btn-normal" lay-submit lay-filter="save">确认保存</button></div>
</div>
</div>
</form>
</div>
</div>
<script src = "<?php echo $libs;?>/jquery/jquery-3.6.0.min.js"></script>
<?php load_static('js.layui');?>
<script>
layui.use(['jquery','form','miniTab'], function () {
var form = layui.form;
var layer = layui.layer;
var $ = layui.jquery;
var miniTab = layui.miniTab;
miniTab.listen();
//监听提交
form.on('submit(save)', function (data) {
return false;
});
});
</script>
</body>
</html>

View File

@@ -73,17 +73,21 @@
<option value="20" >本地服务</option>
<option value="21" >本地服务(伪静态)</option>
<option value="2" >favicon.png.pub (小图标)</option>
<!--<option value="4" >api.15777.cn</option>-->
<!--<option value="5" >favicon.cccyun.cc</option>-->
<option value="6" >api.iowen.cn</option>
<!--<option value="7" >toolb.cn</option>-->
<!--<option value="8" >apis.jxcxin.cn</option>-->
<!--<option value="9" >ico.kucat.cn</option>-->
</select>
</div>
<div class="layui-form-mid layui-word-aux">所有API接口均由其他大佬提供!若有异常请尝试更换接口!</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">重复链接</label>
<div class="layui-input-inline" >
<select name="repeat_url" >
<option value="0" selected>禁止</option>
<option value="1">允许</option>
</select>
</div>
<div class="layui-form-mid layui-word-aux">是否允许添加已存在的链接</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">最新网址</label>
<div class="layui-input-inline" >
@@ -195,13 +199,18 @@ layui.use(['jquery','form','upload'], function () {
});
//监听提交
form.on('submit(save)', function (data) {
layer.load(0);
$.post('./index.php?c=api&method=write_site_setting&u='+u,data.field,function(data,status){
layer.closeLast('loading');
if(data.code == 1) {
layer.msg(data.msg, {icon: 1});
}else{
layer.msg(data.msg, {icon: 5});
}
});
}).fail(function(xhr, textStatus, errorThrown) {
layer.closeLast('loading');
layer.alert('请求失败');
});
return false;
});

View File

@@ -34,7 +34,7 @@
<div class="layui-progress" lay-filter="progress" id="progress" style="display:none;">
<div class="layui-progress-bar"></div>
</div>
<blockquote class="layui-elem-quote" style="margin-top: 10px;border-left: 5px solid #FF5722; color: #FF5722;" id='guide'>第一步:请上传数据,支持: db3 / html 格式(最大10M),使用前请参考<a href="https://gitee.com/tznb/TwoNav/wikis/pages?sort_id=7968661&doc_id=3767990" target="_blank" rel = "nofollow">帮助文档</a></blockquote>
<blockquote class="layui-elem-quote" style="margin-top: 10px;border-left: 5px solid #FF5722; color: #FF5722;" id='guide'>第一步:请上传数据,支持: db3 / html / itabdata 格式(最大10M),使用前请参考<a href="https://gitee.com/tznb/TwoNav/wikis/pages?sort_id=7968661&doc_id=3767990" target="_blank" rel = "nofollow">帮助文档</a></blockquote>
<div class="layui-form-item" style="display:none;" id='fid'>
<label class="layui-form-label">所属分类</label>

View File

@@ -7,7 +7,7 @@
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<?php if(defined('referrer')) echo '<meta name="referrer" content="' . referrer . '">'."\n";?>
<meta name="referrer" content="no-referrer-when-downgrade">
<?php load_static('css');if($awesome) echo str_replace('#',$libs,' <link rel="stylesheet" href="#/Font-awesome/4.7.0/css/font-awesome.css" media="all">'."\n");?>
<script>var u = "<?php echo U;?>";</script>
</head>

View File

@@ -8,10 +8,7 @@ $data = empty($Notice)?[]:json_decode($Notice, true);
//输出最新动态
function echo_notice_link($data){
if(empty($data["notice"])){
return;
}
echo '<div class="layui-card"><div class="layui-card-header"><i class="fa fa-bullhorn icon"></i>最新动态</div><div class="layui-card-body layui-text" id="notice_link">';
echo '<div class="layui-card notice1"><div class="layui-card-header"><i class="fa fa-bullhorn icon"></i>最新动态</div><div class="layui-card-body layui-text" id="notice_link">';
foreach($data["notice"] as $value){
echo "<div class=\"layuimini-notice\"><div class=\"layuimini-notice-title\"><a href=\"{$value['url']}\" target=\"_blank\">{$value['title']}</a></div></div>";
}
@@ -20,10 +17,7 @@ function echo_notice_link($data){
//输出官方公告
function echo_notice_text($data){
if(empty($data["message"])){
return;
}
echo '<div class="layui-card"><div class="layui-card-header"><i class="fa fa-bell-o icon"></i>官方公告</div><div class="layui-card-body layui-text layadmin-text" id="notice_text">';
echo '<div class="layui-card notice2"><div class="layui-card-header"><i class="fa fa-bell-o icon"></i>官方公告</div><div class="layui-card-body layui-text layadmin-text" id="notice_text">';
echo $data['message'];
echo '</div></div>';
}
@@ -39,7 +33,7 @@ if( $global_config['Sub_domain'] == 1 && check_purview('Sub_domain',1)){
}
if(!isset($_h)){
$_h = static_link ? get_surl('{UUID}.html'):"./?u={$u}";
$_l = static_link ? get_surl("login-{UUID}-{$USER_DB['Login']}.html"):"./c={$USER_DB['Login']}&u={$u}" ;
$_l = static_link ? get_surl("login-{UUID}-{$USER_DB['Login']}.html"):"./?c={$USER_DB['Login']}&u={$u}" ;
}
require 'header.php';
?>
@@ -246,7 +240,7 @@ require 'header.php';
<?php }?>
<tr>
<td>用户交流</td>
<td><a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=LaIzFK2hfTYBZGR0cKvW3xZL6aNgcSXH&jump_from=webapi&authKey=LHh1NtAiGdK0wNyoZiHWrzAZTWWq26YgAwX0Ak7rBWchh6Y5ocUX/0cCXLMXvq/k" title="TwoNav - 技术交流">QQ群695720839</a>
<td><a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=dMXOVXaYcnKMVmPsqBqpeSxcszy-z4vT&jump_from=webapi&authKey=SQArXAovtNKkH4VGv2Uy6p9wITMQxtjx8W2xLxCKkw3IOwXqQ9H34k4K9o1p4DVQ" title="TwoNav - 技术交流2">QQ群621815595</a>
</td>
</tr>
<tr>

View File

@@ -4,6 +4,15 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
?>
<style>
.layui-btn-container .layui-btn{border-width: 1px; border-style: solid; border-color: #FF5722!important; color: #FF5722!important;background: none;height: 30px; line-height: 30px; padding: 0 10px; font-size: 12px;}
.footer{
position: fixed;
bottom: 0;
left: 0;
width: 100%;
padding: 10px;
background-color: #fff;
border-top: 1px solid #e6e6e6;
}
</style>
<body>
<div class="layuimini-container">
@@ -331,8 +340,8 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
<div class="layui-form-mid layui-word-aux">是否允许默认用户组使用自定义代码!允许存在安全隐患!</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block"><button class="layui-btn layui-btn-normal" lay-submit lay-filter="save">确认保存</button></div>
<div class="footer">
<button class="layui-btn layui-btn-normal" lay-submit lay-filter="save" style=" margin-left: 10px; ">确认保存</button>
</div>
</div>
</form>

View File

@@ -69,16 +69,22 @@ layui.use(['layer','form','miniTab'], function () {
});
//一键诊断
$('.diagnose').on('click', function(){
layer.load(0);
$("#console_log").text("");
$("#console_log").append("浏览器UA" + navigator.userAgent +"\n");
$("#console_log").append("客户端时间:" + timestampToTime(Math.round(new Date() / 1000) ) +"\n");
$.post(get_api('read_data','diagnostic_log'),function(data,status){
layer.closeLast('loading');
$("#console_log").append(data.msg);
}).fail(function(xhr, textStatus, errorThrown) {
layer.closeLast('loading');
layer.alert('请求失败');
});
});
//连通测试
$('.connectivity_test').on('click', function(){
layer.load(0);
$("#console_log").text("");
$("#console_log").append("浏览器UA" + navigator.userAgent +"\n");
$("#console_log").append("客户端时间:" + timestampToTime(Math.round(new Date() / 1000) ) +"\n");
@@ -94,12 +100,13 @@ layui.use(['layer','form','miniTab'], function () {
url: get_api('read_data', 'connectivity_test'),
type: 'POST',
data: { url: url },
async: false,
//async: false,
success: function(data, status) {
$("#console_log").append(data.msg + "\n");
},
error: function(jqXHR, textStatus, errorThrown) {
$("#console_log").append(routeName + ": 请求 " + url + " 发生错误:" + errorThrown + "\n");
layer.closeLast('loading');
$("#console_log").append(data.msg + "\n");
},error: function(jqXHR, textStatus, errorThrown) {
layer.closeLast('loading');
$("#console_log").append(routeName + ": 请求 " + url + " 发生错误:" + errorThrown + "\n");
}
});
});
@@ -146,21 +153,31 @@ layui.use(['layer','form','miniTab'], function () {
});
//清理缓存
$('.CleanCache').on('click', function(){
layer.load(0);
$.post(get_api('other_root','CleanCache'),function(data,status){
layer.closeLast('loading');
if(data.code == 1){
layer.msg(data.msg,{icon: 1})
} else{
layer.msg(data.msg,{icon: 5});
}
}).fail(function(xhr, textStatus, errorThrown) {
layer.closeLast('loading');
layer.alert('请求失败');
});
});
//数据库升级
$('.db_upgrade').on('click', function(){
layer.load(0);
$("#console_log").text("");
$("#console_log").append(`正在处理中,请勿操作页面...\n`);
$.post(get_api("other_upsys"),{"i":4,"pattern":"manual"}, function(data, status) {
layer.closeLast('loading');
$("#console_log").text("");
$("#console_log").append(`${data.msg}\n`);
}).fail(function(xhr, textStatus, errorThrown) {
layer.closeLast('loading');
layer.alert('请求失败');
});
});
});

View File

@@ -20,6 +20,16 @@ if(!empty($Notice)){
<li>3. 更新成功后就是授权版的系统了,可使用全部功能</li>
<li>4. 禁止传播/破解授权版源代码,违者封授权并追责</li>
</blockquote>
<blockquote class="layui-elem-quote layui-text" style="color:red" >
<li> 温馨提示: </li>
<li>授权是跟当前访问的域名或IP绑定的,通常建议绑定域名</li>
<li>初次保存授权时会自动激活卡密并绑定当前域名或IP</li>
<li>请不要在临时域名或临时IP中激活授权 (特殊情况请提前说明)</li>
<li>授权针对顶级域名授权,如授权www.nav.cn时,dh.nav.cn可以正常使用</li>
<li>绑定IP时部分功能会无法使用,如二级域名功能</li>
<li>激活后修改域名或IP需扣除修改次数(年授权需付费修改)</li>
<li>如有疑问请联系技术支持QQ: 271152681</li>
</blockquote>
<h3 style = "margin-bottom:1em;">当前域名:<font color="red"><?php echo $HTTP_HOST; ?></font></h3>
<div class="layui-form-item">
@@ -56,11 +66,21 @@ if(!empty($Notice)){
<input type="text" name="type_name" id ="type_name" value="<?php echo $subscribe['type_name'] ?? ''; ?>" autocomplete="off" placeholder="若未正确显示请点击保存设置" class="layui-input">
</div>
</div>
<?php if(get_db('global_config','v',["k" => "sys_switch"]) == 'show' && $subscribe['type'] == '3'){ ?>
<div class="layui-form-item">
<label class="layui-form-label">版本切换</label>
<div class="layui-input-inline" >
<select name="sys" id="sys">
<option value="biaozhun" selected>标准版</option>
<option value="gaoji" >高级版</option>
</select>
</div>
<div class="layui-form-mid layui-word-aux">希望使用的系统版本 ( 下次更新时 )</div>
</div>
<?php } ?>
<div class="layui-btn-group">
<button class="layui-btn layui-btn-normal" lay-submit lay-filter="save_key">保存</button>
<button class="layui-btn layui-btn-danger" lay-submit lay-filter="buy_vip" data-url="<?php echo empty($data['pay_rul']) ?'':$data['pay_rul']?>" >购买授权</button>
<button class="layui-btn" lay-submit lay-filter="query_key">查询授权</button>
<button class="layui-btn layui-bg-purple" type="button" id="validate" style="<?php echo empty($subscribe['order_id']) ? 'display:none;':''; ?>">正版验证</button>
</div>
@@ -101,42 +121,8 @@ layui.use(['jquery','form'], function () {
var layer = layui.layer;
var $ = layui.jquery;
var vcode;
//查询订阅
form.on('submit(query_key)', function(data){
vcode = randomnum(6);
index = layer.prompt({formType: 0,value: '',title: '请输入验证码: ' + vcode,shadeClose: false,"success":function(){
$("input.layui-layer-input").on('keydown',function(e){
if(e.which == 13) {
query_key(data);
}
});
}},function(){
query_key(data)
});
});
function query_key(data) {
layer.close(index);
if($("input.layui-layer-input").val() != vcode){
layer.msg('验证码错误', {icon: 5});
return false;
}
layer.load(2, {shade: [0.1,'#fff']});
$.post(get_api('other_services','query_key'),{'order_id':data.field.order_id,'email':data.field.email},function(data,status){
layer.closeAll('loading');
if(data.code == 200) {
$("#order_id").val(data.data.order_id);
$("#end_time").val(timestampToTime(data.data.end_time));
$("#type_name").val(data.data.type_name);
layer.msg(data.msg, {icon: 1,time: 10000});
}else{
layer.alert(data.msg,{icon:5,title:'查询结果',anim: 2,closeBtn: 0,btn: ['我知道了']});
}
}).fail(function () {
layer.msg('请求失败', {icon: 5});
});
}
$("#sys").val('<?php echo empty($subscribe['sys']) ? 'biaozhun':$subscribe['sys']; ?>');
form.render('select');
//保存订阅
form.on('submit(save_key)', function(data){
var order_id = data.field.order_id;
@@ -149,7 +135,7 @@ layui.use(['jquery','form'], function () {
return false;
}
layer.load(2, {shade: [0.1,'#fff']});
$.post(get_api('other_services','save_key'),{'order_id':data.field.order_id,'email':data.field.email},function(data,status){
$.post(get_api('other_services','save_key'),{'order_id':data.field.order_id,'email':data.field.email,'sys':data.field.sys},function(data,status){
layer.closeAll('loading');
if(data.code == 200) {
$("#order_id").val(data.data.order_id);

View File

@@ -1,4 +1,4 @@
<?php $title='主题管理';$awesome=true; require 'header.php';?>
<?php $title='主题管理';$awesome=true; define('referrer','same-origin'); require 'header.php';?>
<style>
.tab-header .layui-btn.layui-this{border-color: #1E9FFF; color: #1E9FFF;}
.screenshot{
@@ -25,7 +25,6 @@
<script src="<?php echo $libs;?>/jquery/jquery.lazyload.min.js"></script>
<script src="./templates/admin/js/public.js?v=<?php echo $Ver;?>"></script>
<?php load_static('js');?>
<script src="./templates/admin/js/theme.js?v=<?php echo $Ver;?>"></script>
<script>
const is_admin = <?php echo $USER_DB['UserGroup'] === 'root' ? 'true' : 'false'; ?>;
const theme_set = <?php echo check_purview('theme_set',1) ? 'true' : 'false'; ?>;
@@ -33,4 +32,5 @@
const guestbook = <?php echo check_purview('guestbook',1) ? 'true' : 'false'; ?>;
const article = <?php echo check_purview('article',1) ? 'true' : 'false'; ?>;
const loginAddress = '<?php echo $USER_DB['Login']; ?>';
</script>
</script>
<script src="./templates/admin/js/theme.js?v=<?php echo $Ver;?>"></script>

View File

@@ -5,7 +5,117 @@
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis"></i>
<div class="layui-timeline-content layui-text">
<h4 class="layui-timeline-title">v2.1.02-20231012</h4>
<h4 class="layui-timeline-title">v2.1.12-20240308</h4>
<ul>
<li>[优化] 后台概要页支持时间差异较大提示,避免因时间错误导致的各种问题</li>
<li>[新增] 站点设置新增重复链接选项,解决部分用户需要添加相同链接的问题</li>
<li>[升级] Layui组件由2.9.2升级到2.9.7</li>
<li>[变更] 默认配置调整,概要页QQ群改为免费用户群(授权用户可凭授权加入会员群)</li>
</ul>
</div>
</li>
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis"></i>
<div class="layui-timeline-content layui-text">
<h4 class="layui-timeline-title">v2.1.11-20240119</h4>
<ul>
<li>[修复] 链接识别遇到中文域名时提示URL无效</li>
<li>[修复] 链接模式为隐私保护(header)时中文域名无法跳转</li>
<li>[修复] 主链优先设为强制优先时不起作用</li>
<li>[优化] 一键诊断缺少intl扩展模块时给出提醒</li>
</ul>
</div>
</li>
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis"></i>
<div class="layui-timeline-content layui-text">
<h4 class="layui-timeline-title">v2.1.09-20231220</h4>
<ul>
<li>[修复] 紧急修复一个影响登录的bug,影响范围:v2.1.08版本 + MySQL数据库</li>
</ul>
</div>
</li>
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis"></i>
<div class="layui-timeline-content layui-text">
<h4 class="layui-timeline-title">v2.1.08-20231219</h4>
<ul>
<li>[升级] Layui组件由2.9.0升级到2.9.2</li>
<li>[修复] Atool工具和用户管理中强制修改用户密码时未将已登录的终端踢下线的bug</li>
<li>[优化] 概要页面更新内容直接从服务器获取并显示,不需要在跳转到Gitee上查看</li>
<li>[优化] 主题管理:可更新时在右上显示一个问号,点击可以查看更新内容</li>
<li>[变更] 普通账号不在支持自定义登录模板,只有站长号可以选择和配置模板</li>
<li>[优化] 系统设置的保存按钮改为悬浮在页面底部,避免老是要滚动到底部去点保存的问题</li>
<li>[修复] 链接列表手机端不显示删除按钮的问题</li>
<li>[修复] 书签分享特定条件下存在的bug</li>
<li>[修复] 安全设置>登录保持设为浏览器关闭会导致无法登录的bug</li>
<li>[修复] OTP双重认证使用公用登录入口时无法输入验证码的问题 ( 需更新登录模板 )</li>
<li>[模板] [12.02]爱导航V1: 配置选项新增分类收缩,可选仅图标/分类/菜单/目录,用于解决部分手机端用户不知道点这个图标展开分类的问题</li>
<li>[模板] [12.02]百素New: 新增拖拽排序功能、修复未加载用户header和全局header的bug、新增搜索框背景自定义支持</li>
<li>[模板] [12.20]花森主页: 调整本地添加链接时判断是否为URL的条件,仅检测http(s)://开头</li>
<li>[修复] [12.20]WebStack-Hugo: 夜间模式下搜索框热词点空白处没有取消热词显示的问题</li>
</ul>
</div>
</li>
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis"></i>
<div class="layui-timeline-content layui-text">
<h4 class="layui-timeline-title">v2.1.06-20231114</h4>
<ul>
<li>[修复] 开启离线模式时概要页依旧获取在线数据,V0921</li>
<li>[优化] 为部分操作添加处理中的效果( 防止网络极差的用户以为没点到而重复点击 )</li>
<li>[新增] 内置用户组新增:访客 (代号:visitor,处于该用户组的账号登录后跳转到默认用户的主页,配合引导页使用实现需注册登录才能访问站点)</li>
<li>[备注] 由于访客无权限进入后台,所以也无法自助修改密码</li>
<li>[新增] 在用户组列表中显示内置用户组 ( 默认/访客/站长 )</li>
<li>[变更] 系统设置中的默认分组允许设置为内置用户组 ( 例如设为访客 )</li>
<li>[新增] 访问限制 (右上角账号下拉),可设置:无限制/白名单/黑名单,具体查看页面中的说明</li>
</ul>
</div>
</li>
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis"></i>
<div class="layui-timeline-content layui-text">
<h4 class="layui-timeline-title">v2.1.05-20231107</h4>
<ul>
<li>[修复] 使用MySQL/MariaDB数据库时记录访客IP错误</li>
<li>[修复] 注册模板/引导页模板配置无法正常读取</li>
<li>[模板] 主页模板新增 > Snavigation ( 简约型的模板,点击时间显示书签数据 )</li>
<li>[模板] 引导页模板新增 > 無名の主页</li>
<li>[模板] WebStack-Hugo > 搜索栏新增站内搜索选项,用于解决同时开启站内搜索和搜索热词时遮挡问题</li>
<li>[模板] 挽风导航V1.0 > CSS样式细节优化 </li>
</ul>
</div>
</li>
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis"></i>
<div class="layui-timeline-content layui-text">
<h4 class="layui-timeline-title">v2.1.04-20231101</h4>
<ul>
<li>[修复] 连续添加分类时未正确添加到所选的父分类中</li>
<li>[修复] 使用MySQL/MariaDB数据库时文章图片可能不显示的bug</li>
<li>[优化] 二级域名功能支持已知的双后缀顶级域名(例如example.com.cn)</li>
<li>[新增] Docker镜像增加intl模块</li>
<li>[模板] WebStack-Hugo > 修复过渡页模板logo设置无效</li>
</ul>
</div>
</li>
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis"></i>
<div class="layui-timeline-content layui-text">
<h4 class="layui-timeline-title">v2.1.03-20231020</h4>
<ul>
<li>[修复] 站点地图时间格式问题</li>
<li>[修复] 后台我的主页地址错误</li>
<li>[变更] 移除授权管理页查询授权功能 ( 如需查询请联系客服 )</li>
<li>[优化] 使用过渡页模板时若站点设置>链接模式不是过渡页面时自动修改配置</li>
<li>[模板] WebStack-Hugo > 修复二级分类横向滚动条过大/顶部的管理入口未遵循系统设置是否显示</li>
</ul>
</div>
</li>
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis"></i>
<div class="layui-timeline-content layui-text">
<h4 class="layui-timeline-title">v2.1.02-20231013</h4>
<ul>
<li>[优化] IP统计的记录方式,提高性能和稳定性</li>
<li>[修复] 未在系统设置保存过设置时因缺少参数而导致部分页面加载异常</li>
@@ -17,7 +127,7 @@
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis"></i>
<div class="layui-timeline-content layui-text">
<h4 class="layui-timeline-title">v2.1.01-20231002</h4>
<h4 class="layui-timeline-title">v2.1.01-20231003</h4>
<ul>
<li>[优化] 已部署国内服务器并接入了CDN加速和3个资源节点</li>
<li>[新增] 系统设置>资源节点,可选自动/国内1/国内2/海外1</li>

View File

@@ -2,9 +2,9 @@
<html>
<head>
<meta charset="utf-8" />
<title><?php echo $site['Title'];?></title>
<meta name="keywords" content="<?php echo $site['keywords']; ?>">
<meta name="description" content="<?php echo $site['description']; ?>">
<title><?php echo $s_site['title'];?></title>
<meta name="keywords" content="<?php echo $s_site['keywords']; ?>">
<meta name="description" content="<?php echo $s_site['description']; ?>">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<link rel="stylesheet" href="<?php echo $theme_dir;?>/main.css" />
<link rel="shortcut icon" href="<?php echo $favicon;?>">

View File

@@ -2,8 +2,8 @@
"name": "默认模板",
"description": "模板来自于html5up.net",
"homepage": "https://gitee.com/tznb/TwoNav",
"version": "2.1.0",
"update": "2023/09/28",
"version": "2.1.1",
"update": "2023/11/27",
"author": "TwoNav",
"config": {
"title":"",

View File

@@ -1,5 +1,4 @@
<?php if(!defined('DIR')){header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit;}
$LoginConfig = unserialize($USER_DB['LoginConfig']);?>
<?php if(!defined('DIR')){header('HTTP/1.1 404 Not Found');header("status: 404 Not Found");exit;}?>
<!DOCTYPE html>
<html>
<head>
@@ -31,20 +30,14 @@ $LoginConfig = unserialize($USER_DB['LoginConfig']);?>
<div class="center">
<div class="item">
<span class="icon layui-icon layui-icon-username"></span>
<input type="text" name="User" lay-verify="required" placeholder="请输入账号">
<input type="text" name="username" lay-verify="required" placeholder="请输入账号">
</div>
<div class="item">
<span class="icon layui-icon layui-icon-password"></span>
<input type="password" name="Password" lay-verify="required" placeholder="请输入密码">
<input type="password" name="password" lay-verify="required" placeholder="请输入密码">
<span class="bind-password icon icon-4"></span>
</div>
<?php if(!empty($LoginConfig['totp_key'])){ ?>
<div class="item">
<span class="icon layui-icon layui-icon-vercode"></span>
<input type="text" name="otp_code" lay-verify="required" placeholder="请输入OTP验证码">
</div>
<?php }?>
</div>
<div class="tip">
<?php
@@ -83,28 +76,73 @@ $LoginConfig = unserialize($USER_DB['LoginConfig']);?>
});
// 进行登录操作
form.on('submit(login)', function (data) {
data = data.field;
if (data.User == '') {
layer.msg('用户名不能为空');
return false;
}
if (data.Password == '') {
layer.msg('密码不能为空');
return false;
}
data.Password = $.md5(data.Password);
$.post('./index.php?c=<?php echo $c; ?>&u='+data.User,data,function(re,status){
if(re.code == 1) {
window.location.href = re.url;
//账号登录
form.on('submit(login)', function($form) {
let url = `./?c=auth&mode=uname&t=` + Math.round(new Date() / 1000);
form_data = $form.field;form_data.keep = 'on';
form_data.password = $.md5(form_data.password);
let load = layer.msg('正在登录..', {icon: 16,shade: [0.1, '#f5f5f5'],scrollbar: false,offset: 'auto',time: 60*1000});
$.post(url,form_data,function(data,status){
layer.close(load);
if(data.code == 1) {
layer.msg('登录成功', {icon: 1,shade: [0.1, '#f5f5f5'],scrollbar: false,offset: 'auto',time: 888,
end: function() {
window.location.href = data.url;
}
});
}else if(data.code == 2){
//双重认证
layer.open({
type: 1,
title: false,
content: $('.OTP'),
move: '.move',
success: function(layero, index, that){
//监听回车事件
$('input[name="otp_code"]').keydown(function(event) {
if (event.which === 13) {
$('button[lay-filter="validate_otp"]').click();
}
});
//监听点击事件
form.on('submit(validate_otp)', function ($form2) {
form_data.otp_code = $form2.field.otp_code
let load = layer.msg('正在验证..', {icon: 16,shade: [0.1, '#f5f5f5'],scrollbar: false,offset: 'auto',time: 60*1000});
$.post(url,form_data,function(data,status){
layer.close(load);
if(data.code == 1) {
layer.msg('登录成功', {icon: 1,shade: [0.1, '#f5f5f5'],scrollbar: false,offset: 'auto',time: 888,
end: function() {
window.location.href = data.url;
}
});
}else{
layer.msg(data.msg, {icon: 5});
}
});
return false;
});
}
});
}else{
layer.msg(re.msg, {icon: 5});
layer.msg(data.msg, {icon: 5});
}
});
return false;
return false;
});
});
</script>
</body>
</html>
</html>
<ul class="OTP" style="display:none;">
<div class="layui-form layuimini-form layui-form-pane" style="padding: 20px 30px;">
<div class="move" style="height: 30px;margin-bottom: 15px;text-align: center;font-size: 21px;">动态口令认证</div>
<div class="layui-form-item">
<div class="layui-input-group" style="width: 100%;">
<input type="text" name="otp_code" lay-verify="required" lay-reqtext="请输入动态口令" placeholder="请输入动态口令" style="text-align: center;" class="layui-input" lay-affix="clear">
</div>
</div>
<div class="layui-input-block" style="margin-left: 1px;"><button type="button" class="layui-btn layui-btn-fluid" lay-submit lay-filter="validate_otp">验证并登录</button></div>
<div style="margin-top: 16px;font-size: 13px;color: #777;">* 如果您无法认证,请联系站长处理</div>
</div>
</ul>

View File

@@ -2,7 +2,7 @@
"name": "默认模板",
"description": "默认",
"homepage": "https://gitee.com/tznb/TwoNav",
"version": "2.1.0",
"update": "2023/09/28",
"version": "2.1.1",
"update": "2023/12/20",
"author": "TwoNav"
}