Compare commits

..

2 Commits

Author SHA1 Message Date
MI15\Win
5c7136ff0f v2.0.36-20230823 2023-08-23 16:33:53 +08:00
MI15\Win
86be0ca786 v2.0.35-20230816 2023-08-16 01:14:09 +08:00
19 changed files with 155 additions and 25 deletions

View File

@@ -1,4 +1,4 @@
TwoNav 是一款开源免费的书签导航管理程序界面简洁安装简单使用方便。TwoNav可帮助你将浏览器书签集中式管理解决跨设备、跨平台、跨浏览器之间同步和访问困难问题做到一处部署随处访问。
TwoNav 是一款开源的书签(导航)管理程序,界面简洁,安装简单,使用方便,基础功能免费。TwoNav可帮助你将浏览器书签集中式管理解决跨设备、跨平台、跨浏览器之间同步和访问困难问题做到一处部署随处访问。
- **演示站**: [http://two.lm21.top](http://two.lm21.top)
- **仅供体验,定期清理数据** 账号密码`admin`

View File

@@ -165,6 +165,14 @@ if(!empty($_GET['type'])){
update_db("user_login_info", ["user" => $_POST['new_user_name']], ["user" => $USER['User']]);
update_db("user_log", ["user" => $_POST['new_user_name']], ["user" => $USER['User']]);
update_db("global_user", ["User" => $_POST['new_user_name']], ["ID" => $_POST['ID']],[1,'操作成功']);
}elseif($_GET['type'] == 'del_otp'){
$user_data = get_db('global_user','*',['ID'=>$_POST['ID']]);
$LoginConfig = unserialize($user_data['LoginConfig']);
if(empty($LoginConfig['totp_key'])){
msgA(['code'=>-1,'msg'=>'当前账号未开启OTP双重验证']);
}
$LoginConfig['totp_key'] = '';
update_db("global_user", ["LoginConfig" => $LoginConfig], ["ID" => $_POST['ID']],[1,'操作成功']);
}
msgA(['code'=>-1,'msg'=>'请求类型错误']);
@@ -267,6 +275,7 @@ function echo_Atool(){
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="set_pwd">改密码</a>
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="set_root">设站长</a>
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="set_user_name">改账号</a>
<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.10/layui.js"></script>
@@ -280,7 +289,7 @@ function echo_Atool(){
var table = layui.table;
var cols = [[
{field:'ID',title:'ID',width:60,sort:true}
,{title:'操作',toolbar:'#tablebar',width:175}
,{title:'操作',toolbar:'#tablebar',width:220}
,{field:'User',title:'账号',minWidth:120,templet:function(d){
return '<a style="color:#3c78d8" title="打开用户主页" target="_blank" href="../?u='+d.User+'">'+d.User+'</a>'
}}
@@ -359,6 +368,14 @@ function echo_Atool(){
}
});
});
}else if(obj.event == 'del_otp'){
$.post('./ATool.php?type=del_otp',{ID:data.ID},function(data,status){
if(data.code == 1) {
layer.msg(data.msg, {icon: 1});
}else{
layer.msg(data.msg, {icon: 5});
}
});
}
});
$('.set').click(function () {

View File

@@ -208,7 +208,7 @@ if ($page == 'menu') {
if($global_config['guestbook'] == 1 && check_purview('guestbook',1)){
array_push($extend,['title'=>'留言管理','href'=>'expand/guestbook-admin','icon'=>'fa fa-commenting-o']);
}
if($global_config['article'] == 1 && check_purview('article',1)){
if($global_config['article'] > 0 && check_purview('article',1)){
array_push($extend,['title'=>'文章管理','href'=>'expand/article-list','icon'=>'fa fa-file-text-o']);
}
if(!empty($extend)){

View File

@@ -1820,6 +1820,22 @@ function read_data(){
$data = ['dates'=>$dates,'day_data'=>$day_data];
msgA(['code'=>1,'data'=>$data]);
}elseif($_GET['type'] == 'tongji_ip_list'){
$days = isset($_GET['date']) && !empty($_GET['date']) ? $_GET['date'] : 7;
$dates = [];
for ($i = 0; $i < $days; $i++) {
$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);
$day_data[$date] = empty($list) ? [] : $list ;
}
msgA(['code'=>1,'data'=>$day_data]);
}
}

View File

@@ -3,7 +3,7 @@
$type = htmlspecialchars(trim($_GET['type']),ENT_QUOTES);
if (function_exists($type) ) {
if($GLOBALS['global_config']['article'] != 1 || !check_purview('article',1)){
if($GLOBALS['global_config']['article'] < 1 || !check_purview('article',1)){
msg(-1,'无权限');
}
$type();

View File

@@ -352,6 +352,25 @@ function write_user_info(){
delete_db('global_user',["ID" => $uids]);
msg(1,'删除成功');
break;
//删除OTP验证
case "Del_OTP":
$uids = json_decode($_POST['ID']);
$USER_S = select_db('global_user',['LoginConfig','ID','User'],['ID'=>$uids]);
$fail = 0;
foreach($USER_S as $USER){
$LoginConfig = unserialize($USER['LoginConfig']);
if(empty($LoginConfig['totp_key'])){
$fail ++;
continue;
}
$LoginConfig['totp_key'] = '';
update_db("global_user", ["LoginConfig" => $LoginConfig], ["ID" => $USER['ID']]);
}
if($fail > 0){
msg(1,'操作完毕,有'.$fail.'个账号未开启OTP双重验证');
}
msg(1,'操作成功');
break;
//设用户组
case "set_UserGroup":
if(empty($_POST['UserGroup'])){
@@ -555,7 +574,7 @@ function write_sys_settings(){
'apply'=>['int'=>true,'min'=>0,'max'=>1,'msg'=>'收录管理参数错误'],
'guestbook'=>['int'=>true,'min'=>0,'max'=>1,'msg'=>'留言管理参数错误'],
'link_extend'=>['int'=>true,'min'=>0,'max'=>1,'msg'=>'链接扩展参数错误'],
'article'=>['int'=>true,'min'=>0,'max'=>1,'msg'=>'文章管理参数错误']
'article'=>['int'=>true,'min'=>0,'max'=>2,'msg'=>'文章管理参数错误']
];
$o_config = [];
foreach ($datas as $key => $data){

View File

@@ -1,5 +1,5 @@
<?php if(!defined('DIR')){Not_Found();}AccessControl();
if($global_config['article'] == 0 | !check_purview('article',1)){
if($global_config['article'] < 1 | !check_purview('article',1)){
Not_Found();
}

View File

@@ -129,7 +129,6 @@ function get_links($fid) {
$where['ORDER']['lid'] = 'ASC';
if(!is_login){
$where['property'] = 0;
}
//书签分享>私有可见
if(isset($share['pv']) && $share['pv'] == 1){

View File

@@ -713,10 +713,10 @@ function send_email($config){
$mail->SMTPSecure = $config['secure'];
$mail->Port = intval($config['port']);
if(preg_match('/(.+)<(.+)>/', $config['sender'], $match)){
if(preg_match('/(.+)<(.+@.+)>$/', $config['sender'], $match)){
$mail->setFrom($match[2],$match[1]);
}else{
$mail->setFrom($config['sender']);
$mail->setFrom($config['user'],empty($config['sender'])?'TwoNav':$config['sender']);
}
$mail->addAddress($config['addressee']); //收件人

View File

@@ -28,7 +28,7 @@ if(empty($c) || in_array($c,['index','click','article'])){
function is_apply(){
global $global_config;
$apply_user = unserialize( get_db("user_config", "v", ["k" => "apply","uid"=>UID]));
return ($global_config['apply'] == 1 && $apply_user['apply'] == 1);
return ($global_config['apply'] == 1 && $apply_user['apply'] > 0);
}
//是否启用留言
function is_guestbook(){

View File

@@ -1 +1 @@
v2.0.34-20230809
v2.0.36-20230823

View File

@@ -69,15 +69,16 @@
<label class="layui-form-label">链接图标</label>
<div class="layui-input-inline" >
<select name="link_icon">
<option value="0" selected>离线图标</option>
<option value="0" selected>离线图标(首字图标)</option>
<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="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>

View File

@@ -1,8 +1,25 @@
<?php
if($global_config['article'] != 1 || !check_purview('article',1)){
if($global_config['article'] < 1 || !check_purview('article',1)){
require(DIR.'/templates/admin/page/404.php');
exit;
}
// if($global_config['article'] == 2 ){
// if(is_file(DIR.'/static/UEditor/ueditor.all.min.js')){
// require('article-edit-2.php');
// exit;
// }else{
// $content = '未检测到UEditor资源';
// require DIR.'/templates/admin/page/404.php';
// exit;
// }
// }
if(!is_file(DIR.'/static/wangEditor/wangEditor.css') || !is_file(DIR.'/static/wangEditor/wangEditor.js')){
$content = '由于缺少静态资源,当前无法加载编辑器!<br />如果您是站长,请在系统设置页面点击确定保存,系统将自动下载相关资源!<br />如果您是用户,请联系站长处理或耐心等候!';
require DIR.'/templates/admin/page/404.php';
exit;
}
$article_id = Get('id');
$mode = empty($article_id) ? 'add' : 'edit' ;

View File

@@ -1,5 +1,5 @@
<?php
if($global_config['article'] != 1 || !check_purview('article',1)){
if($global_config['article'] < 1 || !check_purview('article',1)){
require(DIR.'/templates/admin/page/404.php');
exit;
}

View File

@@ -242,7 +242,7 @@ require 'header.php';
<div class="layui-card">
<div class="layui-card-header">
<div style="display: flex; justify-content: space-between;">
<div><i class="fa fa-line-chart icon"></i>报表统计</div>
<div id="tongji" style="cursor: pointer;"><i class="fa fa-line-chart icon" ></i>报表统计</div>
<div>
<button class="layui-btn layui-btn-primary echarts" style="border: none;display:none;"><span>最近7天</span><i class="layui-icon layui-icon-down layui-font-12"></i></button>
</div>
@@ -359,6 +359,26 @@ if($USER_DB['UserGroup'] == 'root'){
}
});
$('#tongji').on('click', function(){
$.post('./index.php?c=api&method=read_data&date='+home_echarts+'&type=tongji_ip_list&u='+u,function(data,status){
if(data.code == 1){
var content = '<table class="layui-table" border="1"><thead><tr><th>日期</th><th>IP列表</th></tr></thead><tbody>';
$.each(data.data, function (date, ipAddresses) {
content += '<tr><td>' + date + '</td><td>';
$.each(ipAddresses, function (index, ipAddress) {
content += ipAddress + '<br>';
});
content += '</td></tr>';
});
content += '</tbody></table>';
layer.open({
title: '访问IP列表',
content: content,
area: ['100%', '100%']
});
}
});
});
//加载报表统计
function load_echarts(){
var echartsRecords = echarts.init(document.getElementById('echarts-records'), 'walden');

View File

@@ -56,9 +56,9 @@ $title='系统设置';require(dirname(__DIR__).'/header.php');
<div class="layui-form-item">
<label class="layui-form-label">发送人</label>
<div class="layui-input-inline">
<input type="text" name="sender" lay-verify="required" lay-reqtext="发送人邮箱不能为空" placeholder='' autocomplete="off" class="layui-input">
<input type="text" name="sender" lay-verify="required" lay-reqtext="发送人名称不能为空" placeholder='' autocomplete="off" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux">例如: TwoNav书签&lt;test@qq.com&gt;</div>
<div class="layui-form-mid layui-word-aux">例如: TwoNav</div>
</div>
<div class="layui-form-item">

View File

@@ -35,6 +35,7 @@ $user_groups = select_db('user_group',['id','code','name'],'');
<script type="text/html" id="user_tool">
<div class="layui-btn-group">
<button class="layui-btn layui-btn-sm layui-btn-danger" lay-event="Del">删除</button>
<button class="layui-btn layui-btn-sm layui-btn-danger" lay-event="Del_OTP" title="移除OTP双重验证">移除OTP验证</button>
<button class="layui-btn layui-btn-sm" lay-event="register" <?php echo $global_config['RegOption'] == 0? 'style = "display:none;"':'' ?> >注册账号</button>
<button class="layui-btn layui-btn-sm" lay-event="set_UserGroup">设用户组</button>
<button class="layui-btn layui-btn-sm" lay-event="username_retain">账号保留</button>
@@ -163,6 +164,16 @@ layui.use(['table','layer','form'], function () {
}else if(event == 'set_UserGroup'){
IDs = tableIds;
index = layer.open({type: 1,scrollbar: false,shadeClose: true,title: '修改用户组',area : ['100%', '100%'],content: $('.set_UserGroup')});
}else if(event == 'Del_OTP'){
layer.alert("以下账号将被移除OTP双重验证,确定继续吗?<br />"+table_Users,{icon:3,title:'确认操作',anim: 2,closeBtn: 0,btn: ['确定','取消']},function () {
$.post(get_api('write_user_info','Del_OTP'),{ID:tableIds},function(data,status){
if(data.code == 1){
layer.msg(data.msg,{icon: 1})
} else{
layer.msg(data.msg,{icon: 5});
}
});
});
}
});
//行工具

View File

@@ -2,6 +2,35 @@
<body>
<div class="layuimini-container">
<div class="layuimini-main" style=" margin-left: 20px;">
<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.0.36-20230823</h4>
<ul>
<li>[修复] 判断是否显示收录的逻辑错误(导致设为无需审核时不显示)</li>
<li>[变更] 移除2个链接图标API,因稳定性欠佳</li>
<li>[修复] WebStack-Hugo主页模板悬停提示不显示</li>
<li>[新增] 挽风导航主页模板(内置文章模板/拟态风格),注:内置文章模板在预览状态下是不生效的!</li>
<li>[新增] 挽风导航登录模板/过度模板</li>
<li>[新增] 后台概要页可以点击报表统计获取访问的IP列表</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.0.35-20230816</h4>
<ul>
<li>[新增] Atool工具箱增加关闭OTP双重验证选项(删OTP),用于解决站长丢失OTP令牌造成无法登录</li>
<li>[新增] 用户管理支持关闭OTP双重验证选项,用于站长帮助用户关闭OTP双重验证</li>
<li>[优化] 邮件配置发送人只填发送人名称未按要求格式填写邮箱时由系统自动完成拼接</li>
<li>[优化] 文章管理特定情况造成缺少资源时提醒用户如何解决</li>
<li>[模板] 新增爱导航V1主页模板,轻量化设计简洁不卡顿/支持缓存/自适应/站内搜索,适合书签多的用户使用</li>
<li>[模板] WebStack-Hugo主页模板新增:夜间背景图/炫彩横幅</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">

View File

@@ -1,15 +1,16 @@
<!DOCTYPE html>
<html lang="zh-cn" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<meta charset="utf-8">
<title><?php echo $link['title']; ?> - <?php echo $site['title']; ?></title>
<meta name="keywords" content="<?php echo $link['keywords']; ?>" />
<meta name="description" content="<?php echo $link['description']; ?>" />
<meta name="keywords" content="<?php echo $link['keywords']; ?>">
<meta name="description" content="<?php echo $link['description']; ?>">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="<?php echo $libs?>/bootstrap4/css/bootstrap.min.css" type="" media=""/>
<meta http-equiv = "X-UA-Compatible" content = "IE=edge" >
<link rel="stylesheet" href="<?php echo $libs?>/bootstrap4/css/bootstrap.min.css" crossorigin="anonymous">
<link rel="shortcut icon" href="<?php echo $favicon;?>">
<!--<script src="<?php echo $libs?>/jquery/jquery-2.2.4.min.js"></script>-->
<!--<script src="<?php echo $libs?>/bootstrap4/js/bootstrap.min.js"></script>-->
<script src="<?php echo $libs?>/jquery/jquery-2.2.4.min.js"></script>
<script src="<?php echo $libs?>/bootstrap4/js/bootstrap.min.js" crossorigin="anonymous"></script>
<style>
.a_d img{
max-width:100%;