@nocobase/plugin-acl 2.1.0-beta.2 → 2.1.0-beta.20
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.
- package/LICENSE +201 -661
- package/README.md +79 -10
- package/client-v2.d.ts +2 -0
- package/client-v2.js +1 -0
- package/dist/client/949.7ad4ad3b554e5452.js +10 -0
- package/dist/client/971.50ecf7b6ac572080.js +10 -0
- package/dist/client/index.js +1 -1
- package/dist/client-v2/139.929bc11d582ef7d4.js +10 -0
- package/dist/client-v2/193.3245b23f17b4c9f8.js +10 -0
- package/dist/client-v2/366.069b6cf12cfb9a67.js +10 -0
- package/dist/client-v2/627.ce101823deb86dd6.js +10 -0
- package/dist/client-v2/index.d.ts +9 -0
- package/dist/client-v2/index.js +10 -0
- package/dist/client-v2/plugin.d.ts +5 -0
- package/dist/client-v2/routes/AppInfoDemoRoute.d.ts +10 -0
- package/dist/client-v2/routes/DemoHomepageRoute.d.ts +10 -0
- package/dist/client-v2/routes/FlowSettingsComponentLoaderDemoRoute.d.ts +2 -0
- package/dist/client-v2/settings/DemoFlowSettingsLazyField.d.ts +10 -0
- package/dist/externalVersion.js +11 -9
- package/dist/server/actions/apply-data-permissions.d.ts +10 -0
- package/dist/server/actions/apply-data-permissions.js +208 -0
- package/dist/server/actions/data-source-compat.d.ts +13 -0
- package/dist/server/actions/data-source-compat.js +189 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +2 -0
- package/dist/server/middlewares/check-association-operate.js +14 -5
- package/dist/server/middlewares/check-change-with-association.d.ts +21 -0
- package/dist/server/middlewares/check-change-with-association.js +327 -246
- package/dist/server/middlewares/check-query-permission.d.ts +10 -0
- package/dist/server/middlewares/check-query-permission.js +64 -0
- package/dist/server/middlewares/with-acl-meta.js +7 -2
- package/dist/server/migrations/20251119225252-update-member-default-permission.js +1 -1
- package/dist/server/query/apply-query-permission.d.ts +27 -0
- package/dist/server/query/apply-query-permission.js +242 -0
- package/dist/server/server.d.ts +6 -1
- package/dist/server/server.js +24 -1
- package/dist/swagger/index.d.ts +1113 -145
- package/dist/swagger/index.js +986 -180
- package/package.json +5 -3
- package/dist/client/0655d5ded9f45bb1.js +0 -10
- package/dist/client/50204a14518b3a0d.js +0 -10
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
import type { Context, Next } from '@nocobase/actions';
|
|
10
|
+
export declare function applyDataPermissions(ctx: Context, next: Next): Promise<void>;
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
+
for (let key of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
+
var apply_data_permissions_exports = {};
|
|
28
|
+
__export(apply_data_permissions_exports, {
|
|
29
|
+
applyDataPermissions: () => applyDataPermissions
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(apply_data_permissions_exports);
|
|
32
|
+
function ensureString(value, fieldName) {
|
|
33
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
34
|
+
throw new Error(`Invalid ${fieldName}`);
|
|
35
|
+
}
|
|
36
|
+
return value.trim();
|
|
37
|
+
}
|
|
38
|
+
function normalizeFields(fields) {
|
|
39
|
+
if (!Array.isArray(fields)) {
|
|
40
|
+
return void 0;
|
|
41
|
+
}
|
|
42
|
+
const normalized = [
|
|
43
|
+
...new Set(fields.filter((field) => typeof field === "string" && !!field.trim()))
|
|
44
|
+
];
|
|
45
|
+
return normalized.length ? normalized : [];
|
|
46
|
+
}
|
|
47
|
+
function normalizeScopeId(scopeId) {
|
|
48
|
+
if (scopeId === null) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
if (scopeId === void 0) {
|
|
52
|
+
return void 0;
|
|
53
|
+
}
|
|
54
|
+
const parsed = Number(scopeId);
|
|
55
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
56
|
+
throw new Error(`Invalid scopeId: ${scopeId}`);
|
|
57
|
+
}
|
|
58
|
+
return parsed;
|
|
59
|
+
}
|
|
60
|
+
async function resolveScopeIdByKey(options) {
|
|
61
|
+
const scope = await options.ctx.db.getRepository("dataSourcesRolesResourcesScopes").findOne({
|
|
62
|
+
filter: {
|
|
63
|
+
dataSourceKey: options.dataSourceKey,
|
|
64
|
+
key: options.scopeKey
|
|
65
|
+
},
|
|
66
|
+
transaction: options.transaction
|
|
67
|
+
});
|
|
68
|
+
if (!scope) {
|
|
69
|
+
throw new Error(`Scope key "${options.scopeKey}" not found in data source "${options.dataSourceKey}"`);
|
|
70
|
+
}
|
|
71
|
+
return scope.get("id");
|
|
72
|
+
}
|
|
73
|
+
async function normalizeAction(options) {
|
|
74
|
+
const name = ensureString(options.action.name, "action.name");
|
|
75
|
+
let scopeId = normalizeScopeId(options.action.scopeId);
|
|
76
|
+
if (scopeId === void 0 && options.action.scope && typeof options.action.scope.id === "number") {
|
|
77
|
+
scopeId = normalizeScopeId(options.action.scope.id);
|
|
78
|
+
}
|
|
79
|
+
let scopeKey;
|
|
80
|
+
if (typeof options.action.scopeKey === "string" && options.action.scopeKey.trim()) {
|
|
81
|
+
scopeKey = options.action.scopeKey.trim();
|
|
82
|
+
} else if (options.action.scope && typeof options.action.scope.key === "string" && options.action.scope.key.trim()) {
|
|
83
|
+
scopeKey = options.action.scope.key.trim();
|
|
84
|
+
}
|
|
85
|
+
if (scopeId === void 0 && scopeKey) {
|
|
86
|
+
scopeId = await resolveScopeIdByKey({
|
|
87
|
+
ctx: options.ctx,
|
|
88
|
+
dataSourceKey: options.dataSourceKey,
|
|
89
|
+
scopeKey,
|
|
90
|
+
transaction: options.transaction
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
if (scopeId === void 0) {
|
|
94
|
+
scopeId = null;
|
|
95
|
+
}
|
|
96
|
+
const normalized = {
|
|
97
|
+
name,
|
|
98
|
+
fields: normalizeFields(options.action.fields),
|
|
99
|
+
scopeId
|
|
100
|
+
};
|
|
101
|
+
const output = {
|
|
102
|
+
name: normalized.name
|
|
103
|
+
};
|
|
104
|
+
if (normalized.fields !== void 0) {
|
|
105
|
+
output.fields = normalized.fields;
|
|
106
|
+
}
|
|
107
|
+
if (normalized.scopeId !== void 0) {
|
|
108
|
+
output.scopeId = normalized.scopeId;
|
|
109
|
+
}
|
|
110
|
+
return output;
|
|
111
|
+
}
|
|
112
|
+
async function applyDataPermissions(ctx, next) {
|
|
113
|
+
const roleName = ensureString(ctx.action.params.filterByTk, "filterByTk");
|
|
114
|
+
const values = ctx.action.params.values || {};
|
|
115
|
+
const dataSourceKey = ensureString(values.dataSourceKey || "main", "dataSourceKey");
|
|
116
|
+
const resources = values.resources;
|
|
117
|
+
if (!Array.isArray(resources) || resources.length === 0) {
|
|
118
|
+
throw new Error("`resources` must be a non-empty array");
|
|
119
|
+
}
|
|
120
|
+
const role = await ctx.db.getRepository("roles").findOne({
|
|
121
|
+
filterByTk: roleName
|
|
122
|
+
});
|
|
123
|
+
if (!role) {
|
|
124
|
+
throw new Error(`Role "${roleName}" not found`);
|
|
125
|
+
}
|
|
126
|
+
const roleResourceRepository = ctx.db.getRepository("roles.resources", roleName);
|
|
127
|
+
const appliedResources = [];
|
|
128
|
+
await ctx.db.sequelize.transaction(async (transaction) => {
|
|
129
|
+
for (const resourceInput of resources) {
|
|
130
|
+
const resourceName = ensureString(resourceInput == null ? void 0 : resourceInput.name, "resource.name");
|
|
131
|
+
const usingActionsConfig = (resourceInput == null ? void 0 : resourceInput.usingActionsConfig) ?? true;
|
|
132
|
+
const actionsInput = Array.isArray(resourceInput == null ? void 0 : resourceInput.actions) ? resourceInput.actions : [];
|
|
133
|
+
const normalizedActions = [];
|
|
134
|
+
for (const action of actionsInput) {
|
|
135
|
+
normalizedActions.push(
|
|
136
|
+
await normalizeAction({
|
|
137
|
+
ctx,
|
|
138
|
+
dataSourceKey,
|
|
139
|
+
action,
|
|
140
|
+
transaction
|
|
141
|
+
})
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
const existingResource = await roleResourceRepository.findOne({
|
|
145
|
+
filter: {
|
|
146
|
+
name: resourceName,
|
|
147
|
+
dataSourceKey
|
|
148
|
+
},
|
|
149
|
+
appends: ["actions"],
|
|
150
|
+
transaction
|
|
151
|
+
});
|
|
152
|
+
const writeValues = {
|
|
153
|
+
name: resourceName,
|
|
154
|
+
dataSourceKey,
|
|
155
|
+
usingActionsConfig,
|
|
156
|
+
actions: normalizedActions
|
|
157
|
+
};
|
|
158
|
+
let savedResource;
|
|
159
|
+
if (existingResource) {
|
|
160
|
+
await roleResourceRepository.update({
|
|
161
|
+
filterByTk: existingResource.get("id"),
|
|
162
|
+
values: writeValues,
|
|
163
|
+
updateAssociationValues: ["actions"],
|
|
164
|
+
transaction
|
|
165
|
+
});
|
|
166
|
+
savedResource = await roleResourceRepository.findOne({
|
|
167
|
+
filterByTk: existingResource.get("id"),
|
|
168
|
+
appends: ["actions"],
|
|
169
|
+
transaction
|
|
170
|
+
});
|
|
171
|
+
} else {
|
|
172
|
+
const created = await roleResourceRepository.create({
|
|
173
|
+
values: writeValues,
|
|
174
|
+
transaction
|
|
175
|
+
});
|
|
176
|
+
savedResource = await roleResourceRepository.findOne({
|
|
177
|
+
filterByTk: created.get("id"),
|
|
178
|
+
appends: ["actions"],
|
|
179
|
+
transaction
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
const actionModels = savedResource.get("actions") || [];
|
|
183
|
+
appliedResources.push({
|
|
184
|
+
id: savedResource.get("id"),
|
|
185
|
+
name: savedResource.get("name"),
|
|
186
|
+
dataSourceKey: savedResource.get("dataSourceKey"),
|
|
187
|
+
usingActionsConfig: !!savedResource.get("usingActionsConfig"),
|
|
188
|
+
actions: actionModels.map((actionModel) => ({
|
|
189
|
+
id: actionModel.get("id"),
|
|
190
|
+
name: actionModel.get("name"),
|
|
191
|
+
fields: actionModel.get("fields") || [],
|
|
192
|
+
scopeId: actionModel.get("scopeId") ?? null
|
|
193
|
+
}))
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
ctx.body = {
|
|
198
|
+
roleName,
|
|
199
|
+
dataSourceKey,
|
|
200
|
+
resources: appliedResources,
|
|
201
|
+
count: appliedResources.length
|
|
202
|
+
};
|
|
203
|
+
await next();
|
|
204
|
+
}
|
|
205
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
206
|
+
0 && (module.exports = {
|
|
207
|
+
applyDataPermissions
|
|
208
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
import type { Context, Next } from '@nocobase/actions';
|
|
10
|
+
export declare function guardRolesDataSourcesCollectionsList(ctx: Context, next: Next): Promise<void>;
|
|
11
|
+
export declare function guardRolesDataSourceResourcesCreate(ctx: Context, next: Next): Promise<void>;
|
|
12
|
+
export declare function guardRolesDataSourceResourcesGet(ctx: Context, next: Next): Promise<void>;
|
|
13
|
+
export declare function guardRolesDataSourceResourcesUpdate(ctx: Context, next: Next): Promise<void>;
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __create = Object.create;
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
13
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
15
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
16
|
+
var __export = (target, all) => {
|
|
17
|
+
for (var name in all)
|
|
18
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
19
|
+
};
|
|
20
|
+
var __copyProps = (to, from, except, desc) => {
|
|
21
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
22
|
+
for (let key of __getOwnPropNames(from))
|
|
23
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
24
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
25
|
+
}
|
|
26
|
+
return to;
|
|
27
|
+
};
|
|
28
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
29
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
30
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
31
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
32
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
33
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
34
|
+
mod
|
|
35
|
+
));
|
|
36
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
|
+
var data_source_compat_exports = {};
|
|
38
|
+
__export(data_source_compat_exports, {
|
|
39
|
+
guardRolesDataSourceResourcesCreate: () => guardRolesDataSourceResourcesCreate,
|
|
40
|
+
guardRolesDataSourceResourcesGet: () => guardRolesDataSourceResourcesGet,
|
|
41
|
+
guardRolesDataSourceResourcesUpdate: () => guardRolesDataSourceResourcesUpdate,
|
|
42
|
+
guardRolesDataSourcesCollectionsList: () => guardRolesDataSourcesCollectionsList
|
|
43
|
+
});
|
|
44
|
+
module.exports = __toCommonJS(data_source_compat_exports);
|
|
45
|
+
var import_lodash = __toESM(require("lodash"));
|
|
46
|
+
function normalizeString(value) {
|
|
47
|
+
if (typeof value !== "string") {
|
|
48
|
+
return void 0;
|
|
49
|
+
}
|
|
50
|
+
const trimmed = value.trim();
|
|
51
|
+
return trimmed ? trimmed : void 0;
|
|
52
|
+
}
|
|
53
|
+
function normalizeFilter(input) {
|
|
54
|
+
if (!import_lodash.default.isPlainObject(input)) {
|
|
55
|
+
return {};
|
|
56
|
+
}
|
|
57
|
+
return { ...input };
|
|
58
|
+
}
|
|
59
|
+
function applyLocatorFromQuery(params, filter) {
|
|
60
|
+
const dataSourceKeyFromQuery = normalizeString(params.dataSourceKey);
|
|
61
|
+
if (dataSourceKeyFromQuery) {
|
|
62
|
+
filter.dataSourceKey = filter.dataSourceKey || dataSourceKeyFromQuery;
|
|
63
|
+
}
|
|
64
|
+
const nameFromQuery = normalizeString(params.name);
|
|
65
|
+
if (nameFromQuery) {
|
|
66
|
+
filter.name = filter.name || nameFromQuery;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function normalizeNumericTk(value) {
|
|
70
|
+
if (typeof value === "number" && Number.isInteger(value) && value >= 0) {
|
|
71
|
+
return value;
|
|
72
|
+
}
|
|
73
|
+
const normalized = normalizeString(value);
|
|
74
|
+
if (!normalized || !/^\d+$/.test(normalized)) {
|
|
75
|
+
return void 0;
|
|
76
|
+
}
|
|
77
|
+
return normalized;
|
|
78
|
+
}
|
|
79
|
+
function deriveNameFromPrefixedTk(value) {
|
|
80
|
+
const normalized = normalizeString(value);
|
|
81
|
+
if (!normalized) {
|
|
82
|
+
return void 0;
|
|
83
|
+
}
|
|
84
|
+
const matched = normalized.match(/^[a-zA-Z]+_(.+)$/);
|
|
85
|
+
if (!matched) {
|
|
86
|
+
return void 0;
|
|
87
|
+
}
|
|
88
|
+
return normalizeString(matched[1]);
|
|
89
|
+
}
|
|
90
|
+
async function resolveLocatorFromFilterByTk(ctx, roleName, filter) {
|
|
91
|
+
const rawFilterByTk = ctx.action.params.filterByTk;
|
|
92
|
+
if (rawFilterByTk === void 0 || rawFilterByTk === null || rawFilterByTk === "") {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const numericFilterByTk = normalizeNumericTk(rawFilterByTk);
|
|
96
|
+
if (numericFilterByTk === void 0) {
|
|
97
|
+
if (!normalizeString(filter.name)) {
|
|
98
|
+
const derivedName = deriveNameFromPrefixedTk(rawFilterByTk);
|
|
99
|
+
if (derivedName) {
|
|
100
|
+
filter.name = derivedName;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const resource = await ctx.db.getRepository("dataSourcesRolesResources").findOne({
|
|
106
|
+
filterByTk: numericFilterByTk
|
|
107
|
+
});
|
|
108
|
+
if (!resource) {
|
|
109
|
+
ctx.throw(404, `Resource permission not found by filterByTk "${rawFilterByTk}"`);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const targetRoleName = resource.get("roleName");
|
|
113
|
+
if (targetRoleName !== roleName) {
|
|
114
|
+
ctx.throw(400, `Resource permission "${rawFilterByTk}" does not belong to role "${roleName}"`);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (!normalizeString(filter.dataSourceKey)) {
|
|
118
|
+
filter.dataSourceKey = resource.get("dataSourceKey");
|
|
119
|
+
}
|
|
120
|
+
if (!normalizeString(filter.name)) {
|
|
121
|
+
filter.name = resource.get("name");
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async function normalizeRoleDataSourceResourceLocator(ctx) {
|
|
125
|
+
const roleName = normalizeString(ctx.action.params.associatedIndex);
|
|
126
|
+
if (!roleName) {
|
|
127
|
+
ctx.throw(400, "Role name is required");
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const filter = normalizeFilter(ctx.action.params.filter);
|
|
131
|
+
applyLocatorFromQuery(ctx.action.params, filter);
|
|
132
|
+
await resolveLocatorFromFilterByTk(ctx, roleName, filter);
|
|
133
|
+
const dataSourceKey = normalizeString(filter.dataSourceKey);
|
|
134
|
+
const name = normalizeString(filter.name);
|
|
135
|
+
if (!dataSourceKey || !name) {
|
|
136
|
+
ctx.throw(
|
|
137
|
+
400,
|
|
138
|
+
"Missing resource locator: provide --filter-by-tk, or both --data-source-key and --name (or filter.{dataSourceKey,name})"
|
|
139
|
+
);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
ctx.action.params.filter = {
|
|
143
|
+
...filter,
|
|
144
|
+
dataSourceKey,
|
|
145
|
+
name
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
async function guardRolesDataSourcesCollectionsList(ctx, next) {
|
|
149
|
+
const filter = normalizeFilter(ctx.action.params.filter);
|
|
150
|
+
applyLocatorFromQuery(ctx.action.params, filter);
|
|
151
|
+
const dataSourceKey = normalizeString(filter.dataSourceKey);
|
|
152
|
+
if (!dataSourceKey) {
|
|
153
|
+
ctx.throw(400, "dataSourceKey is required: pass --data-source-key or filter.dataSourceKey");
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
ctx.action.params.filter = {
|
|
157
|
+
...filter,
|
|
158
|
+
dataSourceKey
|
|
159
|
+
};
|
|
160
|
+
await next();
|
|
161
|
+
}
|
|
162
|
+
async function guardRolesDataSourceResourcesCreate(ctx, next) {
|
|
163
|
+
const values = normalizeFilter(ctx.action.params.values);
|
|
164
|
+
const dataSourceKeyFromQuery = normalizeString(ctx.action.params.dataSourceKey);
|
|
165
|
+
if (!values.dataSourceKey && dataSourceKeyFromQuery) {
|
|
166
|
+
values.dataSourceKey = dataSourceKeyFromQuery;
|
|
167
|
+
}
|
|
168
|
+
if (!normalizeString(values.dataSourceKey)) {
|
|
169
|
+
ctx.throw(400, "dataSourceKey is required for roles.dataSourceResources:create");
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
ctx.action.params.values = values;
|
|
173
|
+
await next();
|
|
174
|
+
}
|
|
175
|
+
async function guardRolesDataSourceResourcesGet(ctx, next) {
|
|
176
|
+
await normalizeRoleDataSourceResourceLocator(ctx);
|
|
177
|
+
await next();
|
|
178
|
+
}
|
|
179
|
+
async function guardRolesDataSourceResourcesUpdate(ctx, next) {
|
|
180
|
+
await normalizeRoleDataSourceResourceLocator(ctx);
|
|
181
|
+
await next();
|
|
182
|
+
}
|
|
183
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
184
|
+
0 && (module.exports = {
|
|
185
|
+
guardRolesDataSourceResourcesCreate,
|
|
186
|
+
guardRolesDataSourceResourcesGet,
|
|
187
|
+
guardRolesDataSourceResourcesUpdate,
|
|
188
|
+
guardRolesDataSourcesCollectionsList
|
|
189
|
+
});
|
package/dist/server/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export * from './middlewares/setCurrentRole';
|
|
10
10
|
export * from './middlewares/with-acl-meta';
|
|
11
|
+
export * from './query/apply-query-permission';
|
|
11
12
|
export { RoleResourceActionModel } from './model/RoleResourceActionModel';
|
|
12
13
|
export { RoleResourceModel } from './model/RoleResourceModel';
|
|
13
14
|
export * from './constants';
|
package/dist/server/index.js
CHANGED
|
@@ -44,6 +44,7 @@ __export(server_exports, {
|
|
|
44
44
|
module.exports = __toCommonJS(server_exports);
|
|
45
45
|
__reExport(server_exports, require("./middlewares/setCurrentRole"), module.exports);
|
|
46
46
|
__reExport(server_exports, require("./middlewares/with-acl-meta"), module.exports);
|
|
47
|
+
__reExport(server_exports, require("./query/apply-query-permission"), module.exports);
|
|
47
48
|
var import_RoleResourceActionModel = require("./model/RoleResourceActionModel");
|
|
48
49
|
var import_RoleResourceModel = require("./model/RoleResourceModel");
|
|
49
50
|
__reExport(server_exports, require("./constants"), module.exports);
|
|
@@ -55,6 +56,7 @@ var import_server = __toESM(require("./server"));
|
|
|
55
56
|
RoleResourceModel,
|
|
56
57
|
...require("./middlewares/setCurrentRole"),
|
|
57
58
|
...require("./middlewares/with-acl-meta"),
|
|
59
|
+
...require("./query/apply-query-permission"),
|
|
58
60
|
...require("./constants"),
|
|
59
61
|
...require("./enum")
|
|
60
62
|
});
|
|
@@ -31,7 +31,7 @@ __export(check_association_operate_exports, {
|
|
|
31
31
|
module.exports = __toCommonJS(check_association_operate_exports);
|
|
32
32
|
var import_acl = require("@nocobase/acl");
|
|
33
33
|
async function checkAssociationOperate(ctx, next) {
|
|
34
|
-
var _a;
|
|
34
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
35
35
|
const { actionName, resourceName, sourceId } = ctx.action;
|
|
36
36
|
if (!(resourceName.includes(".") && ["add", "set", "remove", "toggle"].includes(actionName))) {
|
|
37
37
|
return next();
|
|
@@ -59,12 +59,21 @@ async function checkAssociationOperate(ctx, next) {
|
|
|
59
59
|
}
|
|
60
60
|
if (params.filter) {
|
|
61
61
|
try {
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
|
|
62
|
+
const timezone = ((_c = (_b = ctx.request) == null ? void 0 : _b.get) == null ? void 0 : _c.call(_b, "x-timezone")) ?? ((_e = (_d = ctx.request) == null ? void 0 : _d.header) == null ? void 0 : _e["x-timezone"]) ?? ((_g = (_f = ctx.req) == null ? void 0 : _f.headers) == null ? void 0 : _g["x-timezone"]);
|
|
63
|
+
const collection = (_i = (_h = ctx.database) == null ? void 0 : _h.getCollection) == null ? void 0 : _i.call(_h, resource);
|
|
64
|
+
(0, import_acl.checkFilterParams)(collection, params.filter);
|
|
65
|
+
const parsedFilter = await (0, import_acl.parseJsonTemplate)(params.filter, {
|
|
66
|
+
state: ctx.state,
|
|
67
|
+
timezone,
|
|
68
|
+
userProvider: (0, import_acl.createUserProvider)({
|
|
69
|
+
db: ctx.db,
|
|
70
|
+
currentUser: (_j = ctx.state) == null ? void 0 : _j.currentUser
|
|
71
|
+
})
|
|
72
|
+
});
|
|
73
|
+
const repo = ctx.database.getRepository(resource);
|
|
65
74
|
const record = await repo.findOne({
|
|
66
75
|
filterByTk: sourceId,
|
|
67
|
-
filter:
|
|
76
|
+
filter: parsedFilter ?? params.filter
|
|
68
77
|
});
|
|
69
78
|
if (!record) {
|
|
70
79
|
ctx.throw(403, "No permissions");
|
|
@@ -6,5 +6,26 @@
|
|
|
6
6
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
|
+
import { ACL, UserProvider } from '@nocobase/acl';
|
|
9
10
|
import { Context, Next } from '@nocobase/actions';
|
|
11
|
+
import { Collection } from '@nocobase/database';
|
|
12
|
+
export type SanitizeAssociationValuesOptions = {
|
|
13
|
+
acl?: ACL;
|
|
14
|
+
resourceName: string;
|
|
15
|
+
actionName: string;
|
|
16
|
+
values: any;
|
|
17
|
+
updateAssociationValues?: string[];
|
|
18
|
+
protectedKeys?: string[];
|
|
19
|
+
aclParams?: any;
|
|
20
|
+
roles?: string[];
|
|
21
|
+
currentRole?: string;
|
|
22
|
+
currentUser?: any;
|
|
23
|
+
collection?: Collection;
|
|
24
|
+
db?: any;
|
|
25
|
+
database?: any;
|
|
26
|
+
state?: Record<string, any>;
|
|
27
|
+
timezone?: string;
|
|
28
|
+
userProvider?: UserProvider;
|
|
29
|
+
};
|
|
30
|
+
export declare function sanitizeAssociationValues(options: SanitizeAssociationValuesOptions): Promise<any>;
|
|
10
31
|
export declare const checkChangesWithAssociation: (ctx: Context, next: Next) => Promise<any>;
|