diff --git a/CHANGELOG.md b/CHANGELOG.md index cf2c2a7aa77..f6e01ddc9e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,34 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v1.8.28](https://github.com/nocobase/nocobase/compare/v1.8.27...v1.8.28) - 2025-10-14 + +### 🚀 Improvements + +- **[client]** In order to get more accurate MIME type of file, use `mime` package to detect MIME type of file in client ([#7551](https://github.com/nocobase/nocobase/pull/7551)) by @mytharcher + +- **[Workflow]** + - Support to limit the maximum number of nodes in a workflow through environment variables ([#7542](https://github.com/nocobase/nocobase/pull/7542)) by @mytharcher + + - Add `keepBranch` option when deleting node ([#7571](https://github.com/nocobase/nocobase/pull/7571)) by @mytharcher + +- **[Workflow: Loop node]** Support to limit the maximum number of cycles for loop nodes through environment variables ([#7543](https://github.com/nocobase/nocobase/pull/7543)) by @mytharcher + +- **[Workflow: Approval]** Add print button to detail popup in custom approval blocks by @mytharcher + +### 🐛 Bug Fixes + +- **[client]** + - Fix the issue where images did not display correctly when both rotated and scaled during preview ([#7573](https://github.com/nocobase/nocobase/pull/7573)) by @mytharcher + + - Fix the issue where missing dynamic properties in the `AssignedField` component caused file upload errors in "Create record" or "Update record" nodes ([#7556](https://github.com/nocobase/nocobase/pull/7556)) by @mytharcher + +- **[Public forms]** Fix the issue where the upload rules for file fields in public forms were incorrect ([#7553](https://github.com/nocobase/nocobase/pull/7553)) by @mytharcher + +- **[Calendar]** fix data query issue caused by unique identifier in calendar block ([#7562](https://github.com/nocobase/nocobase/pull/7562)) by @katherinehhh + +- **[Auth: LDAP]** Fix LDAP bind failure with non-ASCII (UTF-8) DNs in Active Directory by @2013xile + ## [v1.8.27](https://github.com/nocobase/nocobase/compare/v1.8.26...v1.8.27) - 2025-10-02 ### 🚀 Improvements diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index aba39cc84a5..19ef06b4c13 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -5,6 +5,34 @@ 格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/), 并且本项目遵循 [语义化版本](https://semver.org/spec/v2.0.0.html)。 +## [v1.8.28](https://github.com/nocobase/nocobase/compare/v1.8.27...v1.8.28) - 2025-10-14 + +### 🚀 优化 + +- **[client]** 在前端使用 `mime` 包检测文件的 MIME 类型,以获得更准确的类型数据 ([#7551](https://github.com/nocobase/nocobase/pull/7551)) by @mytharcher + +- **[工作流]** + - 支持通过环境变量限制一个工作流中的最大节点数 ([#7542](https://github.com/nocobase/nocobase/pull/7542)) by @mytharcher + + - 删除节点时增加“保留分支”选项 ([#7571](https://github.com/nocobase/nocobase/pull/7571)) by @mytharcher + +- **[工作流:循环节点]** 支持通过环境变量限制循环节点的最大循环次数 ([#7543](https://github.com/nocobase/nocobase/pull/7543)) by @mytharcher + +- **[工作流:审批]** 为自定义审批区块的详情弹窗增加打印按钮 by @mytharcher + +### 🐛 修复 + +- **[client]** + - 修复预览图片同时旋转和缩放显示不正常的问题 ([#7573](https://github.com/nocobase/nocobase/pull/7573)) by @mytharcher + + - 修复 AssignedField 组件未实现动态属性导致的新增、更新节点上传文件错误问题 ([#7556](https://github.com/nocobase/nocobase/pull/7556)) by @mytharcher + +- **[公开表单]** 修复公开表单中的文件字段上传规则不正确的问题 ([#7553](https://github.com/nocobase/nocobase/pull/7553)) by @mytharcher + +- **[日历]** 修复日历区块数据表设置唯一标识后详情数据查询错误问题 ([#7562](https://github.com/nocobase/nocobase/pull/7562)) by @katherinehhh + +- **[认证:LDAP]** 修复含非 ASCII(UTF-8)DN 的 AD 登录失败问题 by @2013xile + ## [v1.8.27](https://github.com/nocobase/nocobase/compare/v1.8.26...v1.8.27) - 2025-10-02 ### 🚀 优化 diff --git a/packages/core/test/perf/scenarios/blog/flow-login-list-create-list-with-delay.ts b/packages/core/test/perf/scenarios/blog/flow-login-list-create-list-with-delay.ts index a1fd6b579e9..03b3b5f64f4 100644 --- a/packages/core/test/perf/scenarios/blog/flow-login-list-create-list-with-delay.ts +++ b/packages/core/test/perf/scenarios/blog/flow-login-list-create-list-with-delay.ts @@ -11,9 +11,11 @@ export const options = { // { target: 100, duration: '1s' }, // { target: 100, duration: '58s' }, // { target: 0, duration: '1s' }, + + // 10min { target: 100, duration: '30s' }, - { target: 200, duration: '1m' }, - { target: 200, duration: '1m' }, + { target: 200, duration: '30s' }, + { target: 200, duration: '8m' }, { target: 100, duration: '30s' }, { target: 0, duration: '30s' }, ], @@ -45,8 +47,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -66,8 +66,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -87,8 +85,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -127,8 +123,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -167,8 +161,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -190,8 +182,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -214,8 +204,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - token = resp.json('data.token'); params = { @@ -239,8 +227,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -262,8 +248,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -285,8 +269,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -308,8 +290,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -333,8 +313,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -356,8 +334,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -379,8 +355,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -403,8 +377,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -427,8 +399,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -451,8 +421,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -475,8 +443,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -499,8 +465,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -525,8 +489,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -549,8 +511,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -575,8 +535,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -599,8 +557,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -623,8 +579,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -647,8 +601,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -671,8 +623,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -792,8 +742,6 @@ export default function () { check(resp, { 'status equals 200': (r) => r.status === 200 }); - sleep(1); - params = { headers: { 'Proxy-Connection': `keep-alive`, @@ -815,9 +763,7 @@ export default function () { resp = http.request('GET', url, null, params); check(resp, { 'status equals 200': (r) => r.status === 200 }); - - sleep(1); }); - // sleep(1); + sleep(1); } diff --git a/packages/plugins/@nocobase/plugin-acl/src/server/__tests__/role-user.test.ts b/packages/plugins/@nocobase/plugin-acl/src/server/__tests__/role-user.test.ts index 4c2a29b8ee9..9f3287e0111 100644 --- a/packages/plugins/@nocobase/plugin-acl/src/server/__tests__/role-user.test.ts +++ b/packages/plugins/@nocobase/plugin-acl/src/server/__tests__/role-user.test.ts @@ -238,4 +238,21 @@ describe('role', () => { const response3 = await agent.resource('roles').check(); expect(response3.statusCode).toEqual(200); }); + + it('should not allow to set other role', async () => { + const user = await db.getRepository('users').create({ + values: {}, + }); + const client = await api.agent().login(user); + await client.post('/users:setDefaultRole').send({ + roleName: 'root', + }); + const role = await db.getRepository('rolesUsers').findOne({ + where: { + userId: user.get('id'), + roleName: 'root', + }, + }); + expect(role).toBeFalsy(); + }); }); diff --git a/packages/plugins/@nocobase/plugin-acl/src/server/actions/user-setDefaultRole.ts b/packages/plugins/@nocobase/plugin-acl/src/server/actions/user-setDefaultRole.ts index 093f3f7fc29..0b884b09abb 100644 --- a/packages/plugins/@nocobase/plugin-acl/src/server/actions/user-setDefaultRole.ts +++ b/packages/plugins/@nocobase/plugin-acl/src/server/actions/user-setDefaultRole.ts @@ -8,6 +8,8 @@ */ import { Context, Next } from '@nocobase/actions'; +import { UNION_ROLE_KEY } from '../constants'; +import { Model } from '@nocobase/database'; export async function setDefaultRole(ctx: Context, next: Next) { const { @@ -55,11 +57,11 @@ export async function setDefaultRole(ctx: Context, next: Next) { }, transaction, }); - let model; + let model: Model; if (targetUserRole) { await repository.model.update({ default: true }, { where: { userId: currentUser.id, roleName }, transaction }); model = targetUserRole.set('default', true); - } else { + } else if (roleName === UNION_ROLE_KEY) { model = await repository.create({ values: { userId: currentUser.id, @@ -69,7 +71,9 @@ export async function setDefaultRole(ctx: Context, next: Next) { transaction, }); } - db.emitAsync('rolesUsers.afterSave', model); + if (model) { + db.emitAsync('rolesUsers.afterSave', model); + } }); ctx.body = 'ok';