befly 3.76.0 → 3.76.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -51,7 +51,8 @@ export default {
51
51
  username: ctx.body.username,
52
52
  password: hashedPassword,
53
53
  nickname: ctx.body.nickname,
54
- roleCode: ctx.body.roleCode
54
+ roleCode: ctx.body.roleCode,
55
+ roleType: "admin"
55
56
  }
56
57
  });
57
58
 
@@ -16,8 +16,7 @@ export default {
16
16
  lastLoginIp: adminTable.lastLoginIp,
17
17
  lastLoginTime: adminTable.lastLoginTime,
18
18
  password: adminTable.password,
19
- phone: adminTable.phone,
20
- roleType: adminTable.roleType
19
+ phone: adminTable.phone
21
20
  },
22
21
  required: ["id"],
23
22
  handler: async (befly, ctx) => {
@@ -79,7 +78,7 @@ export default {
79
78
  updateData.password = await hashPassword(ctx.body.password);
80
79
  }
81
80
  if (ctx.body.phone !== undefined) updateData.phone = ctx.body.phone;
82
- if (ctx.body.roleType !== undefined) updateData.roleType = ctx.body.roleType;
81
+ // 管理员表类型固定为 admin,roleType 不允许通过更新接口修改
83
82
  if (ctx.body.username !== undefined) updateData.username = ctx.body.username;
84
83
  if (ctx.body.nickname !== undefined) updateData.nickname = ctx.body.nickname;
85
84
  if (ctx.body.roleCode !== undefined) updateData.roleCode = ctx.body.roleCode;
@@ -6,9 +6,11 @@ import { ErrorResponse } from "../utils/response.js";
6
6
  /**
7
7
  * 权限检查钩子
8
8
  * - 接口无需权限(auth=false):直接通过
9
- * - auth ctx.roleType 白名单(string[]):登录后按 ctx.roleType 放行
9
+ * - auth 为角色类型白名单(string[],如 ["admin"] / ["user"]):按 ctx.roleType 校验。
10
+ * 类型与角色解耦:管理员表(beflyAdmin)roleType 固定 "admin",用户表固定 "user",
11
+ * 任意角色 code 的管理员共享 "admin" 类型门槛,细粒度授权由下方集合检查(roleCode)负责
10
12
  * - 用户未登录:返回 401
11
- * - 开发者角色(dev):最高权限,直接通过
13
+ * - 开发者角色(dev):最高权限,直接通过(唯一内置角色,不可创建)
12
14
  * - 其他角色:检查 Redis 中的角色权限集合
13
15
  */
14
16
  export default {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "befly",
3
- "version": "3.76.0",
3
+ "version": "3.76.1",
4
4
  "gitHead": "49c39d36695036e85fc64083cc43c1652fff96cb",
5
5
  "private": false,
6
6
  "description": "Befly - 为 Bun 专属打造的 JavaScript API 接口框架核心引擎",
package/sync/syncUtil.js CHANGED
@@ -1,23 +1,17 @@
1
1
  // 接口 auth 的存储协议(serializeAuth 与 authAllowsRole 配套使用):
2
- // - true -> "是"
3
- // - false -> "否"
4
- // - string[] -> "a,b,c"
5
- export const AUTH_YES = "是";
6
- export const AUTH_NO = "否";
7
-
8
- /**
9
- * 序列化 api.auth 为存储字符串
10
- */
2
+ // - true -> 1(需登录)
3
+ // - false -> 0(免登录)
4
+ // - string[] -> "a,b,c"(角色类型白名单,如 admin/user)
11
5
  export function serializeAuth(auth) {
12
- return auth === false ? AUTH_NO : Array.isArray(auth) ? auth.join(",") : AUTH_YES;
6
+ return auth === false ? 0 : Array.isArray(auth) ? auth.join(",") : 1;
13
7
  }
14
8
 
15
9
  /**
16
- * 判断 auth 存储串是否授权给指定角色
10
+ * 判断 auth 存储值是否授权给指定角色
17
11
  */
18
12
  export function authAllowsRole(auth, roleCode) {
19
- if (auth === AUTH_NO) return true;
20
- if (typeof auth === "string" && auth !== AUTH_YES) {
13
+ if (Number(auth) === 0) return true;
14
+ if (typeof auth === "string" && Number(auth) !== 1) {
21
15
  return auth.split(",").some((code) => code.trim() === roleCode);
22
16
  }
23
17
  return false;
package/tables/api.json CHANGED
@@ -1,4 +1,4 @@
1
- {
1
+ {
2
2
  "id": {
3
3
  "name": "ID",
4
4
  "input": "integer",
@@ -12,7 +12,7 @@
12
12
  "max": 100
13
13
  },
14
14
  "auth": {
15
- "name": "是否需要登录",
15
+ "name": "登录与权限(0=免登录,1=需登录,其他=角色类型白名单)",
16
16
  "input": "string",
17
17
  "min": 1,
18
18
  "max": 200
@@ -1,41 +0,0 @@
1
- import { getRoleById, systemRoleCodes } from "./_role.js";
2
-
3
- export default {
4
- name: "删除角色",
5
- method: "POST",
6
- body: "none",
7
- auth: true,
8
- fields: {
9
- id: { name: "ID", input: "integer", min: 1, max: null }
10
- },
11
- required: ["id"],
12
- handler: async (befly, ctx) => {
13
- const role = await getRoleById(befly, ctx.body.id, ["code"]);
14
-
15
- if (!role.data?.code) {
16
- return befly.tool.No("角色不存在");
17
- }
18
-
19
- if (systemRoleCodes.includes(role.data.code)) {
20
- return befly.tool.No(`系统角色 [${role.data.code}] 不允许删除`);
21
- }
22
-
23
- const adminList = await befly.mysql.getList({
24
- table: "beflyAdmin",
25
- where: { roleCode: role.data.code }
26
- });
27
-
28
- if (adminList.data.total > 0) {
29
- return befly.tool.No("该角色已分配给用户,无法删除");
30
- }
31
-
32
- await befly.mysql.delData({
33
- table: "beflyRole",
34
- where: { id: ctx.body.id }
35
- });
36
-
37
- await befly.cache.deleteRoleApis(role.data.code);
38
-
39
- return befly.tool.Yes("操作成功");
40
- }
41
- };
@@ -1,45 +0,0 @@
1
- import roleTable from "#befly/tables/role.json";
2
-
3
- export default {
4
- name: "创建角色",
5
- method: "POST",
6
- body: "none",
7
- auth: true,
8
- fields: {
9
- name: roleTable.name,
10
- code: roleTable.code,
11
- description: roleTable.description,
12
- menus: roleTable.menus,
13
- apis: roleTable.apis,
14
- sort: roleTable.sort
15
- },
16
- required: [],
17
- handler: async (befly, ctx) => {
18
- const menuPaths = ctx.body.menus || [];
19
- const apiPaths = ctx.body.apis || [];
20
- const existing = await befly.mysql.getOne({
21
- table: "beflyRole",
22
- where: { code: ctx.body.code }
23
- });
24
-
25
- if (existing.data?.id) {
26
- return befly.tool.No("角色代码已存在");
27
- }
28
-
29
- const roleId = await befly.mysql.insData({
30
- table: "beflyRole",
31
- data: {
32
- name: ctx.body.name,
33
- code: ctx.body.code,
34
- description: ctx.body.description,
35
- menus: menuPaths,
36
- apis: apiPaths,
37
- sort: ctx.body.sort
38
- }
39
- });
40
-
41
- await befly.cache.refreshRoleApis(ctx.body.code, apiPaths);
42
-
43
- return befly.tool.Yes("操作成功", { id: roleId.data });
44
- }
45
- };
package/apis/role/save.js DELETED
@@ -1,36 +0,0 @@
1
- import adminTable from "#befly/tables/admin.json";
2
- import roleTable from "#befly/tables/role.json";
3
-
4
- import { getRoleByCode } from "./_role.js";
5
-
6
- export default {
7
- name: "角色保存",
8
- method: "POST",
9
- body: "none",
10
- auth: true,
11
- fields: {
12
- adminId: adminTable.id,
13
- roleCode: roleTable.code
14
- },
15
- required: ["adminId", "roleCode"],
16
- handler: async (befly, ctx) => {
17
- const role = await getRoleByCode(befly, ctx.body.roleCode);
18
-
19
- if (!role.data?.id) {
20
- return befly.tool.No("角色不存在");
21
- }
22
-
23
- const roleType = role.data.code === "dev" || role.data.code === "admin" ? "admin" : "user";
24
-
25
- await befly.mysql.updData({
26
- table: "beflyAdmin",
27
- where: { id: ctx.body.adminId },
28
- data: {
29
- roleCode: role.data.code,
30
- roleType: roleType
31
- }
32
- });
33
-
34
- return befly.tool.Yes("操作成功");
35
- }
36
- };
@@ -1,66 +0,0 @@
1
- import roleTable from "#befly/tables/role.json";
2
-
3
- import { getRoleById } from "./_role.js";
4
-
5
- export default {
6
- name: "更新角色",
7
- method: "POST",
8
- body: "none",
9
- auth: true,
10
- fields: {
11
- id: roleTable.id,
12
- name: roleTable.name,
13
- code: roleTable.code,
14
- description: roleTable.description,
15
- menus: roleTable.menus,
16
- apis: roleTable.apis,
17
- sort: roleTable.sort
18
- },
19
- required: ["id"],
20
- handler: async (befly, ctx) => {
21
- const role = await getRoleById(befly, ctx.body.id);
22
-
23
- if (!role.data?.id) {
24
- return befly.tool.No("角色不存在");
25
- }
26
-
27
- if (ctx.body.code !== undefined) {
28
- const existing = await befly.mysql.getOne({
29
- table: "beflyRole",
30
- where: {
31
- code: ctx.body.code,
32
- id$not: ctx.body.id
33
- }
34
- });
35
-
36
- if (existing.data?.id) {
37
- return befly.tool.No("角色代码已被其他角色使用");
38
- }
39
- }
40
-
41
- const roleCode = ctx.body.code === undefined ? role.data.code : ctx.body.code;
42
- const apiPaths = ctx.body.apis === undefined ? role.data.apis || [] : ctx.body.apis;
43
- const menuPaths = ctx.body.menus === undefined ? role.data.menus || [] : ctx.body.menus;
44
-
45
- await befly.mysql.updData({
46
- table: "beflyRole",
47
- where: { id: ctx.body.id },
48
- data: {
49
- name: ctx.body.name,
50
- code: roleCode,
51
- description: ctx.body.description,
52
- menus: menuPaths,
53
- apis: apiPaths,
54
- sort: ctx.body.sort
55
- }
56
- });
57
-
58
- if (role.data.code !== roleCode) {
59
- await befly.cache.deleteRoleApis(role.data.code);
60
- }
61
-
62
- await befly.cache.refreshRoleApis(roleCode, apiPaths);
63
-
64
- return befly.tool.Yes("操作成功");
65
- }
66
- };