@abhi1693/medusa-rbac 0.0.1 → 0.0.2

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.
Files changed (35) hide show
  1. package/.medusa/server/src/admin/index.js +43 -25
  2. package/.medusa/server/src/admin/index.mjs +43 -25
  3. package/.medusa/server/src/admin/lib/access.d.ts +6 -3
  4. package/.medusa/server/src/admin/lib/access.js +1 -1
  5. package/.medusa/server/src/api/admin/access/me/route.js +3 -1
  6. package/.medusa/server/src/api/admin/access/permissions/route.js +4 -1
  7. package/.medusa/server/src/api/middlewares/enforce-admin-access.js +49 -61
  8. package/.medusa/server/src/index.d.ts +1 -0
  9. package/.medusa/server/src/index.js +2 -1
  10. package/.medusa/server/src/lib/access/config.d.ts +6 -0
  11. package/.medusa/server/src/lib/access/config.js +110 -14
  12. package/.medusa/server/src/lib/access/explain.d.ts +1 -1
  13. package/.medusa/server/src/lib/access/explain.js +3 -2
  14. package/.medusa/server/src/lib/access/immutable-config.d.ts +2 -0
  15. package/.medusa/server/src/lib/access/immutable-config.js +17 -0
  16. package/.medusa/server/src/lib/access/native-resources.d.ts +3 -0
  17. package/.medusa/server/src/lib/access/native-resources.js +444 -0
  18. package/.medusa/server/src/lib/access/permission-key.d.ts +1 -1
  19. package/.medusa/server/src/lib/access/permission-key.js +3 -2
  20. package/.medusa/server/src/lib/access/permissions.d.ts +7 -0
  21. package/.medusa/server/src/lib/access/permissions.js +15 -2
  22. package/.medusa/server/src/lib/access/policy.d.ts +12 -3
  23. package/.medusa/server/src/lib/access/policy.js +149 -264
  24. package/.medusa/server/src/lib/access/resources.d.ts +107 -0
  25. package/.medusa/server/src/lib/access/resources.js +363 -0
  26. package/.medusa/server/src/lib/access/route-facts.d.ts +24 -0
  27. package/.medusa/server/src/lib/access/route-facts.js +77 -0
  28. package/.medusa/server/src/lib/access/write-permissions.d.ts +2 -0
  29. package/.medusa/server/src/lib/access/write-permissions.js +40 -0
  30. package/.medusa/server/src/modules/access-control/service.d.ts +4 -0
  31. package/.medusa/server/src/modules/access-control/service.js +8 -3
  32. package/.medusa/server/src/resources.d.ts +2 -0
  33. package/.medusa/server/src/resources.js +18 -0
  34. package/README.md +71 -9
  35. package/package.json +11 -7
@@ -0,0 +1,363 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defineResource = defineResource;
4
+ exports.crudProfile = crudProfile;
5
+ exports.commandProfile = commandProfile;
6
+ exports.actorOwnedPreferences = actorOwnedPreferences;
7
+ exports.profileAction = profileAction;
8
+ exports.resourceRoutes = resourceRoutes;
9
+ exports.describeResource = describeResource;
10
+ exports.describeResources = describeResources;
11
+ exports.operationAllowed = operationAllowed;
12
+ exports.validateResources = validateResources;
13
+ const route_facts_1 = require("./route-facts");
14
+ const permissions_1 = require("./permissions");
15
+ const immutable_config_1 = require("./immutable-config");
16
+ const identifier = /^[a-z][a-z0-9_-]{0,63}$/;
17
+ const parameter = /^[a-z][a-z0-9_]{0,63}$/;
18
+ const own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
19
+ const safeName = (name) => identifier.test(name) &&
20
+ !["constructor", "prototype", "__proto__"].includes(name);
21
+ const record = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
22
+ const keys = (value, allowed) => Object.keys(value).every((key) => allowed.includes(key));
23
+ const strings = (value) => Array.isArray(value) &&
24
+ value.length <= 500 &&
25
+ value.every((item) => typeof item === "string" && item.length > 0 && item.length <= 200);
26
+ function defineResource(definition) {
27
+ return definition;
28
+ }
29
+ function crudProfile(options = {}) {
30
+ const read = options.read || "read";
31
+ return {
32
+ actions: { GET: read, POST: options.create || "create" },
33
+ item: {
34
+ parameter: options.parameter || "id",
35
+ profile: {
36
+ actions: {
37
+ GET: read,
38
+ POST: options.update || "update",
39
+ DELETE: options.delete || "delete",
40
+ },
41
+ children: options.children,
42
+ },
43
+ },
44
+ };
45
+ }
46
+ function commandProfile(operation, method = "POST") {
47
+ return { actions: { [method]: operation } };
48
+ }
49
+ function actorOwnedPreferences(options) {
50
+ return {
51
+ children: { [options.list]: { actions: { GET: "read" } } },
52
+ item: {
53
+ parameter: options.parameter,
54
+ profile: {
55
+ children: {
56
+ [options.member]: {
57
+ actions: {
58
+ GET: "read",
59
+ POST: {
60
+ operation: "save",
61
+ scope: { kind: "boolean", field: options.sharedField },
62
+ },
63
+ DELETE: { operation: "reset", scope: { kind: "personal" } },
64
+ },
65
+ },
66
+ },
67
+ },
68
+ },
69
+ };
70
+ }
71
+ function profileAction(profile, facts) {
72
+ let node = profile;
73
+ for (const segment of facts.segments) {
74
+ if (segment.kind === "literal") {
75
+ const next = node.children && own(node.children, segment.value)
76
+ ? node.children[segment.value]
77
+ : undefined;
78
+ if (!next)
79
+ return null;
80
+ node = next;
81
+ }
82
+ else {
83
+ if (!node.item || node.item.parameter !== segment.name)
84
+ return null;
85
+ node = node.item.profile;
86
+ }
87
+ }
88
+ const action = node.actions?.[facts.method];
89
+ return typeof action === "string" ? { operation: action } : action || null;
90
+ }
91
+ function resourceRoutes(resource) {
92
+ const routes = [];
93
+ const visit = (profile, path) => {
94
+ if (profile.actions)
95
+ routes.push({ path, methods: Object.keys(profile.actions) });
96
+ for (const [member, child] of Object.entries(profile.children || {}))
97
+ visit(child, `${path}/${member}`);
98
+ if (profile.item)
99
+ visit(profile.item.profile, `${path}/:${profile.item.parameter}`);
100
+ };
101
+ visit(resource.profile, `/${resource.namespace || "admin"}/${resource.root}`);
102
+ return routes;
103
+ }
104
+ function describeResource(resource, facts, body, actorId, resolvedScope) {
105
+ const action = profileAction(resource.profile, facts);
106
+ if (!action)
107
+ return null;
108
+ const capability = own(resource.operations, action.operation)
109
+ ? resource.operations[action.operation]
110
+ : undefined;
111
+ if (!capability)
112
+ return null;
113
+ let scope = "global";
114
+ if (action.scope?.kind === "personal")
115
+ scope = "personal";
116
+ if (action.scope?.kind === "boolean") {
117
+ if (!body || typeof body !== "object" || Array.isArray(body))
118
+ return null;
119
+ const flag = body[action.scope.field];
120
+ if (flag !== undefined && typeof flag !== "boolean")
121
+ return null;
122
+ scope = flag === true ? "shared" : "personal";
123
+ }
124
+ scope = resolvedScope || scope;
125
+ const scoped = capability.scopes?.[scope];
126
+ if (capability.scopes && !scoped)
127
+ return null;
128
+ const self = Boolean(action.self &&
129
+ actorId &&
130
+ own(facts.params, action.self.parameter) &&
131
+ actorId === facts.params[action.self.parameter] &&
132
+ body &&
133
+ typeof body === "object" &&
134
+ !Array.isArray(body) &&
135
+ Object.keys(body).every((key) => action.self.fields.includes(key)));
136
+ return {
137
+ facts,
138
+ resource: resource.key,
139
+ operation: action.operation,
140
+ scope,
141
+ params: facts.params,
142
+ fieldResource: action.fieldResource || resource.key,
143
+ actorTypes: resource.actorTypes,
144
+ access: self ? "authenticated" : capability.access || "active-principal",
145
+ self,
146
+ policy: self
147
+ ? { permissions: [] }
148
+ : {
149
+ permissions: [...capability.permissions, ...(scoped || [])],
150
+ ...(capability.superuser ? { superuser: true } : {}),
151
+ },
152
+ action: self
153
+ ? { ...action, forceFields: action.self.responseFields }
154
+ : action,
155
+ fields: resource.fields,
156
+ fieldRequirements: resource.fieldRequirements || [],
157
+ };
158
+ }
159
+ function describeResources(resources, method, url, body, actorId) {
160
+ const facts = (0, route_facts_1.matchRoute)(resources.flatMap(resourceRoutes), method, url);
161
+ if (!facts)
162
+ return null;
163
+ const resource = resources.find((definition) => definition.root === facts.root &&
164
+ (definition.namespace || "admin") === facts.namespace);
165
+ return describeResource(resource, facts, body, actorId);
166
+ }
167
+ function operationAllowed(principal, operation, allows) {
168
+ if (operation.access === "public")
169
+ return (operation.policy.permissions.length === 0 && !operation.policy.superuser);
170
+ if (principal &&
171
+ (0, permissions_1.isSuperuser)(principal) &&
172
+ operation.facts.namespace === "admin")
173
+ return true;
174
+ return Boolean(principal &&
175
+ operation.actorTypes.includes(principal.actor_type) &&
176
+ (operation.access === "authenticated" || principal.active) &&
177
+ (!operation.policy.superuser || (0, permissions_1.isSuperuser)(principal)) &&
178
+ operation.policy.permissions.every(allows));
179
+ }
180
+ /** Validate host-owned registrations. Native resources cannot be replaced. */
181
+ function validateResources(value, permissions, reserved) {
182
+ const invalid = () => {
183
+ throw new Error("Invalid, conflicting or reserved resource registration");
184
+ };
185
+ if (!Array.isArray(value) || value.length > 100)
186
+ return invalid();
187
+ const resourceKeys = new Set(reserved.map((resource) => resource.key));
188
+ const roots = new Set(reserved.map((resource) => `${resource.namespace || "admin"}/${resource.root}`));
189
+ const registered = new Set(permissions);
190
+ const permissionList = (list) => strings(list) && list.every((permission) => registered.has(permission));
191
+ for (const definition of value) {
192
+ if (!record(definition) ||
193
+ !keys(definition, [
194
+ "key",
195
+ "namespace",
196
+ "root",
197
+ "profile",
198
+ "operations",
199
+ "actorTypes",
200
+ "fields",
201
+ "fieldRequirements",
202
+ "resolveScope",
203
+ ]) ||
204
+ typeof definition.key !== "string" ||
205
+ !safeName(definition.key) ||
206
+ typeof definition.root !== "string" ||
207
+ !safeName(definition.root) ||
208
+ (definition.namespace !== undefined &&
209
+ (typeof definition.namespace !== "string" ||
210
+ !safeName(definition.namespace))) ||
211
+ !strings(definition.actorTypes) ||
212
+ !definition.actorTypes.length ||
213
+ !record(definition.operations) ||
214
+ !Object.keys(definition.operations).length ||
215
+ (definition.fields !== undefined && !strings(definition.fields)) ||
216
+ (definition.resolveScope !== undefined &&
217
+ typeof definition.resolveScope !== "function"))
218
+ return invalid();
219
+ const root = `${definition.namespace || "admin"}/${definition.root}`;
220
+ if (resourceKeys.has(definition.key) || roots.has(root))
221
+ return invalid();
222
+ resourceKeys.add(definition.key);
223
+ roots.add(root);
224
+ for (const [operation, capability] of Object.entries(definition.operations)) {
225
+ if (!safeName(operation) ||
226
+ !record(capability) ||
227
+ !keys(capability, ["permissions", "superuser", "access", "scopes"]) ||
228
+ !permissionList(capability.permissions) ||
229
+ (capability.superuser !== undefined &&
230
+ typeof capability.superuser !== "boolean") ||
231
+ (capability.access !== undefined &&
232
+ !["public", "authenticated", "active-principal"].includes(capability.access)))
233
+ return invalid();
234
+ if (capability.access === "public" &&
235
+ (capability.permissions.length > 0 ||
236
+ capability.superuser === true ||
237
+ capability.scopes !== undefined))
238
+ return invalid();
239
+ if (capability.scopes !== undefined &&
240
+ (!record(capability.scopes) ||
241
+ !Object.keys(capability.scopes).length ||
242
+ Object.entries(capability.scopes).some(([scope, grants]) => !["global", "personal", "shared"].includes(scope) ||
243
+ !permissionList(grants))))
244
+ return invalid();
245
+ }
246
+ if (definition.fieldRequirements !== undefined &&
247
+ (!Array.isArray(definition.fieldRequirements) ||
248
+ definition.fieldRequirements.length > 100 ||
249
+ definition.fieldRequirements.some((requirement) => !record(requirement) ||
250
+ !keys(requirement, ["pattern", "permissions"]) ||
251
+ !(requirement.pattern instanceof RegExp) ||
252
+ requirement.pattern.global ||
253
+ requirement.pattern.sticky ||
254
+ !permissionList(requirement.permissions))))
255
+ return invalid();
256
+ const seen = new Set();
257
+ const validateProfile = (profile, depth, bound) => {
258
+ if (depth > 12 ||
259
+ !record(profile) ||
260
+ seen.has(profile) ||
261
+ !keys(profile, ["actions", "item", "children"]) ||
262
+ !Object.keys(profile).length)
263
+ return invalid();
264
+ seen.add(profile);
265
+ if (profile.actions !== undefined) {
266
+ if (!record(profile.actions) || !Object.keys(profile.actions).length)
267
+ return invalid();
268
+ for (const [method, rawAction] of Object.entries(profile.actions)) {
269
+ if (!["GET", "POST", "PUT", "PATCH", "DELETE"].includes(method))
270
+ return invalid();
271
+ const action = typeof rawAction === "string" ? { operation: rawAction } : rawAction;
272
+ if (!record(action) ||
273
+ !keys(action, [
274
+ "operation",
275
+ "fieldResource",
276
+ "payload",
277
+ "scope",
278
+ "forceFields",
279
+ "fallbackFields",
280
+ "self",
281
+ "redirect",
282
+ ]) ||
283
+ typeof action.operation !== "string" ||
284
+ !own(definition.operations, action.operation) ||
285
+ (action.fieldResource !== undefined &&
286
+ (typeof action.fieldResource !== "string" ||
287
+ !safeName(action.fieldResource))) ||
288
+ (action.payload !== undefined &&
289
+ typeof action.payload !== "function") ||
290
+ (action.forceFields !== undefined && !strings(action.forceFields)))
291
+ return invalid();
292
+ if (action.scope !== undefined &&
293
+ (!record(action.scope) ||
294
+ !keys(action.scope, ["kind", "field"]) ||
295
+ !["personal", "boolean"].includes(action.scope.kind) ||
296
+ (action.scope.kind === "boolean" &&
297
+ (typeof action.scope.field !== "string" ||
298
+ !parameter.test(action.scope.field)))))
299
+ return invalid();
300
+ if (action.fallbackFields !== undefined &&
301
+ (!record(action.fallbackFields) ||
302
+ !keys(action.fallbackFields, ["permissions", "fields"]) ||
303
+ !permissionList(action.fallbackFields.permissions) ||
304
+ !strings(action.fallbackFields.fields)))
305
+ return invalid();
306
+ if (action.self !== undefined &&
307
+ (!record(action.self) ||
308
+ !keys(action.self, ["parameter", "fields", "responseFields"]) ||
309
+ typeof action.self.parameter !== "string" ||
310
+ !parameter.test(action.self.parameter) ||
311
+ !bound.includes(action.self.parameter) ||
312
+ !strings(action.self.fields) ||
313
+ !strings(action.self.responseFields)))
314
+ return invalid();
315
+ if (action.redirect !== undefined &&
316
+ (!record(action.redirect) ||
317
+ !keys(action.redirect, ["destination", "parameter"]) ||
318
+ typeof action.redirect.destination !== "string" ||
319
+ !/^\/(?:[a-z0-9_-]+|:[a-z][a-z0-9_]*)(?:\/(?:[a-z0-9_-]+|:[a-z][a-z0-9_]*))*$/.test(action.redirect.destination) ||
320
+ typeof action.redirect.parameter !== "string" ||
321
+ !parameter.test(action.redirect.parameter) ||
322
+ !bound.includes(action.redirect.parameter)))
323
+ return invalid();
324
+ }
325
+ }
326
+ if (profile.children !== undefined) {
327
+ if (!record(profile.children) || !Object.keys(profile.children).length)
328
+ return invalid();
329
+ for (const [member, child] of Object.entries(profile.children)) {
330
+ if (!safeName(member))
331
+ return invalid();
332
+ validateProfile(child, depth + 1, bound);
333
+ }
334
+ }
335
+ if (profile.item !== undefined) {
336
+ if (!record(profile.item) ||
337
+ !keys(profile.item, ["parameter", "profile"]) ||
338
+ typeof profile.item.parameter !== "string" ||
339
+ !parameter.test(profile.item.parameter) ||
340
+ !safeName(profile.item.parameter))
341
+ return invalid();
342
+ validateProfile(profile.item.profile, depth + 1, [
343
+ ...bound,
344
+ profile.item.parameter,
345
+ ]);
346
+ }
347
+ seen.delete(profile);
348
+ };
349
+ validateProfile(definition.profile, 0, []);
350
+ const routes = resourceRoutes(definition);
351
+ if (!routes.length ||
352
+ routes.length > 500 ||
353
+ routes.some((route) => {
354
+ const params = route.path
355
+ .split("/")
356
+ .filter((segment) => segment.startsWith(":"));
357
+ return new Set(params).size !== params.length;
358
+ }))
359
+ return invalid();
360
+ }
361
+ return (0, immutable_config_1.immutableConfig)(value);
362
+ }
363
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb3VyY2VzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9hY2Nlc3MvcmVzb3VyY2VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBK0ZBLHdDQUlDO0FBRUQsa0NBeUJDO0FBRUQsd0NBS0M7QUFFRCxzREEwQkM7QUFFRCxzQ0FvQkM7QUFFRCx3Q0FjQztBQUVELDRDQXdEQztBQUVELDhDQWVDO0FBRUQsNENBc0JDO0FBR0QsOENBc09DO0FBamhCRCwrQ0FBMEM7QUFDMUMsK0NBQWlFO0FBQ2pFLHlEQUFvRDtBQUVwRCxNQUFNLFVBQVUsR0FBRyx5QkFBeUIsQ0FBQTtBQUM1QyxNQUFNLFNBQVMsR0FBRyx3QkFBd0IsQ0FBQTtBQUMxQyxNQUFNLEdBQUcsR0FBRyxDQUFDLEtBQWEsRUFBRSxHQUFXLEVBQUUsRUFBRSxDQUN6QyxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFBO0FBQ2xELE1BQU0sUUFBUSxHQUFHLENBQUMsSUFBWSxFQUFFLEVBQUUsQ0FDaEMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDckIsQ0FBQyxDQUFDLGFBQWEsRUFBRSxXQUFXLEVBQUUsV0FBVyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFBO0FBQzNELE1BQU0sTUFBTSxHQUFHLENBQUMsS0FBYyxFQUFvQyxFQUFFLENBQ2xFLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO0FBQ3RFLE1BQU0sSUFBSSxHQUFHLENBQUMsS0FBYSxFQUFFLE9BQTBCLEVBQUUsRUFBRSxDQUN6RCxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsT0FB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
@@ -0,0 +1,24 @@
1
+ export type RouteMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
2
+ export type RouteRegistration = {
3
+ path: string;
4
+ methods: readonly string[];
5
+ };
6
+ export type RouteSegment = {
7
+ kind: "literal";
8
+ value: string;
9
+ } | {
10
+ kind: "parameter";
11
+ name: string;
12
+ value: string;
13
+ };
14
+ export type RouteFacts = {
15
+ template: string;
16
+ method: string;
17
+ namespace: string;
18
+ root: string;
19
+ segments: RouteSegment[];
20
+ params: Record<string, string>;
21
+ };
22
+ export declare function canonicalPath(url: string): string | null;
23
+ export declare function createRouteMatcher(registrations: readonly RouteRegistration[]): (method: string, url: string) => RouteFacts | null;
24
+ export declare function matchRoute(registrations: readonly RouteRegistration[], method: string, url: string): RouteFacts | null;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.canonicalPath = canonicalPath;
4
+ exports.createRouteMatcher = createRouteMatcher;
5
+ exports.matchRoute = matchRoute;
6
+ function canonicalPath(url) {
7
+ const raw = url.split("?")[0];
8
+ if (!raw.startsWith("/") ||
9
+ /%(?:2f|5c|2e|25)/i.test(raw) ||
10
+ raw.includes("\\") ||
11
+ raw.includes("//"))
12
+ return null;
13
+ try {
14
+ decodeURIComponent(raw);
15
+ return raw.replace(/\/+$/, "");
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ }
21
+ function createRouteMatcher(registrations) {
22
+ const index = new Map();
23
+ for (const registration of registrations) {
24
+ const parts = registration.path.split("/").slice(1);
25
+ for (const method of registration.methods) {
26
+ const key = `${method}:${parts.length}`;
27
+ const group = index.get(key) || [];
28
+ group.push({ route: { path: registration.path }, parts });
29
+ index.set(key, group);
30
+ }
31
+ }
32
+ for (const group of index.values())
33
+ group.sort((left, right) => {
34
+ for (let i = 0; i < left.parts.length; i++) {
35
+ const difference = Number(left.parts[i].startsWith(":")) -
36
+ Number(right.parts[i].startsWith(":"));
37
+ if (difference)
38
+ return difference;
39
+ }
40
+ return left.route.path.localeCompare(right.route.path);
41
+ });
42
+ return (method, url) => {
43
+ const path = canonicalPath(url);
44
+ if (!path)
45
+ return null;
46
+ const values = path.split("/").slice(1);
47
+ const verb = method === "HEAD" ? "GET" : method;
48
+ const candidates = index.get(`${verb}:${values.length}`) || [];
49
+ for (const { route, parts } of candidates) {
50
+ if (!parts.every((part, i) => part.startsWith(":") ||
51
+ part.toLowerCase() === values[i].toLowerCase()))
52
+ continue;
53
+ const params = {};
54
+ const segments = parts.map((part, i) => {
55
+ if (!part.startsWith(":"))
56
+ return { kind: "literal", value: part.toLowerCase() };
57
+ const name = part.slice(1);
58
+ const value = decodeURIComponent(values[i]);
59
+ params[name] = value;
60
+ return { kind: "parameter", name, value };
61
+ });
62
+ return {
63
+ template: route.path,
64
+ method: verb,
65
+ namespace: parts.length > 1 ? parts[0].toLowerCase() : "",
66
+ root: (parts[1] || parts[0]).toLowerCase(),
67
+ segments: segments.slice(2),
68
+ params,
69
+ };
70
+ }
71
+ return null;
72
+ };
73
+ }
74
+ function matchRoute(registrations, method, url) {
75
+ return createRouteMatcher(registrations)(method, url);
76
+ }
77
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUtZmFjdHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2FjY2Vzcy9yb3V0ZS1mYWN0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWNBLHNDQWVDO0FBRUQsZ0RBNkRDO0FBRUQsZ0NBTUM7QUF0RkQsU0FBZ0IsYUFBYSxDQUFDLEdBQVc7SUFDdkMsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUM3QixJQUNFLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUM7UUFDcEIsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztRQUM3QixHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztRQUNsQixHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztRQUVsQixPQUFPLElBQUksQ0FBQTtJQUNiLElBQUksQ0FBQztRQUNILGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQ3ZCLE9BQU8sR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUE7SUFDaEMsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU8sSUFBSSxDQUFBO0lBQ2IsQ0FBQztBQUNILENBQUM7QUFFRCxTQUFnQixrQkFBa0IsQ0FDaEMsYUFBMkM7SUFFM0MsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBR2xCLENBQUE7SUFDSCxLQUFLLE1BQU0sWUFBWSxJQUFJLGFBQWEsRUFBRSxDQUFDO1FBQ3pDLE1BQU0sS0FBSyxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUNuRCxLQUFLLE1BQU0sTUFBTSxJQUFJLFlBQVksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUMxQyxNQUFNLEdBQUcsR0FBRyxHQUFHLE1BQU0s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
@@ -0,0 +1,2 @@
1
+ import type { Permission } from "./permissions";
2
+ export declare function additionalWritePermissions(value: unknown, creating?: boolean): Permission[];
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.additionalWritePermissions = additionalWritePermissions;
4
+ function additionalWritePermissions(value, creating = false) {
5
+ const needed = new Set();
6
+ const visit = (data, isCreate) => {
7
+ if (!data || typeof data !== "object")
8
+ return;
9
+ if (Array.isArray(data)) {
10
+ data.forEach((item) => visit(item, isCreate));
11
+ return;
12
+ }
13
+ for (const [key, child] of Object.entries(data)) {
14
+ if (key === "status" && (!isCreate || child !== "draft"))
15
+ needed.add("products.publish");
16
+ if (key === "delete")
17
+ needed.add("products.delete");
18
+ if (key === "create")
19
+ needed.add("products.create");
20
+ if (["price", "prices", "price_set", "price_sets", "amount"].includes(key))
21
+ needed.add("prices.edit");
22
+ if (key === "collection_id")
23
+ needed.add("collections.manage");
24
+ if (key === "categories" || key === "category_ids")
25
+ needed.add("categories.manage");
26
+ if (["inventory_items", "inventory_quantity"].includes(key) ||
27
+ (key === "manage_inventory" && (!isCreate || child !== true)) ||
28
+ (key === "allow_backorder" && (!isCreate || child !== false)))
29
+ needed.add("inventory.adjust");
30
+ if (["images", "thumbnail"].includes(key))
31
+ needed.add("media.manage");
32
+ // Traverse only native batch/variant envelopes, not arbitrary metadata.
33
+ if (["variants", "create", "update"].includes(key))
34
+ visit(child, key === "create" || (key === "variants" && isCreate));
35
+ }
36
+ };
37
+ visit(value, creating);
38
+ return [...needed];
39
+ }
40
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3JpdGUtcGVybWlzc2lvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2FjY2Vzcy93cml0ZS1wZXJtaXNzaW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLGdFQXFDQztBQXJDRCxTQUFnQiwwQkFBMEIsQ0FDeEMsS0FBYyxFQUNkLFFBQVEsR0FBRyxLQUFLO0lBRWhCLE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxFQUFjLENBQUE7SUFDcEMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxJQUFhLEVBQUUsUUFBaUIsRUFBRSxFQUFFO1FBQ2pELElBQUksQ0FBQyxJQUFJLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUTtZQUFFLE9BQU07UUFDN0MsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFBO1lBQzdDLE9BQU07UUFDUixDQUFDO1FBQ0QsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNoRCxJQUFJLEdBQUcsS0FBSyxRQUFRLElBQUksQ0FBQyxDQUFDLFFBQVEsSUFBSSxLQUFLLEtBQUssT0FBTyxDQUFDO2dCQUN0RCxNQUFNLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDLENBQUE7WUFDaEMsSUFBSSxHQUFHLEtBQUssUUFBUTtnQkFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLENBQUE7WUFDbkQsSUFBSSxHQUFHLEtBQUssUUFBUTtnQkFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLENBQUE7WUFDbkQsSUFDRSxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDO2dCQUV0RSxNQUFNLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxDQUFBO1lBQzNCLElBQUksR0FBRyxLQUFLLGVBQWU7Z0JBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFBO1lBQzdELElBQUksR0FBRyxLQUFLLFlBQVksSUFBSSxHQUFHLEtBQUssY0FBYztnQkFDaEQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO1lBQ2pDLElBQ0UsQ0FBQyxpQkFBaUIsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7Z0JBQ3ZELENBQUMsR0FBRyxLQUFLLGtCQUFrQixJQUFJLENBQUMsQ0FBQyxRQUFRLElBQUksS0FBSyxLQUFLLElBQUksQ0FBQyxDQUFDO2dCQUM3RCxDQUFDLEdBQUcsS0FBSyxpQkFBaUIsSUFBSSxDQUFDLENBQUMsUUFBUSxJQUFJLEtBQUssS0FBSyxLQUFLLENBQUMsQ0FBQztnQkFFN0QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFBO1lBQ2hDLElBQUksQ0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQztnQkFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFBO1lBQ3JFLHdFQUF3RTtZQUN4RSxJQUFJLENBQUMsVUFBVSxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDO2dCQUNoRCxLQUFLLENBQUMsS0FBSyxFQUFFLEdBQUcsS0FBSyxRQUFRLElBQUksQ0FBQyxHQUFHLEtBQUssVUFBVSxJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUE7UUFDdEUsQ0FBQztJQUNILENBQUMsQ0FBQTtJQUNELEtBQUssQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUE7SUFDdEIsT0FBTyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUE7QUFDcEIsQ0FBQyJ9
@@ -170,14 +170,18 @@ declare class AccessControlService extends AccessControlService_base {
170
170
  roles: import("../../lib/access/roles").ConfiguredRoleDefinition[];
171
171
  ids: string[];
172
172
  actors: import("../..").ActorProvider[];
173
+ resources: import("../..").ResourceDefinition[];
173
174
  contextResolvers: ((request: MedusaRequest) => PermissionContext | Promise<PermissionContext>)[];
174
175
  policyFor(method: string, path: string): import("../../lib/access/policy").Policy | null;
176
+ resolveRequest(request: MedusaRequest): Promise<import("../..").OperationDescriptor | null>;
175
177
  };
176
178
  permissionDefinitions(): import("../../lib/access/config").PermissionDefinition[];
177
179
  validatePermissions(values: unknown): string[];
178
180
  validateRules(values: unknown): PermissionRule[];
179
181
  private validateEditableRoleName;
182
+ /** Static inspection only; never a substitute for request resolution and enforcement. */
180
183
  policyFor(method: string, path: string): import("../../lib/access/policy").Policy | null;
184
+ resolveRequest(request: MedusaRequest): Promise<import("../..").OperationDescriptor | null>;
181
185
  permissionContext(request: MedusaRequest): Promise<PermissionContext>;
182
186
  validateActor(actor: ActorReference, request: MedusaRequest): Promise<void>;
183
187
  principalForRequest(request: MedusaRequest): Promise<AccessPrincipal | null>;