From 57b99ccd5cbce6b12b92f3206251bba2115022d0 Mon Sep 17 00:00:00 2001
From: "Mr.April"
Date: Fri, 22 Aug 2025 03:53:30 +0000
Subject: [PATCH 1/7] !16 !15 Update README.md * !15 Update README.md * Update
README.md
---
README.md | 38 +++++++++++++++++---------------------
1 file changed, 17 insertions(+), 21 deletions(-)
diff --git a/README.md b/README.md
index e392fa8..afd4e0c 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,6 @@
Webman官方文档
-
## 开源单用户独立版本快速开发框架
我们致力于提供一个卓越、简约且美观的开源单用户独立应用开发框架。秉持“取之于开源,回馈于开源”的理念,我们希望为开发者节省宝贵时间,让他们能够享受生活的每一刻——无论是休闲放松、自我提升、陪伴家人、健身锻炼,还是邂逅美好。
@@ -33,18 +32,22 @@
### 基础架构
- 多租户体系:产品订阅、初始数据、独立数据源等企业级功能
- 权限管理:完整的RBAC权限控制系统
+
### 组织架构
- 用户管理:系统操作者配置中心
- 部门架构:树形组织管理,支持数据权限
- 岗位管理:职务体系配置
+
### 系统管理
- 菜单权限:菜单/操作/按钮权限精细控制
- 角色管理:菜单权限分配+数据范围划分
- 字典系统:常用数据标准化维护
+
### 监控审计
- 通知公告:系统消息发布平台
- 操作日志:完整记录正常与异常操作
- 登录审计:包含异常登录监控
+
### 设计哲学
大道至简 —— 我们坚持:
@@ -53,39 +56,32 @@
- 架构清晰明了
- 无论是前端还是后端开发,都能享受**"快就完事了"**的编程体验。
-
## 环境需求
为了确保系统的正常运行,请确保您的服务器环境满足以下要求:
-- PHP:版本需 >= 8.1,并开启以下扩展:
-- mbstring:用于多字节字符串处理。
-- json:支持JSON数据的编码和解码。
-- pdo:提供统一的数据库访问接口。
-- openssl:用于加密和解密操作,保障数据传输安全。
-- redis:支持Redis缓存和数据存储。
-- pcntl:用于多进程控制。
-- Mysql:版本需 >= 5.7,作为系统的主要数据库存储数据。
-- Redis:版本需 >= 4.0,用于缓存数据,提高系统性能。
-- Git:版本需 >= 2.x,方便代码的版本管理和协作开发。
-- Composer:版本需 >= 2.x,用于PHP依赖管理。
-
+- **PHP**:版本需 >= 8.1,并开启以下扩展:
+ - mbstring:用于多字节字符串处理。
+ - json:支持JSON数据的编码和解码。
+ - pdo:提供统一的数据库访问接口。
+ - openssl:用于加密和解密操作,保障数据传输安全。
+ - redis:支持Redis缓存和数据存储。
+ - pcntl:用于多进程控制。
+- **Mysql**:版本需 >= 5.7,作为系统的主要数据库存储数据。
+- **Redis**:版本需 >= 4.0,用于缓存数据,提高系统性能。
+- **Git**:版本需 >= 2.x,方便代码的版本管理和协作开发。
+- **Composer**:版本需 >= 2.x,用于PHP依赖管理。
## 体验地址
-
[体验地址](https://admin.madong.tech) https://admin.madong.tech
- 账号:admin
- 密码:123456
-期待您的使用和反馈,我们将不断优化和完善系统,为您提供更优质的服务。
-
+期待您的使用和反馈,我们将不断优化和完善系统,为您提供更优质的服务。
## 官方社区
欢迎加入我们的官方社区交流互动
-
## 共同交流
-
-
## 加入我们
-欢迎加入技术交流群,与核心开发者直接沟通(扫码添加作者微信进群),共同打造更强大的开源企业级平台!
+欢迎加入技术交流群,与核心开发者直接沟通(扫码添加作者微信进群),共同打造更强大的开源企业级平台!
\ No newline at end of file
--
Gitee
From d2e4bab3940e67cc5da4fd9e2aff9b114df7528c Mon Sep 17 00:00:00 2001
From: "Mr.April"
Date: Fri, 22 Aug 2025 13:14:03 +0800
Subject: [PATCH 2/7] =?UTF-8?q?fix:=E5=AE=89=E8=A3=85=E5=AE=8C=E7=B3=BB?=
=?UTF-8?q?=E7=BB=9F=E5=90=8E=E6=97=A0=E6=B3=95=E8=BF=9B=E5=85=A5=E5=90=8E?=
=?UTF-8?q?=E5=8F=B0=20https://gitee.com/motion-code/madong-admin/issues/I?=
=?UTF-8?q?CS5TN?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
server/plugin/install/app/functions.php | 32 ++++++++++++-------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/server/plugin/install/app/functions.php b/server/plugin/install/app/functions.php
index f1a4eef..3986b9a 100644
--- a/server/plugin/install/app/functions.php
+++ b/server/plugin/install/app/functions.php
@@ -130,35 +130,35 @@ function generateEnvTemplate(): string
# Database Configuration
DB_CONNECTION=mysql
- DB_HOST = ~db_host~
- DB_PORT = ~db_port~
- DB_DATABASE= ~db_name~
- DB_USERNAME= ~db_user~
- DB_PASSWORD= ~db_pwd~
- DB_PREFIX = ~db_prefix~
+ DB_HOST=~db_host~
+ DB_PORT=~db_port~
+ DB_DATABASE=~db_name~
+ DB_USERNAME=~db_user~
+ DB_PASSWORD=~db_pwd~
+ DB_PREFIX=~db_prefix~
# Redis Configuration
- REDIS_HOST= ~redis_host~
- REDIS_PORT= ~redis_port~
- REDIS_PASSWORD= ~redis_pwd~
+ REDIS_HOST=~redis_host~
+ REDIS_PORT=~redis_port~
+ REDIS_PASSWORD=~redis_pwd~
REDIS_DB=0
# Queue Redis Configuration
- QUEUE_REDIS_HOST= ~redis_host~
- QUEUE_REDIS_PORT= ~redis_port~
- QUEUE_REDIS_PASSWORD= ~redis_pwd~
+ QUEUE_REDIS_HOST=~redis_host~
+ QUEUE_REDIS_PORT=~redis_port~
+ QUEUE_REDIS_PASSWORD=~redis_pwd~
QUEUE_REDIS_DB=0
QUEUE_REDIS_PREFIX=queue
# Cache Configuration
- CACHE_CUSTOM_REDIS_HOST= ~redis_host~
- CACHE_CUSTOM_REDIS_PORT= ~redis_port~
- CACHE_CUSTOM_REDIS_PASSWORD= ~redis_pwd~
+ CACHE_CUSTOM_REDIS_HOST=~redis_host~
+ CACHE_CUSTOM_REDIS_PORT=~redis_port~
+ CACHE_CUSTOM_REDIS_PASSWORD=~redis_pwd~
CACHE_CUSTOM_REDIS_DB=0
CACHE_CUSTOM_REDIS_PREFIX=cache_custom
# Feature Toggles
- APP_TASK_ENABLED=false # Timer switch
+ APP_TASK_ENABLED=false # Timer switch
APP_TENANT_ENABLED=true # Tenant mode switch
APP_TENANT_AUTO_SELECT_FIRST=false # Tenant auto
CAPTCHA_ENABLED=false # Captcha switch
--
Gitee
From 76ad3f9bd674f86e26721cadd7d70b58f6103c45 Mon Sep 17 00:00:00 2001
From: "Mr.April"
Date: Fri, 22 Aug 2025 16:48:26 +0800
Subject: [PATCH 3/7] =?UTF-8?q?fix:=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86?=
=?UTF-8?q?=E5=B7=A6=E4=BE=A7=E7=AD=9B=E9=80=89=E5=A4=B1=E6=95=88=20https:?=
=?UTF-8?q?//gitee.com/motion-code/madong-admin/issues/ICT9J1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
server/app/common/dao/system/SysAdminDao.php | 55 ++++++++++++++++----
1 file changed, 45 insertions(+), 10 deletions(-)
diff --git a/server/app/common/dao/system/SysAdminDao.php b/server/app/common/dao/system/SysAdminDao.php
index 89ce32b..51d27de 100644
--- a/server/app/common/dao/system/SysAdminDao.php
+++ b/server/app/common/dao/system/SysAdminDao.php
@@ -15,7 +15,6 @@ namespace app\common\dao\system;
use app\common\model\system\SysAdmin;
use InvalidArgumentException;
use core\abstract\BaseDao;
-use core\context\TenantContext;
class SysAdminDao extends BaseDao
{
@@ -28,11 +27,11 @@ class SysAdminDao extends BaseDao
/**
* 用户详情
*
- * @param $id
- * @param array|null $field
- * @param array|null $with
- * @param string $order
- * @param array|null $withoutScopes
+ * @param $id
+ * @param array|null $field
+ * @param array|null $with
+ * @param string $order
+ * @param array|null $withoutScopes
*
* @return SysAdmin|null
* @throws \Exception
@@ -90,17 +89,53 @@ class SysAdminDao extends BaseDao
*/
public function getList(array $where, string $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): array
{
-// $where['enabled'] = 1;//显示禁用用户列表
+ // 初始化部门ID
+ $deptId = null;
+
+ // 遍历$where数组,查找并移除dept_id条件
+ foreach ($where as $index => $condition) {
+ // 条件可能是索引数组,第一个元素是字段名
+ if (is_array($condition) && count($condition) >= 2) {
+ $fieldName = $condition[0];
+ // 如果字段名是'dept_id'
+ if ($fieldName === 'dept_id') {
+ // 根据条件数组的长度判断操作符和值的位置
+ if (count($condition) === 2) {
+ // 条件格式为 ['dept_id', 值]
+ $deptId = $condition[1];
+ } elseif (count($condition) === 3) {
+ // 条件格式为 ['dept_id', '=', 值]
+ $deptId = $condition[2];
+ }
+ // 移除这个条件
+ unset($where[$index]);
+ // 因为我们只处理一个dept_id条件,所以找到后跳出循环
+ break;
+ }
+ }
+ }
+
+ // 重新索引数组,防止父类处理时出错
+ $where = array_values($where);
+
if (empty($with)) {
$with = ['depts', 'posts', 'casbin.roles'];
}
+
$query = parent::selectModel($where, $field, $page, $limit, $order, $with, $search, $withoutScopes);
+
+ // 如果存在deptId条件,则添加关联条件
+ if (!is_null($deptId)) {
+ $query->whereHas('depts', function ($q) use ($deptId) {
+ $q->where('id', $deptId); // 假设部门模型的主键是id
+ });
+ }
+
$total = $query->count();
$items = $query->get()->makeHidden(['password', 'backend_setting']);
return [$total, $items];
}
-
/**
* 获取用户列表-角色id
*
@@ -120,7 +155,7 @@ class SysAdminDao extends BaseDao
}
$where['enabled'] = 1;//有效用户
$where['is_super'] = 0;//非顶级管理员
- $query = $this->getModel()->with(['roles'])
+ $query = $this->getModel()->with(['roles'])
->whereHas('roles', function ($query) use ($roleId) {
$query->where('id', $roleId);
});
@@ -201,7 +236,7 @@ class SysAdminDao extends BaseDao
{
$result = $this->getModel()
->where('id', $id)
- ->with(['depts', 'posts', 'casbin.roles','roles'])
+ ->with(['depts', 'posts', 'casbin.roles', 'roles'])
->first()
->makeHidden(['password', 'backend_setting']);
--
Gitee
From 685be98e59320ba7b97ff1fd6a33034f4e79e524 Mon Sep 17 00:00:00 2001
From: "Mr.April"
Date: Fri, 22 Aug 2025 16:49:26 +0800
Subject: [PATCH 4/7] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0RSA=E5=8A=A0?=
=?UTF-8?q?=E5=AF=86=E8=A7=A3=E5=AF=86=E6=A8=A1=E5=9D=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
server/core/utils/RSAService.php | 132 +++++++++++++++++++++++++++++++
1 file changed, 132 insertions(+)
create mode 100644 server/core/utils/RSAService.php
diff --git a/server/core/utils/RSAService.php b/server/core/utils/RSAService.php
new file mode 100644
index 0000000..9bbb14e
--- /dev/null
+++ b/server/core/utils/RSAService.php
@@ -0,0 +1,132 @@
+toString('PKCS1');
+ $publicPem = $privateKey->getPublicKey()->toString('PKCS8');
+
+ return [
+ 'private' => $privatePem,
+ 'public' => $publicPem,
+ ];
+ }
+
+ /**
+ * 签名
+ *
+ * @param string $data
+ * @param string $privatePem
+ *
+ * @return string
+ */
+ public static function sign(string $data, string $privatePem): string
+ {
+ $privateKey = PublicKeyLoader::loadPrivateKey($privatePem)
+ ->withHash('sha256')
+ ->withPadding(RSA::SIGNATURE_PKCS1);
+
+ return $privateKey->sign($data);
+ }
+
+ /**
+ * 验证签名
+ *
+ * @param string $data
+ * @param string $signature
+ * @param string $publicPem
+ *
+ * @return bool
+ */
+ public static function verify(string $data, string $signature, string $publicPem): bool
+ {
+ $publicKey = PublicKeyLoader::load($publicPem)
+ ->withHash('sha256')
+ ->withPadding(RSA::SIGNATURE_PKCS1);
+
+ return $publicKey->verify($data, $signature);
+ }
+
+ /**
+ * 公钥加密
+ *
+ * @param string $data
+ * @param string $publicPem
+ *
+ * @return string
+ */
+ public static function encrypt(string $data, string $publicPem): string
+ {
+ $publicKey = PublicKeyLoader::load($publicPem)->withPadding(RSA::ENCRYPTION_PKCS1);
+ return base64_encode($publicKey->encrypt($data));
+ }
+
+ /**
+ * 私钥解密
+ *
+ * @param string $cipherBase64
+ * @param string $privatePem
+ *
+ * @return string
+ */
+ public static function decrypt(string $cipherBase64, string $privatePem): string
+ {
+ $privateKey = PublicKeyLoader::loadPrivateKey($privatePem)
+ ->withPadding(RSA::ENCRYPTION_PKCS1);
+
+ $cipher = base64_decode($cipherBase64);
+ return $privateKey->decrypt($cipher);
+ }
+
+
+ /**
+ * 公钥掩码显示
+ *
+ * @param string $pem
+ * @param int $keep
+ *
+ * @return string
+ */
+ public static function maskKey(string $pem, int $keep = 20): string
+ {
+ $clean = str_replace(
+ ["\r", "\n", "-----BEGIN PUBLIC KEY-----", "-----END PUBLIC KEY-----"],
+ '',
+ $pem
+ );
+ $len = strlen($clean);
+ return substr($clean, 0, $keep) . '...' . substr($clean, -$keep);
+ }
+}
--
Gitee
From 81f6dc1c794a79116f608c718e1d5c55ca63262c Mon Sep 17 00:00:00 2001
From: "Mr.April"
Date: Fri, 22 Aug 2025 16:50:34 +0800
Subject: [PATCH 5/7] =?UTF-8?q?fix:=20"=E5=81=8F=E5=A5=BD=E8=AE=BE?=
=?UTF-8?q?=E7=BD=AE"=E7=9A=84=E9=97=AE=E9=A2=98=20https://gitee.com/motio?=
=?UTF-8?q?n-code/madong-admin/issues/ICS5VB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
web/pnpm-lock.yaml | 5 +++++
.../layouts/widgets/preferences/preferences-drawer.vue | 9 ++++++++-
web/src/locale/effects/langs/en-US/preferences.json | 2 ++
web/src/locale/effects/langs/zh-CN/preferences.json | 2 ++
4 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml
index 510e477..9d82a9b 100644
--- a/web/pnpm-lock.yaml
+++ b/web/pnpm-lock.yaml
@@ -2317,6 +2317,9 @@ packages:
js-tokens@9.0.1:
resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==}
+ jsencrypt@3.5.4:
+ resolution: {integrity: sha512-kNjfYEMNASxrDGsmcSQh/rUTmcoRfSUkxnAz+MMywM8jtGu+fFEZ3nJjHM58zscVnwR0fYmG9sGkTDjqUdpiwA==}
+
jsesc@3.1.0:
resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
engines: {node: '>=6'}
@@ -6113,6 +6116,8 @@ snapshots:
js-tokens@9.0.1: {}
+ jsencrypt@3.5.4: {}
+
jsesc@3.1.0: {}
json5@2.2.3: {}
diff --git a/web/src/components/common/effects/layouts/widgets/preferences/preferences-drawer.vue b/web/src/components/common/effects/layouts/widgets/preferences/preferences-drawer.vue
index e263d30..ec0b532 100644
--- a/web/src/components/common/effects/layouts/widgets/preferences/preferences-drawer.vue
+++ b/web/src/components/common/effects/layouts/widgets/preferences/preferences-drawer.vue
@@ -58,6 +58,8 @@ import {
import { SystemUserApi } from '#/api/system/user';
import { SaveOutlined } from '@ant-design/icons-vue';
+import { message as antMessage } from 'ant-design-vue';
+
const emit = defineEmits<{ clearPreferencesAndLogout: [] }>();
const message = globalShareState.getMessage();
@@ -225,7 +227,12 @@ async function handleCopy() {
async function handleUserPreferences(){
const {theme}= preferences;
const api=new SystemUserApi();
- await api.preferences({theme});
+ try {
+ await api.preferences({theme});
+ antMessage.success($t('preferences.savePreferencesSuccess'));
+ } catch (error) {
+ antMessage.error($t('preferences.savePreferencesFailed'));
+ }
}
diff --git a/web/src/locale/effects/langs/en-US/preferences.json b/web/src/locale/effects/langs/en-US/preferences.json
index db83a97..e31364e 100644
--- a/web/src/locale/effects/langs/en-US/preferences.json
+++ b/web/src/locale/effects/langs/en-US/preferences.json
@@ -29,6 +29,8 @@
"plain": "Plain",
"rounded": "Rounded",
"save":"Save",
+ "savePreferencesSuccess": "Preferences saved successfully",
+ "savePreferencesFailed": "Failed to save preferences",
"copyPreferences": "Copy Preferences",
"copyPreferencesSuccessTitle": "Copy successful",
"copyPreferencesSuccess": "Copy successful, please override in `src/preferences.ts` under app",
diff --git a/web/src/locale/effects/langs/zh-CN/preferences.json b/web/src/locale/effects/langs/zh-CN/preferences.json
index 21aa4a7..ae437f4 100644
--- a/web/src/locale/effects/langs/zh-CN/preferences.json
+++ b/web/src/locale/effects/langs/zh-CN/preferences.json
@@ -30,6 +30,8 @@
"rounded": "圆润",
"copyPreferences": "复制偏好设置",
"save":"保存",
+ "savePreferencesSuccess": "偏好设置保存成功",
+ "savePreferencesFailed": "偏好设置保存失败",
"copyPreferencesSuccessTitle": "复制成功",
"copyPreferencesSuccess": "复制成功,请在 app 下的 `src/preferences.ts`内进行覆盖",
"clearAndLogout": "清空缓存 & 退出登录",
--
Gitee
From 694195f1f6dfe3a322bea78fa71209e34ff314a1 Mon Sep 17 00:00:00 2001
From: "Mr.April"
Date: Fri, 22 Aug 2025 17:01:19 +0800
Subject: [PATCH 6/7] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0RSA=E8=A7=A3?=
=?UTF-8?q?=E5=AF=86=E4=BE=9D=E8=B5=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
server/composer.json | 3 +-
server/composer.lock | 233 ++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 232 insertions(+), 4 deletions(-)
diff --git a/server/composer.json b/server/composer.json
index 32ca147..261fca2 100644
--- a/server/composer.json
+++ b/server/composer.json
@@ -73,7 +73,8 @@
"topthink/think-template": "^3.0",
"ext-gd": "*",
"php-di/php-di": "^7.0",
- "casbin/casbin": "^4.0"
+ "casbin/casbin": "^4.0",
+ "phpseclib/phpseclib": "^3.0"
},
"suggest": {
"ext-event": "For better performance. "
diff --git a/server/composer.lock b/server/composer.lock
index 7f41469..9616d99 100644
--- a/server/composer.lock
+++ b/server/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "f817c0f2a5ba81575320f7454197f6df",
+ "content-hash": "57d030f5acb60a4099e32eebfb29f6be",
"packages": [
{
"name": "aliyuncs/oss-sdk-php",
@@ -3594,6 +3594,123 @@
],
"time": "2025-03-10T09:33:39+00:00"
},
+ {
+ "name": "paragonie/constant_time_encoding",
+ "version": "v3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/constant_time_encoding.git",
+ "reference": "df1e7fde177501eee2037dd159cf04f5f301a512"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/df1e7fde177501eee2037dd159cf04f5f301a512",
+ "reference": "df1e7fde177501eee2037dd159cf04f5f301a512",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9",
+ "vimeo/psalm": "^4|^5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "ParagonIE\\ConstantTime\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com",
+ "role": "Maintainer"
+ },
+ {
+ "name": "Steve 'Sc00bz' Thomas",
+ "email": "steve@tobtu.com",
+ "homepage": "https://www.tobtu.com",
+ "role": "Original Developer"
+ }
+ ],
+ "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
+ "keywords": [
+ "base16",
+ "base32",
+ "base32_decode",
+ "base32_encode",
+ "base64",
+ "base64_decode",
+ "base64_encode",
+ "bin2hex",
+ "encoding",
+ "hex",
+ "hex2bin",
+ "rfc4648"
+ ],
+ "support": {
+ "email": "info@paragonie.com",
+ "issues": "https://github.com/paragonie/constant_time_encoding/issues",
+ "source": "https://github.com/paragonie/constant_time_encoding"
+ },
+ "time": "2024-05-08T12:36:18+00:00"
+ },
+ {
+ "name": "paragonie/random_compat",
+ "version": "v9.99.100",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/random_compat.git",
+ "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a",
+ "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">= 7"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*|5.*",
+ "vimeo/psalm": "^1"
+ },
+ "suggest": {
+ "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+ },
+ "type": "library",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com"
+ }
+ ],
+ "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+ "keywords": [
+ "csprng",
+ "polyfill",
+ "pseudorandom",
+ "random"
+ ],
+ "support": {
+ "email": "info@paragonie.com",
+ "issues": "https://github.com/paragonie/random_compat/issues",
+ "source": "https://github.com/paragonie/random_compat"
+ },
+ "time": "2020-10-15T08:29:30+00:00"
+ },
{
"name": "php-di/invoker",
"version": "2.3.6",
@@ -3984,6 +4101,116 @@
],
"time": "2024-07-20T21:41:07+00:00"
},
+ {
+ "name": "phpseclib/phpseclib",
+ "version": "3.0.46",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpseclib/phpseclib.git",
+ "reference": "56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6",
+ "reference": "56483a7de62a6c2a6635e42e93b8a9e25d4f0ec6",
+ "shasum": ""
+ },
+ "require": {
+ "paragonie/constant_time_encoding": "^1|^2|^3",
+ "paragonie/random_compat": "^1.4|^2.0|^9.99.99",
+ "php": ">=5.6.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "*"
+ },
+ "suggest": {
+ "ext-dom": "Install the DOM extension to load XML formatted public keys.",
+ "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
+ "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
+ "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
+ "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations."
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "phpseclib/bootstrap.php"
+ ],
+ "psr-4": {
+ "phpseclib3\\": "phpseclib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jim Wigginton",
+ "email": "terrafrost@php.net",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Patrick Monnerat",
+ "email": "pm@datasphere.ch",
+ "role": "Developer"
+ },
+ {
+ "name": "Andreas Fischer",
+ "email": "bantu@phpbb.com",
+ "role": "Developer"
+ },
+ {
+ "name": "Hans-Jürgen Petrich",
+ "email": "petrich@tronic-media.com",
+ "role": "Developer"
+ },
+ {
+ "name": "Graham Campbell",
+ "email": "graham@alt-three.com",
+ "role": "Developer"
+ }
+ ],
+ "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
+ "homepage": "http://phpseclib.sourceforge.net",
+ "keywords": [
+ "BigInteger",
+ "aes",
+ "asn.1",
+ "asn1",
+ "blowfish",
+ "crypto",
+ "cryptography",
+ "encryption",
+ "rsa",
+ "security",
+ "sftp",
+ "signature",
+ "signing",
+ "ssh",
+ "twofish",
+ "x.509",
+ "x509"
+ ],
+ "support": {
+ "issues": "https://github.com/phpseclib/phpseclib/issues",
+ "source": "https://github.com/phpseclib/phpseclib/tree/3.0.46"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/terrafrost",
+ "type": "github"
+ },
+ {
+ "url": "https://www.patreon.com/phpseclib",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2025-06-26T16:29:55+00:00"
+ },
{
"name": "psr/cache",
"version": "3.0.0",
@@ -8177,7 +8404,7 @@
"packages-dev": [],
"aliases": [],
"minimum-stability": "dev",
- "stability-flags": {},
+ "stability-flags": [],
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
@@ -8186,6 +8413,6 @@
"ext-pdo": "*",
"ext-gd": "*"
},
- "platform-dev": {},
+ "platform-dev": [],
"plugin-api-version": "2.6.0"
}
--
Gitee
From 005c8d1361ff6670716a92b3cac997aac42db47b Mon Sep 17 00:00:00 2001
From: "Mr.April"
Date: Fri, 22 Aug 2025 17:02:31 +0800
Subject: [PATCH 7/7] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E5=8F=82=E6=95=B0?=
=?UTF-8?q?=E7=B1=BB=E5=9E=8B=E9=99=90=E5=88=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../app/admin/controller/LoginController.php | 20 +++++------
.../app/common/dao/system/SysCrontabDao.php | 2 +-
server/app/common/dao/system/SysDeptDao.php | 2 +-
server/app/common/dao/system/SysMenuDao.php | 2 +-
.../app/common/dao/system/SysMessageDao.php | 3 +-
.../common/dao/system/SysOperateLogDao.php | 18 +++++-----
.../common/dao/system/SysRecycleBinDao.php | 2 +-
server/app/common/dao/system/SysRoleDao.php | 2 +-
server/app/common/dao/system/SysUploadDao.php | 2 +-
.../services/system/SysAdminService.php | 36 +++++++++----------
server/core/abstract/BaseDao.php | 8 ++---
server/core/uuid/UUIDGenerator.php | 2 +-
12 files changed, 48 insertions(+), 51 deletions(-)
diff --git a/server/app/admin/controller/LoginController.php b/server/app/admin/controller/LoginController.php
index 68f77af..9b8c68b 100644
--- a/server/app/admin/controller/LoginController.php
+++ b/server/app/admin/controller/LoginController.php
@@ -18,6 +18,8 @@ use core\exception\handler\AdminException;
use core\jwt\JwtToken;
use core\utils\Json;
use core\captcha\Captcha;
+use core\utils\RSAService;
+use core\uuid\UUIDGenerator;
use support\Container;
use support\Request;
@@ -58,13 +60,12 @@ class LoginController extends Crud
{
try {
// 生成密钥对
- $cache = Container::make(CacheService::class,[]);
- // 使用 uniqid 增加唯一性
- $keyId = bin2hex(random_bytes(8)) . uniqid();
- $keys = $this->service->generateRSAKeys();
+ $cache = Container::make(CacheService::class, []);
+ $keyId = md5(UUIDGenerator::generate());
+ $keys = RSAService::generateKeys();
// 存储私钥到缓存,用于解密密码
- $cache->set("rsa_private_key:$keyId", $keys['private'], 60); // 5分钟过期
- return Json::success('ok', ['flag' => config('core.captcha.app.enable', false),'key_id'=>$keyId,'public_key'=>$keys['public']]);
+ $cache->set("rsa_private_key_$keyId", $keys['private'], 60); // 5分钟过期
+ return Json::success('ok', ['flag' => config('core.captcha.app.enable', false), 'key_id' => $keyId, 'public_key' => $keys['public']]);
} catch (\Throwable $e) {
return Json::fail($e->getMessage());
}
@@ -127,12 +128,10 @@ class LoginController extends Crud
$type = $request->input('type', 'admin');
$grantType = $request->input('grant_type', 'default');//refresh_token sms default 可以自行定义拓展登录方式
$keyId = $request->input('key_id', '');//获取公钥Id
+ /** @var SysAdminService $service */
$service = Container::make(SysAdminService::class);
$captcha = new Captcha();
-// if (config('tenant.enabled') && empty($tenantId)) {
-// throw new AdminException('请选择数据源!');
-// }
if (config('core.captcha.app.enable') && $grantType === 'default') {
if (!$captcha->check($uuid, $code)) {
@@ -150,7 +149,8 @@ class LoginController extends Crud
}
$username = $info->getData('user_name');
}
- $data = $service->login($username, $password, $type, $grantType, ['keyId'=> $keyId ?? '']);
+
+ $data = $service->login($username, $password, $type, $grantType, ['key_id' => $keyId ?? '']);
return Json::success('ok', $data);
} catch (\Throwable $e) {
return Json::fail($e->getMessage());
diff --git a/server/app/common/dao/system/SysCrontabDao.php b/server/app/common/dao/system/SysCrontabDao.php
index dc2c7e7..ba3e314 100644
--- a/server/app/common/dao/system/SysCrontabDao.php
+++ b/server/app/common/dao/system/SysCrontabDao.php
@@ -38,7 +38,7 @@ class SysCrontabDao extends BaseDao
* @return \Illuminate\Database\Eloquent\Collection|null
* @throws \Exception
*/
- public function selectList(array $where, string $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false,?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
+ public function selectList(array $where, string|array $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
{
$result = parent::selectList($where, $field, $page, $limit, $order, [], $search,$withoutScopes);
diff --git a/server/app/common/dao/system/SysDeptDao.php b/server/app/common/dao/system/SysDeptDao.php
index 875fe66..35264a7 100644
--- a/server/app/common/dao/system/SysDeptDao.php
+++ b/server/app/common/dao/system/SysDeptDao.php
@@ -26,7 +26,7 @@ class SysDeptDao extends BaseDao
- public function selectList(array $where, string $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
+ public function selectList(array $where, string|array $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
{
return parent::selectList($where, $field, $page, $limit, $order, ['leader'], $search, $withoutScopes);
}
diff --git a/server/app/common/dao/system/SysMenuDao.php b/server/app/common/dao/system/SysMenuDao.php
index 541b2c0..2b7a01c 100644
--- a/server/app/common/dao/system/SysMenuDao.php
+++ b/server/app/common/dao/system/SysMenuDao.php
@@ -29,7 +29,7 @@ class SysMenuDao extends BaseDao
return SysMenu::class;
}
- public function selectList(array $where, string $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
+ public function selectList(array $where, string|array $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
{
$order='sort';
return parent::selectList($where, $field, $page, $limit, $order, [], $search, $withoutScopes);
diff --git a/server/app/common/dao/system/SysMessageDao.php b/server/app/common/dao/system/SysMessageDao.php
index 448c53a..5921eab 100644
--- a/server/app/common/dao/system/SysMessageDao.php
+++ b/server/app/common/dao/system/SysMessageDao.php
@@ -28,8 +28,7 @@ class SysMessageDao extends BaseDao
return parent::get($id, $field, ['sender'], $order, $withoutScopes);
}
-
- public function selectList(array $where, string $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
+ public function selectList(array $where, string|array $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
{
return parent::selectList($where, $field, $page, $limit, 'created_at desc', ['sender'], $search, $withoutScopes);
}
diff --git a/server/app/common/dao/system/SysOperateLogDao.php b/server/app/common/dao/system/SysOperateLogDao.php
index 7e4bc9e..01793f3 100644
--- a/server/app/common/dao/system/SysOperateLogDao.php
+++ b/server/app/common/dao/system/SysOperateLogDao.php
@@ -32,19 +32,19 @@ class SysOperateLogDao extends BaseDao
/**
* 操作日志列表
*
- * @param array $where
- * @param string $field
- * @param int $page
- * @param int $limit
- * @param string $order
- * @param array $with
- * @param bool $search
- * @param array|null $withoutScopes
+ * @param array $where
+ * @param string|array $field
+ * @param int $page
+ * @param int $limit
+ * @param string $order
+ * @param array $with
+ * @param bool $search
+ * @param array|null $withoutScopes
*
* @return \Illuminate\Database\Eloquent\Collection|null
* @throws \Exception
*/
- public function selectList(array $where, string $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
+ public function selectList(array $where, string|array $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
{
//注意不要输出result 要不然深度递归会卡死
return parent::selectList($where, $field, $page, $limit, $order, $with, $search, $withoutScopes)->makeHidden(['result']);
diff --git a/server/app/common/dao/system/SysRecycleBinDao.php b/server/app/common/dao/system/SysRecycleBinDao.php
index 8317755..bc244b9 100644
--- a/server/app/common/dao/system/SysRecycleBinDao.php
+++ b/server/app/common/dao/system/SysRecycleBinDao.php
@@ -29,7 +29,7 @@ class SysRecycleBinDao extends BaseDao
return SysRecycleBin::class;
}
- public function selectList(array $where, string $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
+ public function selectList(array $where, string|array $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
{
return parent::selectList($where, $field, $page, $limit, $order, ['operate'], $search, $withoutScopes);
}
diff --git a/server/app/common/dao/system/SysRoleDao.php b/server/app/common/dao/system/SysRoleDao.php
index 3aca30d..7cc69d3 100644
--- a/server/app/common/dao/system/SysRoleDao.php
+++ b/server/app/common/dao/system/SysRoleDao.php
@@ -146,7 +146,7 @@ class SysRoleDao extends BaseDao
* @return \Illuminate\Database\Eloquent\Collection|null
* @throws \Exception
*/
- public function selectList(array $where, string $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
+ public function selectList(array $where, string|array $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
{
$with = ['casbin'];
return parent::selectList($where, $field, $page, $limit, $order, $with, $search, $withoutScopes);
diff --git a/server/app/common/dao/system/SysUploadDao.php b/server/app/common/dao/system/SysUploadDao.php
index 3b2eb17..bb799cc 100644
--- a/server/app/common/dao/system/SysUploadDao.php
+++ b/server/app/common/dao/system/SysUploadDao.php
@@ -29,7 +29,7 @@ class SysUploadDao extends BaseDao
return SysUpload::class;
}
- public function selectList(array $where, string $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
+ public function selectList(array $where, string|array $field = '*', int $page = 0, int $limit = 0, string $order = '', array $with = [], bool $search = false, ?array $withoutScopes = null): ?\Illuminate\Database\Eloquent\Collection
{
//重写追加两个关联模型
return parent::selectList($where, $field, $page, $limit, $order, ['createds', 'updateds'], $search, $withoutScopes);
diff --git a/server/app/common/services/system/SysAdminService.php b/server/app/common/services/system/SysAdminService.php
index 81a4e71..73c6934 100644
--- a/server/app/common/services/system/SysAdminService.php
+++ b/server/app/common/services/system/SysAdminService.php
@@ -20,6 +20,8 @@ use core\casbin\Permission;
use core\enum\system\PolicyPrefix;
use core\exception\handler\AdminException;
use core\jwt\JwtToken;
+use core\utils\RSAService;
+use phpseclib3\Crypt\RSA;
use support\Container;
use Webman\Event\Event;
@@ -236,20 +238,20 @@ class SysAdminService extends BaseService
/**
* 用户登录
*
- * @param string $username
- * @param string $password
- * @param string $type
- * @param string $grantType
- * @param string|int $tenantId
+ * @param string $username
+ * @param string $password
+ * @param string $type
+ * @param string $grantType
+ * @param array $params
*
* @return array
- * @throws \Exception
+ * @throws \core\exception\handler\AdminException
*/
public function login(string $username, string $password = '', string $type = 'admin', string $grantType = 'default', array $params = []): array
{
$adminInfo = $this->getAdminByName($username);
$this->validateAdminStatus($adminInfo);
- $decryptedPassword = $this->validateRsaKeys($params['keyId'], $password);
+ $decryptedPassword = $this->validateRsaKeys($params['key_id'], $password);
$this->validatePassword($adminInfo, $decryptedPassword, $grantType);
[$userInfo, $token] = $this->generateTokenData($adminInfo, $type);
$this->emitLoginSuccessEvent(array_merge($userInfo, $token), $tenant?->id ?? null);
@@ -294,7 +296,6 @@ class SysAdminService extends BaseService
}
}
-
/**
* token生成
*
@@ -483,28 +484,25 @@ class SysAdminService extends BaseService
preg_match($pattern, $url, $matches);
return $matches[1] ?? '';
}
+
/**
* 校验密钥
+ *
* @param $keyId
* @param $encryptedPassword
+ *
* @return string
* @throws AdminException
*/
private function validateRsaKeys($keyId, $encryptedPassword): string
{
- $cache = Container::make(CacheService::class,[]);
- $privateKey = $cache->get("rsa_private_key:$keyId");
+ $cache = Container::make(CacheService::class, []);
+ $privateKey = $cache->get("rsa_private_key_$keyId");
if (!$privateKey) {
throw new AdminException('私钥不存在或已过期,请刷新页面重试');
}
- $privateKeyResource = openssl_pkey_get_private($privateKey);
- $decrypted = '';
- $encryptedData = base64_decode($encryptedPassword);
- if (openssl_private_decrypt($encryptedData, $decrypted, $privateKeyResource)) {
- $cache->delete("rsa_private_key:$keyId"); // 删除私钥,防止泄露
- return $decrypted;
- } else {
- throw new AdminException('解密失败!');
- }
+ return RSAService::decrypt($encryptedPassword, $privateKey);
}
}
+
+
diff --git a/server/core/abstract/BaseDao.php b/server/core/abstract/BaseDao.php
index f72c5e8..c45cee2 100644
--- a/server/core/abstract/BaseDao.php
+++ b/server/core/abstract/BaseDao.php
@@ -388,15 +388,15 @@ abstract class BaseDao
* 获取一条数据
*
* @param $id
- * @param string|array|null $field
+ * @param array|null $field
* @param array|null $with
- * @param string $order
+ * @param string $order
* @param array|null $withoutScopes
*
* @return Model|null
- * @throws Exception
+ * @throws \Exception
*/
- public function get($id, string|array $field = null, ?array $with = [], string $order = '', ?array $withoutScopes = null): ?Model
+ public function get($id, ?array $field = null, ?array $with = [], string $order = '', ?array $withoutScopes = null): ?Model
{
$where = is_array($id) ? $id : [$this->getPk() => $id];
$query = $this->getModel()->query();
diff --git a/server/core/uuid/UUIDGenerator.php b/server/core/uuid/UUIDGenerator.php
index d77f910..5f1c314 100644
--- a/server/core/uuid/UUIDGenerator.php
+++ b/server/core/uuid/UUIDGenerator.php
@@ -29,7 +29,7 @@ class UUIDGenerator
* @return string|null
* @throws \Exception
*/
- public static function generate(string $format = 'uuid', int $length = 36)
+ public static function generate(string $format = 'uuid', int $length = 36): ?string
{
if ($format === 'uuid') {
return self::generateUUID();
--
Gitee