@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
@@ -3,249 +3,62 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.additionalWritePermissions = void 0;
6
7
  exports.normalizedPath = normalizedPath;
7
8
  exports.policyFor = policyFor;
8
9
  exports.isBootstrapRead = isBootstrapRead;
9
10
  exports.isSelfProfileUpdate = isSelfProfileUpdate;
10
11
  exports.can = can;
12
+ exports.nativeFieldSelection = nativeFieldSelection;
13
+ exports.nativePromotionRuleValue = nativePromotionRuleValue;
11
14
  exports.validateFieldSelection = validateFieldSelection;
12
- exports.additionalWritePermissions = additionalWritePermissions;
13
15
  const config_1 = require("./config");
14
- const native_routes_json_1 = __importDefault(require("./native-routes.json"));
15
16
  const native_fields_json_1 = __importDefault(require("./native-fields.json"));
16
- const read = (...permissions) => ({ permissions });
17
- const resourcePolicies = {
18
- products: {
19
- read: read("products.view", "prices.view"),
20
- write: read("products.edit"),
21
- },
22
- "product-variants": {
23
- read: read("products.view", "prices.view"),
24
- write: read("products.edit"),
25
- },
26
- "product-categories": {
27
- read: read("categories.view"),
28
- write: read("categories.manage"),
29
- },
30
- collections: {
31
- read: read("collections.view"),
32
- write: read("collections.manage"),
33
- },
34
- "product-types": {
35
- read: read("products.view"),
36
- write: read("product_options.manage"),
37
- },
38
- "product-tags": {
39
- read: read("products.view"),
40
- write: read("product_options.manage"),
41
- },
42
- "product-options": {
43
- read: read("products.view"),
44
- write: read("product_options.manage"),
45
- },
46
- "product-option-values": {
47
- read: read("products.view"),
48
- write: read("product_options.manage"),
49
- },
50
- "price-lists": { read: read("prices.view"), write: read("prices.edit") },
51
- "price-preferences": {
52
- read: read("prices.view"),
53
- write: read("prices.edit"),
54
- },
55
- "inventory-items": {
56
- read: read("inventory.view", "products.view", "prices.view", "stock_locations.view"),
57
- write: read("inventory.adjust"),
58
- },
59
- "stock-locations": {
60
- read: read("stock_locations.view"),
61
- write: read("stock_locations.manage"),
62
- },
63
- reservations: {
64
- read: read("inventory.view", "products.view", "prices.view"),
65
- write: read("inventory.adjust"),
66
- },
67
- orders: {
68
- read: read("orders.view"),
69
- write: read("orders.manage"),
70
- },
71
- "order-changes": {
72
- read: read("orders.view"),
73
- write: read("orders.manage"),
74
- },
75
- "draft-orders": {
76
- read: read("orders.view"),
77
- write: read("orders.manage"),
78
- },
79
- returns: {
80
- read: read("orders.view"),
81
- write: read("orders.manage"),
82
- },
83
- exchanges: {
84
- read: read("orders.view"),
85
- write: read("orders.manage"),
86
- },
87
- claims: {
88
- read: read("orders.view"),
89
- write: read("orders.manage"),
90
- },
91
- fulfillments: { read: read("orders.view"), write: read("orders.manage") },
92
- customers: { read: read("customers.view"), write: read("customers.manage") },
93
- "customer-groups": {
94
- read: read("customers.view"),
95
- write: read("customers.manage"),
96
- },
97
- payments: { read: read("payments.view"), write: read("payments.capture") },
98
- "payment-collections": {
99
- read: read("payments.view"),
100
- write: read("payments.capture"),
101
- },
102
- promotions: {
103
- read: read("promotions.view"),
104
- write: read("promotions.manage"),
105
- },
106
- campaigns: {
107
- read: read("promotions.view"),
108
- write: read("promotions.manage"),
109
- },
110
- uploads: { read: read("media.manage"), write: read("media.manage") },
111
- };
112
- const settings = [
113
- "stores",
114
- "regions",
115
- "currencies",
116
- "countries",
117
- "sales-channels",
118
- "shipping-profiles",
119
- "shipping-options",
120
- "shipping-option-types",
121
- "fulfillment-providers",
122
- "fulfillment-sets",
123
- "tax-regions",
124
- "tax-rates",
125
- "tax-providers",
126
- "return-reasons",
127
- "refund-reasons",
128
- "locales",
129
- "translations",
130
- ];
131
- for (const resource of settings)
132
- resourcePolicies[resource] = {
133
- read: read("settings.view"),
134
- write: read("settings.manage"),
135
- };
136
- const patterns = native_routes_json_1.default.map((route) => ({
137
- ...route,
138
- pattern: new RegExp("^" +
139
- route.path
140
- .split("/")
141
- .map((segment) => segment.startsWith(":")
142
- ? "[^/]+"
143
- : segment.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"))
144
- .join("/") +
145
- "$", "i"),
146
- }));
147
- const bootstrapReads = new Set([
148
- "/admin/stores",
149
- "/admin/users/me",
150
- "/admin/feature-flags",
151
- "/admin/plugins",
152
- "/admin/access/me",
153
- ]);
17
+ const permissions_1 = require("./permissions");
18
+ const route_facts_1 = require("./route-facts");
19
+ const native_resources_1 = require("./native-resources");
20
+ var write_permissions_1 = require("./write-permissions");
21
+ Object.defineProperty(exports, "additionalWritePermissions", { enumerable: true, get: function () { return write_permissions_1.additionalWritePermissions; } });
154
22
  function normalizedPath(url) {
155
- const raw = url.split("?")[0];
156
- // Express decodes parameter values. Reject encoded separators and ambiguous canonical forms.
157
- if (/%(?:2f|5c|2e|25)/i.test(raw) || raw.includes("\\") || raw.includes("//"))
158
- return null;
159
- return raw.replace(/\/+$/, "").toLowerCase();
23
+ return (0, route_facts_1.canonicalPath)(url)?.toLowerCase() ?? null;
160
24
  }
25
+ /** Structural inspection; request body, scope and payload grants require resolveRequest. */
161
26
  function policyFor(method, path) {
162
- const verb = method === "HEAD" ? "GET" : method;
163
- if (verb === "GET" && bootstrapReads.has(path))
164
- return read();
165
- if (verb === "GET" && path === "/admin/access/invites")
166
- return { permissions: [], superuser: true };
167
- if ((verb === "GET" && /^\/admin\/access\/actors\/[^/]+$/.test(path)) ||
168
- (["GET", "POST"].includes(verb) &&
169
- /^\/admin\/access\/actors\/[^/]+\/[^/]+$/.test(path)))
170
- return { permissions: [], superuser: true };
171
- if (verb === "GET" && /^\/admin\/access\/roles(?:\/[^/]+)?$/.test(path))
172
- return read("roles.view");
173
- if (verb === "POST" && path === "/admin/access/evaluate")
174
- return { permissions: [], superuser: true };
175
- if (verb === "GET" && /^\/admin\/access\/staff(?:\/[^/]+)?$/.test(path))
176
- return read("staff.view");
177
- if ((verb === "POST" && path === "/admin/access/invites") ||
178
- (verb === "DELETE" && /^\/admin\/access\/invites\/[^/]+$/.test(path)) ||
179
- (verb === "POST" && path === "/admin/access/roles") ||
180
- (["POST", "DELETE"].includes(verb) &&
181
- /^\/admin\/access\/roles\/[^/]+$/.test(path)) ||
182
- (["POST", "DELETE"].includes(verb) &&
183
- /^\/admin\/access\/staff\/[^/]+$/.test(path))) {
184
- return { permissions: [], superuser: true };
185
- }
186
- if (path === "/admin/access/permissions" && verb === "GET")
187
- return read("roles.view");
188
- if (path === "/admin/access/audit" && verb === "GET")
189
- return read("audit.view");
190
- // No access to Enterprise APIs, arbitrary workflows, keys, generic search or exports by accident.
191
- if (/^\/admin\/(rbac|workflows|workflow-executions|api-keys|search|search-indexes)(\/|$)/.test(path))
192
- return null;
193
- const route = patterns.find((r) => r.pattern.test(path) && r.methods.includes(verb));
194
- if (!route)
195
- return null;
196
- const resource = path.split("/")[2];
197
- if (resource === "users") {
198
- if (verb === "GET")
199
- return { permissions: ["staff.view"], superuser: true };
200
- if ((verb === "POST" &&
201
- /^\/admin\/users\/[^/]+(?:\/reset-password)?$/.test(path)) ||
202
- (verb === "DELETE" && /^\/admin\/users\/[^/]+$/.test(path)))
203
- return { permissions: [], superuser: true };
204
- return null;
205
- }
206
- if (resource === "invites")
207
- return { permissions: [], superuser: true };
208
- const policies = resourcePolicies[resource];
209
- if (!policies)
210
- return null;
211
- if (path.includes("/export"))
212
- return resource === "products"
213
- ? read("products.view", "prices.view", "products.export")
214
- : null;
215
- if (verb === "GET") {
216
- return policies.read;
217
- }
218
- if (/\/refund(?:\/|$)/.test(path))
219
- return read("refunds.issue");
220
- if (path.includes("/cancel") && ["orders", "draft-orders"].includes(resource))
221
- return read("orders.cancel");
222
- if (resource === "products" || resource === "product-variants") {
223
- if (path.includes("/import"))
224
- return read("products.import", "products.create", "products.edit", "prices.edit");
225
- if (verb === "DELETE")
226
- return read("products.delete");
227
- if (path === "/admin/products")
228
- return read("products.create");
229
- }
230
- return policies.write;
27
+ return (0, native_resources_1.describeNative)(method, path, {})?.policy || null;
231
28
  }
232
29
  function isBootstrapRead(method, path) {
233
- return ["GET", "HEAD"].includes(method) && bootstrapReads.has(path);
30
+ return (["GET", "HEAD"].includes(method) &&
31
+ ["authenticated", "public"].includes((0, native_resources_1.describeNative)(method, path)?.access || ""));
234
32
  }
235
33
  function isSelfProfileUpdate(method, path, userId, body) {
236
- return (method === "POST" &&
237
- path === `/admin/users/${userId.toLowerCase()}` &&
238
- Boolean(body) &&
239
- typeof body === "object" &&
240
- !Array.isArray(body) &&
241
- Object.keys(body).every((key) => ["first_name", "last_name", "avatar_url"].includes(key)));
34
+ const descriptor = (0, native_resources_1.describeNative)(method, path, body, userId);
35
+ return Boolean(descriptor?.self);
242
36
  }
243
37
  function can(principal, policy, context = {}) {
244
- return (principal.active &&
245
- (!policy.superuser || principal.is_superuser) &&
246
- policy.permissions.every((p) => (0, config_1.evaluatePermission)(principal, p, context)));
38
+ return ((0, permissions_1.isSuperuser)(principal) ||
39
+ (principal.active &&
40
+ !policy.superuser &&
41
+ policy.permissions.every((p) => (0, config_1.evaluatePermission)(principal, p, context))));
42
+ }
43
+ /** Dashboard's group picker only reads member IDs to disable existing choices. */
44
+ function nativeFieldSelection(resource, fields) {
45
+ return resource === "customer-groups" && fields === "*customers"
46
+ ? "+customers.id"
47
+ : fields;
247
48
  }
248
- function validateFieldSelection(resource, fields) {
49
+ /** Native promotion rule picker hydrates a selected sales channel by ID. */
50
+ function nativePromotionRuleValue(resource, params, query) {
51
+ if (resource === "promotions" &&
52
+ params.rule_type === "rules" &&
53
+ params.rule_attribute_id === "sales_channel" &&
54
+ query.limit === "1" &&
55
+ query.value === undefined &&
56
+ typeof query.id === "string" &&
57
+ /^sc_[a-z0-9]+$/i.test(query.id))
58
+ return query.id;
59
+ return undefined;
60
+ }
61
+ function validateFieldSelection(resource, fields, override) {
249
62
  if (fields === undefined)
250
63
  return true;
251
64
  if (typeof fields !== "string" || fields.length > 4000)
@@ -255,17 +68,112 @@ function validateFieldSelection(resource, fields) {
255
68
  // Narrow relation IDs requested by native Admin list/count screens.
256
69
  collections: ["products.id"],
257
70
  "customer-groups": ["customers.id"],
71
+ // Dashboard 2.22.2 customer detail loads the native addresses relation.
72
+ customers: ["*addresses", "*groups"],
73
+ campaigns: ["promotions.id"],
74
+ "price-lists": [
75
+ "*prices",
76
+ "prices.price_set.variant.id",
77
+ "prices.price_rules.attribute",
78
+ "prices.price_rules.value",
79
+ ],
80
+ // Order summary and timeline request these owning order-module relations.
81
+ returns: ["*items", "*items.reason"],
82
+ claims: ["*additional_items"],
83
+ exchanges: ["*additional_items"],
84
+ // Native settings and taxonomy detail components select these named links.
85
+ regions: ["*payment_providers"],
86
+ "shipping-options": [
87
+ "service_zone.fulfillment_set.type",
88
+ "service_zone.fulfillment_set.location.id",
89
+ ],
90
+ "product-categories": ["products.id"],
91
+ "product-options": ["values.id", "values.value", "values.rank"],
92
+ "stock-locations": [
93
+ "*sales_channels",
94
+ "*address",
95
+ "*fulfillment_sets",
96
+ "*fulfillment_sets.service_zones",
97
+ "*fulfillment_sets.service_zones.shipping_options",
98
+ "*fulfillment_sets.service_zones.shipping_options.shipping_profile",
99
+ "fulfillment_sets.type",
100
+ "fulfillment_sets.name",
101
+ "*fulfillment_sets.service_zones.geo_zones",
102
+ "fulfillment_sets.service_zones.name",
103
+ "*fulfillment_sets.service_zones.shipping_options.rules",
104
+ "*fulfillment_providers",
105
+ ],
258
106
  // Native Admin requests these computed order summaries explicitly.
259
- orders: ["payment_status", "fulfillment_status"],
107
+ orders: [
108
+ "items.variant.product.shipping_profile.id",
109
+ "shipping_methods.shipping_option_id",
110
+ "items.variant.product.title",
111
+ "*items.variant.inventory",
112
+ "*items.variant.inventory.location_levels",
113
+ "*items.variant.inventory_items",
114
+ "payment_status",
115
+ "fulfillment_status",
116
+ // The customer detail order table displays the shipping country.
117
+ "shipping_address.country_code",
118
+ "item_discount_total",
119
+ "discount_subtotal",
120
+ "shipping_discount_total",
121
+ "refundable_total",
122
+ "order_change",
123
+ "*items.variant.options",
124
+ "items.variant.manage_inventory",
125
+ "*items.variant.inventory_items.inventory",
126
+ "items.variant.inventory_items.required_quantity",
127
+ "*promotions",
128
+ "fulfillments.shipping_option.service_zone.fulfillment_set.type",
129
+ "*fulfillments.items",
130
+ "*fulfillments.labels",
131
+ "*payment_collections.payment_sessions",
132
+ "*payment_collections.payments.refunds.refund_reason",
133
+ "region.automatic_taxes",
134
+ ],
260
135
  products: [
136
+ "images.id",
137
+ "images.url",
138
+ "images.variants.id",
261
139
  "*categories",
140
+ // Option detail lists the owning Product module join records.
141
+ "*product_options",
142
+ // Dashboard's native product detail also expands this linked profile.
143
+ "*shipping_profile",
262
144
  "variants.id",
263
145
  "variants.inventory_quantity",
264
146
  "variants.inventory_items.inventory.location_levels",
265
147
  "variants.inventory_items.required_quantity",
266
148
  ],
149
+ // Dashboard 2.22.2 inventory-detail/constants.ts requests these linked data.
150
+ // Inventory reads already require product, price and stock-location access.
151
+ "inventory-items": [
152
+ "*variants",
153
+ "*variants.product",
154
+ "*variants.options",
155
+ // The location-level table selects only these related location fields.
156
+ "stock_locations.id",
157
+ "stock_locations.name",
158
+ ],
267
159
  "product-variants": [
160
+ "*product.images",
161
+ "*images",
268
162
  "inventory_quantity",
163
+ "inventory_items.*",
164
+ "inventory_items.inventory.id",
165
+ "inventory_items.inventory.title",
166
+ "inventory_items.inventory.sku",
167
+ // Reviewed native Variant table/detail expansions. Inventory grants are
168
+ // checked separately by the Admin middleware.
169
+ "*inventory_items",
170
+ "*inventory_items.inventory",
171
+ "*inventory_items.inventory.location_levels",
172
+ "*options.option",
173
+ "*prices.price_rules",
174
+ "images.id",
175
+ "images.url",
176
+ "images.variants.id",
269
177
  "product.id",
270
178
  "product.title",
271
179
  "product.handle",
@@ -274,49 +182,26 @@ function validateFieldSelection(resource, fields) {
274
182
  "product.metadata",
275
183
  ],
276
184
  users: ["id", "email", "first_name", "last_name", "avatar_url"],
185
+ // Layout list query configuration lives below configurations/query-config.
186
+ layouts: [
187
+ "id",
188
+ "zone",
189
+ "user_id",
190
+ "is_system_default",
191
+ "configuration",
192
+ "created_at",
193
+ "updated_at",
194
+ ],
277
195
  };
278
- const allowed = new Set([...safe, ...(extra[resource] || [])]);
196
+ const allowed = new Set(override || [...safe, ...(extra[resource] || [])]);
279
197
  return fields.split(",").every((value) => {
280
198
  const field = value.trim();
199
+ // The option detail excludes the products relation; adding it remains denied.
200
+ if (!override && resource === "product-options" && field === "-products")
201
+ return true;
281
202
  const name = field.replace(/^[+-]/, "");
282
203
  // Native Admin also selects reviewed relations without the '*' prefix.
283
204
  return allowed.has(name) || allowed.has(`*${name}`);
284
205
  });
285
206
  }
286
- function additionalWritePermissions(value, creating = false) {
287
- const needed = new Set();
288
- const visit = (data, isCreate) => {
289
- if (!data || typeof data !== "object")
290
- return;
291
- if (Array.isArray(data)) {
292
- data.forEach((item) => visit(item, isCreate));
293
- return;
294
- }
295
- for (const [key, child] of Object.entries(data)) {
296
- if (key === "status" && (!isCreate || child !== "draft"))
297
- needed.add("products.publish");
298
- if (key === "delete")
299
- needed.add("products.delete");
300
- if (key === "create")
301
- needed.add("products.create");
302
- if (["price", "prices", "price_set", "price_sets", "amount"].includes(key))
303
- needed.add("prices.edit");
304
- if (key === "collection_id")
305
- needed.add("collections.manage");
306
- if (key === "categories" || key === "category_ids")
307
- needed.add("categories.manage");
308
- if (["inventory_items", "inventory_quantity"].includes(key) ||
309
- (key === "manage_inventory" && (!isCreate || child !== true)) ||
310
- (key === "allow_backorder" && (!isCreate || child !== false)))
311
- needed.add("inventory.adjust");
312
- if (["images", "thumbnail"].includes(key))
313
- needed.add("media.manage");
314
- // Traverse only native batch/variant envelopes, not arbitrary metadata.
315
- if (["variants", "create", "update"].includes(key))
316
- visit(child, key === "create" || (key === "variants" && isCreate));
317
- }
318
- };
319
- visit(value, creating);
320
- return [...needed];
321
- }
322
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9saWN5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9hY2Nlc3MvcG9saWN5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBNEpBLHdDQU1DO0FBRUQsOEJBK0VDO0FBRUQsMENBRUM7QUFFRCxrREFnQkM7QUFFRCxrQkFVQztBQUVELHdEQXNDQztBQUVELGdFQXFDQztBQXBXRCxxQ0FBcUU7QUFDckUsOEVBQStDO0FBQy9DLDhFQUErQztBQUkvQyxNQUFNLElBQUksR0FBRyxDQUFDLEdBQUcsV0FBeUIsRUFBVSxFQUFFLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUE7QUFDeEUsTUFBTSxnQkFBZ0IsR0FBb0Q7SUFDeEUsUUFBUSxFQUFFO1FBQ1IsSUFBSSxFQUFFLElBQUksQ0FBQyxlQUFlLEVBQUUsYUFBYSxDQUFDO1FBQzFDLEtBQUssRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDO0tBQzdCO0lBQ0Qsa0JBQWtCLEVBQUU7UUFDbEIsSUFBSSxFQUFFLElBQUksQ0FBQyxlQUFlLEVBQUUsYUFBYSxDQUFDO1FBQzFDLEtBQUssRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDO0tBQzdCO0lBQ0Qsb0JBQW9CLEVBQUU7UUFDcEIsSUFBSSxFQUFFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztRQUM3QixLQUFLLEVBQUUsSUFBSSxDQUFDLG1CQUFtQixDQUFDO0tBQ2pDO0lBQ0QsV0FBVyxFQUFFO1FBQ1gsSUFBSSxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztRQUM5QixLQUFLLEVBQUUsSUFBSSxDQUFDLG9CQUFvQixDQUFDO0tBQ2xDO0lBQ0QsZUFBZSxFQUFFO1FBQ2YsSUFBSSxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUM7UUFDM0IsS0FBSyxFQUFFLElBQUksQ0FBQyx3QkFBd0IsQ0FBQztLQUN0QztJQUNELGNBQWMsRUFBRTtRQUNkLElBQUksRUFBRSxJQUFJLENBQUMsZUFBZSxD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
207
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9saWN5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9hY2Nlc3MvcG9saWN5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQWFBLHdDQUVDO0FBR0QsOEJBRUM7QUFFRCwwQ0FPQztBQUVELGtEQVFDO0FBRUQsa0JBYUM7QUFHRCxvREFPQztBQUdELDREQWdCQztBQUVELHdEQW1KQztBQXhPRCxxQ0FBcUU7QUFDckUsOEVBQStDO0FBQy9DLCtDQUlzQjtBQUN0QiwrQ0FBNkM7QUFDN0MseURBQW1EO0FBQ25ELHlEQUFnRTtBQUF2RCwrSEFBQSwwQkFBMEIsT0FBQTtBQUluQyxTQUFnQixjQUFjLENBQUMsR0FBVztJQUN4QyxPQUFPLElBQUEsMkJBQWEsRUFBQyxHQUFHLENBQUMsRUFBRSxXQUFXLEVBQUUsSUFBSSxJQUFJLENBQUE7QUFDbEQsQ0FBQztBQUVELDRGQUE0RjtBQUM1RixTQUFnQixTQUFTLENBQUMsTUFBYyxFQUFFLElBQVk7SUFDcEQsT0FBTyxJQUFBLGlDQUFjLEVBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsRUFBRSxNQUFNLElBQUksSUFBSSxDQUFBO0FBQ3pELENBQUM7QUFFRCxTQUFnQixlQUFlLENBQUMsTUFBYyxFQUFFLElBQVk7SUFDMUQsT0FBTyxDQUNMLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7UUFDaEMsQ0FBQyxlQUFlLEVBQUUsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUNsQyxJQUFBLGlDQUFjLEVBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxFQUFFLE1BQU0sSUFBSSxFQUFFLENBQzNDLENBQ0YsQ0FBQTtBQUNILENBQUM7QUFFRCxTQUFnQixtQkFBbUIsQ0FDakMsTUFBYyxFQUNkLElBQVksRUFDWixNQUFjLEVBQ2QsSUFBYTtJQUViLE1BQU0sVUFBVSxHQUFHLElBQUEsaUNBQWMsRUFBQyxNQUFN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
@@ -0,0 +1,107 @@
1
+ import type { MedusaRequest } from "@medusajs/framework/http";
2
+ import type { RouteFacts, RouteMethod, RouteRegistration } from "./route-facts";
3
+ import { type AccessPrincipal } from "./permissions";
4
+ export type AccessMode = "public" | "authenticated" | "active-principal";
5
+ export type ResourceScope = "global" | "personal" | "shared";
6
+ export type CapabilityPolicy = {
7
+ permissions: readonly string[];
8
+ superuser?: boolean;
9
+ access?: AccessMode;
10
+ scopes?: Partial<Record<ResourceScope, readonly string[]>>;
11
+ };
12
+ export type ProfileAction = {
13
+ operation: string;
14
+ fieldResource?: string;
15
+ payload?: (request: MedusaRequest, operation: OperationDescriptor) => readonly string[] | null | Promise<readonly string[] | null>;
16
+ scope?: {
17
+ kind: "boolean";
18
+ field: string;
19
+ } | {
20
+ kind: "personal";
21
+ };
22
+ forceFields?: readonly string[];
23
+ fallbackFields?: {
24
+ permissions: readonly string[];
25
+ fields: readonly string[];
26
+ };
27
+ self?: {
28
+ parameter: string;
29
+ fields: readonly string[];
30
+ responseFields: readonly string[];
31
+ };
32
+ redirect?: {
33
+ destination: string;
34
+ parameter: string;
35
+ };
36
+ };
37
+ export type ResourceProfile = {
38
+ actions?: Partial<Record<RouteMethod, string | ProfileAction>>;
39
+ item?: {
40
+ parameter: string;
41
+ profile: ResourceProfile;
42
+ };
43
+ children?: Readonly<Record<string, ResourceProfile>>;
44
+ };
45
+ export type OperationDescriptor = {
46
+ facts: RouteFacts;
47
+ resource: string;
48
+ operation: string;
49
+ scope: ResourceScope;
50
+ params: Record<string, string>;
51
+ fieldResource: string;
52
+ actorTypes: readonly string[];
53
+ access: AccessMode;
54
+ self: boolean;
55
+ policy: {
56
+ permissions: string[];
57
+ superuser?: boolean;
58
+ };
59
+ action: ProfileAction;
60
+ fields?: readonly string[];
61
+ fieldRequirements: readonly {
62
+ pattern: RegExp;
63
+ permissions: readonly string[];
64
+ }[];
65
+ };
66
+ export type ResourceDefinition = {
67
+ key: string;
68
+ namespace?: string;
69
+ root: string;
70
+ profile: ResourceProfile;
71
+ operations: Readonly<Record<string, CapabilityPolicy>>;
72
+ actorTypes: readonly string[];
73
+ fields?: readonly string[];
74
+ fieldRequirements?: readonly {
75
+ pattern: RegExp;
76
+ permissions: readonly string[];
77
+ }[];
78
+ resolveScope?: (request: MedusaRequest, operation: {
79
+ facts: RouteFacts;
80
+ resource: string;
81
+ operation: string;
82
+ params: Record<string, string>;
83
+ }) => ResourceScope | null | Promise<ResourceScope | null>;
84
+ };
85
+ export declare function defineResource<const T extends ResourceDefinition>(definition: T): T;
86
+ export declare function crudProfile(options?: {
87
+ parameter?: string;
88
+ read?: string;
89
+ create?: string;
90
+ update?: string;
91
+ delete?: string;
92
+ children?: Readonly<Record<string, ResourceProfile>>;
93
+ }): ResourceProfile;
94
+ export declare function commandProfile(operation: string, method?: RouteMethod): ResourceProfile;
95
+ export declare function actorOwnedPreferences(options: {
96
+ parameter: string;
97
+ member: string;
98
+ list: string;
99
+ sharedField: string;
100
+ }): ResourceProfile;
101
+ export declare function profileAction(profile: ResourceProfile, facts: RouteFacts): ProfileAction | null;
102
+ export declare function resourceRoutes(resource: ResourceDefinition): RouteRegistration[];
103
+ export declare function describeResource(resource: ResourceDefinition, facts: RouteFacts, body?: unknown, actorId?: string, resolvedScope?: ResourceScope): OperationDescriptor | null;
104
+ export declare function describeResources(resources: readonly ResourceDefinition[], method: string, url: string, body?: unknown, actorId?: string): OperationDescriptor | null;
105
+ export declare function operationAllowed(principal: AccessPrincipal | null, operation: OperationDescriptor, allows: (permission: string) => boolean): boolean;
106
+ /** Validate host-owned registrations. Native resources cannot be replaced. */
107
+ export declare function validateResources(value: unknown, permissions: readonly string[], reserved: readonly Pick<ResourceDefinition, "key" | "root" | "namespace">[]): ResourceDefinition[];