@webiny/api-aco 5.37.8 → 5.38.0-beta.0

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 (102) hide show
  1. package/apps/AcoApp.d.ts +4 -0
  2. package/apps/AcoApp.js +44 -5
  3. package/apps/AcoApp.js.map +1 -1
  4. package/apps/AcoApps.js +3 -1
  5. package/apps/app.gql.js +6 -4
  6. package/apps/app.gql.js.map +1 -1
  7. package/apps/index.js +3 -1
  8. package/createAcoContext.js +90 -15
  9. package/createAcoContext.js.map +1 -1
  10. package/createAcoGraphQL.js +5 -2
  11. package/createAcoGraphQL.js.map +1 -1
  12. package/createAcoHooks.js +9 -3
  13. package/createAcoHooks.js.map +1 -1
  14. package/createAcoModels.js +5 -2
  15. package/createAcoModels.js.map +1 -1
  16. package/createAcoStorageOperations.js +5 -2
  17. package/createAcoStorageOperations.js.map +1 -1
  18. package/fields/index.js +3 -1
  19. package/fields/location.js +3 -1
  20. package/filter/filter.crud.d.ts +3 -0
  21. package/filter/filter.crud.js +94 -0
  22. package/filter/filter.crud.js.map +1 -0
  23. package/filter/filter.gql.d.ts +3 -0
  24. package/filter/filter.gql.js +150 -0
  25. package/filter/filter.gql.js.map +1 -0
  26. package/filter/filter.model.d.ts +4 -0
  27. package/filter/filter.model.js +127 -0
  28. package/filter/filter.model.js.map +1 -0
  29. package/filter/filter.so.d.ts +3 -0
  30. package/filter/filter.so.js +96 -0
  31. package/filter/filter.so.js.map +1 -0
  32. package/filter/filter.types.d.ts +95 -0
  33. package/filter/filter.types.js +14 -0
  34. package/filter/filter.types.js.map +1 -0
  35. package/folder/folder.crud.d.ts +8 -1
  36. package/folder/folder.crud.js +197 -15
  37. package/folder/folder.crud.js.map +1 -1
  38. package/folder/folder.gql.js +75 -7
  39. package/folder/folder.gql.js.map +1 -1
  40. package/folder/folder.model.js +49 -3
  41. package/folder/folder.model.js.map +1 -1
  42. package/folder/folder.so.js +12 -4
  43. package/folder/folder.so.js.map +1 -1
  44. package/folder/folder.types.d.ts +23 -0
  45. package/folder/folder.types.js +3 -1
  46. package/folder/folder.types.js.map +1 -1
  47. package/folder/onFolderBeforeDeleteAco.hook.d.ts +2 -0
  48. package/folder/{onFolderBeforeDelete.hook.js → onFolderBeforeDeleteAco.hook.js} +8 -6
  49. package/folder/onFolderBeforeDeleteAco.hook.js.map +1 -0
  50. package/folder/onFolderBeforeDeleteFm.hook.d.ts +2 -0
  51. package/folder/onFolderBeforeDeleteFm.hook.js +49 -0
  52. package/folder/onFolderBeforeDeleteFm.hook.js.map +1 -0
  53. package/folder/onFolderBeforeDeleteHcms.hook.d.ts +2 -0
  54. package/folder/onFolderBeforeDeleteHcms.hook.js +56 -0
  55. package/folder/onFolderBeforeDeleteHcms.hook.js.map +1 -0
  56. package/index.d.ts +1 -0
  57. package/index.js +12 -2
  58. package/index.js.map +1 -1
  59. package/package.json +25 -20
  60. package/plugins/AcoAppModifierPlugin.js +3 -1
  61. package/plugins/AcoAppRegisterPlugin.js +3 -1
  62. package/plugins/index.js +3 -1
  63. package/record/graphql/createAppResolvers.js +11 -9
  64. package/record/graphql/createAppResolvers.js.map +1 -1
  65. package/record/graphql/createAppSchema.js +3 -1
  66. package/record/record.crud.js +3 -1
  67. package/record/record.gql.js +3 -1
  68. package/record/record.model.js +3 -1
  69. package/record/record.so.js +3 -1
  70. package/record/record.types.d.ts +2 -1
  71. package/record/record.types.js +3 -1
  72. package/record/record.types.js.map +1 -1
  73. package/types.d.ts +19 -5
  74. package/types.js +16 -1
  75. package/types.js.map +1 -1
  76. package/utils/FolderLevelPermissions.d.ts +65 -0
  77. package/utils/FolderLevelPermissions.js +355 -0
  78. package/utils/FolderLevelPermissions.js.map +1 -0
  79. package/utils/acoRecordId.js +3 -1
  80. package/utils/createListSort.js +3 -1
  81. package/utils/createModelField.js +3 -1
  82. package/utils/createOperationsWrapper.js +3 -1
  83. package/utils/decorators/CmsEntriesCrudDecorators.d.ts +11 -0
  84. package/utils/decorators/CmsEntriesCrudDecorators.js +175 -0
  85. package/utils/decorators/CmsEntriesCrudDecorators.js.map +1 -0
  86. package/utils/ensureAuthentication.d.ts +2 -0
  87. package/utils/{checkPermissions.js → ensureAuthentication.js} +5 -3
  88. package/utils/ensureAuthentication.js.map +1 -0
  89. package/utils/fieldResolver.js +3 -1
  90. package/utils/getFieldValues.d.ts +2 -0
  91. package/utils/getFieldValues.js +9 -1
  92. package/utils/getFieldValues.js.map +1 -1
  93. package/utils/getFolderAndItsAncestors.d.ts +2 -2
  94. package/utils/getFolderAndItsAncestors.js +16 -11
  95. package/utils/getFolderAndItsAncestors.js.map +1 -1
  96. package/utils/isInstallationPending.js +3 -1
  97. package/utils/modelFactory.js +3 -1
  98. package/utils/resolve.js +3 -1
  99. package/folder/onFolderBeforeDelete.hook.d.ts +0 -2
  100. package/folder/onFolderBeforeDelete.hook.js.map +0 -1
  101. package/utils/checkPermissions.d.ts +0 -2
  102. package/utils/checkPermissions.js.map +0 -1
@@ -1,3 +1,10 @@
1
1
  import { CreateAcoParams } from "../types";
2
2
  import { AcoFolderCrud } from "./folder.types";
3
- export declare const createFolderCrudMethods: ({ storageOperations }: CreateAcoParams) => AcoFolderCrud;
3
+ import { AdminUser } from "@webiny/api-admin-users/types";
4
+ import { Team } from "@webiny/api-security/types";
5
+ interface CreateFolderCrudMethodsParams extends CreateAcoParams {
6
+ listAdminUsers: () => Promise<AdminUser[]>;
7
+ listTeams: () => Promise<Team[]>;
8
+ }
9
+ export declare const createFolderCrudMethods: ({ storageOperations, folderLevelPermissions, listAdminUsers, listTeams }: CreateFolderCrudMethodsParams) => AcoFolderCrud;
10
+ export {};
@@ -1,13 +1,23 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
7
  exports.createFolderCrudMethods = void 0;
8
+ var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
7
9
  var _pubsub = require("@webiny/pubsub");
10
+ var _validation = require("@webiny/validation");
8
11
  var _getFolderAndItsAncestors = require("../utils/getFolderAndItsAncestors");
12
+ var _NotAuthorizedError = _interopRequireDefault(require("@webiny/api-security/NotAuthorizedError"));
13
+ var _structuredClone = _interopRequireDefault(require("@ungap/structured-clone"));
14
+ var _error = _interopRequireDefault(require("@webiny/error"));
15
+ const FIXED_FOLDER_LISTING_LIMIT = 10_000;
9
16
  const createFolderCrudMethods = ({
10
- storageOperations
17
+ storageOperations,
18
+ folderLevelPermissions,
19
+ listAdminUsers,
20
+ listTeams
11
21
  }) => {
12
22
  // create
13
23
  const onFolderBeforeCreate = (0, _pubsub.createTopic)("aco.onFolderBeforeCreate");
@@ -29,20 +39,81 @@ const createFolderCrudMethods = ({
29
39
  onFolderBeforeDelete,
30
40
  onFolderAfterDelete,
31
41
  async get(id) {
32
- return storageOperations.getFolder({
42
+ const folder = await storageOperations.getFolder({
33
43
  id
34
44
  });
45
+ await folderLevelPermissions.ensureCanAccessFolder({
46
+ folder,
47
+ rwd: "r"
48
+ });
49
+ await folderLevelPermissions.assignFolderPermissions(folder);
50
+ return folder;
35
51
  },
36
52
  async list(params) {
37
- return storageOperations.listFolders(params);
53
+ // No matter what was the limit set in the params, initially, we always retrieve
54
+ // all folders. The limit is then applied with the filtered folders list below.
55
+ const filteredFolders = await folderLevelPermissions.listAllFoldersWithPermissions(params.where.type).then(filteredFolders => {
56
+ // If `parentId` was included in the `where` clause, we need to filter the folders.
57
+ // TODO: we might want to incorporate this into the `listAllFoldersWithPermissions` method.
58
+ if (params.where.parentId) {
59
+ // Filter by parent ID.
60
+ return filteredFolders.filter(folder => folder.parentId === params.where.parentId);
61
+ }
62
+ return filteredFolders;
63
+ });
64
+ const totalCount = filteredFolders.length;
65
+ let hasMoreItems = false;
66
+ let cursor = null;
67
+
68
+ // Apply cursor/limit params.
69
+ if (params.after) {
70
+ const afterListItemIndex = filteredFolders.findIndex(folder => folder.id === params.after);
71
+ if (afterListItemIndex >= 0) {
72
+ // Remove all items below the "after" item.
73
+ filteredFolders.splice(0, afterListItemIndex + 1);
74
+ }
75
+ }
76
+ hasMoreItems = !!params.limit && filteredFolders.length > params.limit;
77
+ if (hasMoreItems) {
78
+ var _filteredFolders;
79
+ cursor = ((_filteredFolders = filteredFolders[params.limit - 1]) === null || _filteredFolders === void 0 ? void 0 : _filteredFolders.id) || null;
80
+ filteredFolders.splice(params.limit);
81
+ }
82
+ return [filteredFolders, {
83
+ totalCount,
84
+ hasMoreItems,
85
+ cursor
86
+ }];
87
+ },
88
+ async listAll(params) {
89
+ return this.list((0, _objectSpread2.default)((0, _objectSpread2.default)({}, params), {}, {
90
+ limit: FIXED_FOLDER_LISTING_LIMIT
91
+ }));
38
92
  },
39
93
  async create(data) {
94
+ let canCreateFolder = false;
95
+ if (data.parentId) {
96
+ const parentFolder = await storageOperations.getFolder({
97
+ id: data.parentId
98
+ });
99
+ canCreateFolder = await folderLevelPermissions.canAccessFolder({
100
+ folder: parentFolder,
101
+ rwd: "w"
102
+ });
103
+ } else {
104
+ canCreateFolder = await folderLevelPermissions.canCreateFolderInRoot();
105
+ }
106
+ if (!canCreateFolder) {
107
+ throw new _NotAuthorizedError.default();
108
+ }
40
109
  await onFolderBeforeCreate.publish({
41
110
  input: data
42
111
  });
43
112
  const folder = await storageOperations.createFolder({
44
113
  data
45
114
  });
115
+ folderLevelPermissions.invalidateCache();
116
+ await folderLevelPermissions.assignFolderPermissions(folder);
46
117
  await onFolderAfterCreate.publish({
47
118
  folder
48
119
  });
@@ -52,6 +123,63 @@ const createFolderCrudMethods = ({
52
123
  const original = await storageOperations.getFolder({
53
124
  id
54
125
  });
126
+ const canUpdateFolder = await folderLevelPermissions.canAccessFolder({
127
+ folder: original,
128
+ rwd: "w"
129
+ });
130
+ if (!canUpdateFolder) {
131
+ throw new _NotAuthorizedError.default();
132
+ }
133
+
134
+ // Validate data.
135
+ if (Array.isArray(data.permissions)) {
136
+ data.permissions.forEach(permission => {
137
+ const targetIsValid = permission.target.startsWith("admin:") || permission.target.startsWith("team:");
138
+ if (!targetIsValid) {
139
+ throw new Error(`Permission target "${permission.target}" is not valid.`);
140
+ }
141
+ if (permission.inheritedFrom) {
142
+ throw new Error(`Permission "inheritedFrom" cannot be set manually.`);
143
+ }
144
+ });
145
+ }
146
+
147
+ // Parent change is not allowed if the user doesn't have access to the new parent.
148
+ if (data.parentId && data.parentId !== original.parentId) {
149
+ try {
150
+ // Getting the parent folder will throw an error if the user doesn't have access.
151
+ await this.get(data.parentId);
152
+ } catch (e) {
153
+ if (e instanceof _NotAuthorizedError.default) {
154
+ throw new _error.default(`Cannot move folder to a new parent because you don't have access to the new parent.`, "CANNOT_MOVE_FOLDER_TO_NEW_PARENT");
155
+ }
156
+
157
+ // If we didn't receive the expected error, we still want to throw it.
158
+ throw e;
159
+ }
160
+ }
161
+
162
+ // Let's prepare a custom folder permissions list, where the folder contains the updated data.
163
+ const customFoldersList = await folderLevelPermissions.listAllFolders(original.type).then(folders => {
164
+ const foldersClone = (0, _structuredClone.default)(folders);
165
+ return foldersClone.map(folder => {
166
+ if (folder.id === id) {
167
+ Object.assign(folder, data);
168
+ }
169
+ return folder;
170
+ });
171
+ });
172
+ const stillHasAccess = await folderLevelPermissions.canAccessFolder({
173
+ folder: {
174
+ id,
175
+ type: original.type
176
+ },
177
+ rwd: "w",
178
+ foldersList: customFoldersList
179
+ });
180
+ if (!stillHasAccess) {
181
+ throw new _error.default(`Cannot continue because you would loose access to this folder.`, "CANNOT_LOOSE_FOLDER_ACCESS");
182
+ }
55
183
  await onFolderBeforeUpdate.publish({
56
184
  original,
57
185
  input: {
@@ -71,12 +199,18 @@ const createFolderCrudMethods = ({
71
199
  },
72
200
  folder
73
201
  });
202
+ folderLevelPermissions.invalidateCache();
203
+ await folderLevelPermissions.assignFolderPermissions(folder);
74
204
  return folder;
75
205
  },
76
206
  async delete(id) {
77
207
  const folder = await storageOperations.getFolder({
78
208
  id
79
209
  });
210
+ await folderLevelPermissions.ensureCanAccessFolder({
211
+ folder,
212
+ rwd: "d"
213
+ });
80
214
  await onFolderBeforeDelete.publish({
81
215
  folder
82
216
  });
@@ -88,23 +222,71 @@ const createFolderCrudMethods = ({
88
222
  });
89
223
  return true;
90
224
  },
91
- async getFolderWithAncestors(id) {
92
- const {
93
- type
94
- } = await storageOperations.getFolder({
95
- id
96
- });
97
- const [folders] = await storageOperations.listFolders({
225
+ async getAncestors(folder) {
226
+ const [folders] = await this.listAll({
98
227
  where: {
99
- type
100
- },
101
- limit: 10000
228
+ type: folder.type
229
+ }
102
230
  });
103
231
  return (0, _getFolderAndItsAncestors.getFolderAndItsAncestors)({
104
- id,
232
+ folder,
105
233
  folders
106
234
  });
235
+ },
236
+ /**
237
+ * @deprecated use `getAncestors` instead
238
+ */
239
+ async getFolderWithAncestors(id) {
240
+ const folder = await this.get(id);
241
+ return this.getAncestors(folder);
242
+ },
243
+ async listFolderLevelPermissionsTargets() {
244
+ const adminUsers = await listAdminUsers();
245
+ const teams = await listTeams();
246
+ const teamTargets = teams.map(team => ({
247
+ id: team.id,
248
+ type: "team",
249
+ target: `team:${team.id}`,
250
+ name: team.name || "",
251
+ meta: {}
252
+ }));
253
+ const adminUserTargets = adminUsers.map(user => {
254
+ var _user$avatar;
255
+ let name = user.displayName;
256
+ if (!name) {
257
+ // For backwards compatibility, we also want to try concatenating first and last name.
258
+ name = [user.firstName, user.lastName].filter(Boolean).join(" ");
259
+ }
260
+
261
+ // We're doing the validation because, with non-Cognito IdPs (Okta, Auth0), the email
262
+ // field might actually contain a non-email value: `id:${IdP_Identity_ID}`. In that case,
263
+ // let's not assign anything to the `email` field.
264
+ let email = user.email;
265
+ try {
266
+ _validation.validation.validateSync(email, "email");
267
+ } catch {
268
+ email = null;
269
+ }
270
+ const image = ((_user$avatar = user.avatar) === null || _user$avatar === void 0 ? void 0 : _user$avatar.src) || null;
271
+ return {
272
+ id: user.id,
273
+ type: "admin",
274
+ target: `admin:${user.id}`,
275
+ name,
276
+ meta: {
277
+ email,
278
+ image
279
+ }
280
+ };
281
+ });
282
+ const results = [...teamTargets, ...adminUserTargets];
283
+ const meta = {
284
+ totalCount: results.length
285
+ };
286
+ return [results, meta];
107
287
  }
108
288
  };
109
289
  };
110
- exports.createFolderCrudMethods = createFolderCrudMethods;
290
+ exports.createFolderCrudMethods = createFolderCrudMethods;
291
+
292
+ //# sourceMappingURL=folder.crud.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_pubsub","require","_getFolderAndItsAncestors","createFolderCrudMethods","storageOperations","onFolderBeforeCreate","createTopic","onFolderAfterCreate","onFolderBeforeUpdate","onFolderAfterUpdate","onFolderBeforeDelete","onFolderAfterDelete","get","id","getFolder","list","params","listFolders","create","data","publish","input","folder","createFolder","update","original","updateFolder","delete","deleteFolder","getFolderWithAncestors","type","folders","where","limit","getFolderAndItsAncestors","exports"],"sources":["folder.crud.ts"],"sourcesContent":["import { createTopic } from \"@webiny/pubsub\";\n\nimport { CreateAcoParams } from \"~/types\";\nimport {\n AcoFolderCrud,\n OnFolderAfterCreateTopicParams,\n OnFolderAfterDeleteTopicParams,\n OnFolderAfterUpdateTopicParams,\n OnFolderBeforeCreateTopicParams,\n OnFolderBeforeDeleteTopicParams,\n OnFolderBeforeUpdateTopicParams\n} from \"./folder.types\";\n\nimport { getFolderAndItsAncestors } from \"~/utils/getFolderAndItsAncestors\";\n\nexport const createFolderCrudMethods = ({ storageOperations }: CreateAcoParams): AcoFolderCrud => {\n // create\n const onFolderBeforeCreate = createTopic<OnFolderBeforeCreateTopicParams>(\n \"aco.onFolderBeforeCreate\"\n );\n const onFolderAfterCreate =\n createTopic<OnFolderAfterCreateTopicParams>(\"aco.onFolderAfterCreate\");\n // update\n const onFolderBeforeUpdate = createTopic<OnFolderBeforeUpdateTopicParams>(\n \"aco.onFolderBeforeUpdate\"\n );\n const onFolderAfterUpdate =\n createTopic<OnFolderAfterUpdateTopicParams>(\"aco.onFolderAfterUpdate\");\n // delete\n const onFolderBeforeDelete = createTopic<OnFolderBeforeDeleteTopicParams>(\n \"aco.onFolderBeforeDelete\"\n );\n const onFolderAfterDelete =\n createTopic<OnFolderAfterDeleteTopicParams>(\"aco.onFolderAfterDelete\");\n\n return {\n /**\n * Lifecycle events\n */\n onFolderBeforeCreate,\n onFolderAfterCreate,\n onFolderBeforeUpdate,\n onFolderAfterUpdate,\n onFolderBeforeDelete,\n onFolderAfterDelete,\n async get(id) {\n return storageOperations.getFolder({ id });\n },\n async list(params) {\n return storageOperations.listFolders(params);\n },\n async create(data) {\n await onFolderBeforeCreate.publish({ input: data });\n const folder = await storageOperations.createFolder({ data });\n await onFolderAfterCreate.publish({ folder });\n return folder;\n },\n async update(id, data) {\n const original = await storageOperations.getFolder({ id });\n await onFolderBeforeUpdate.publish({ original, input: { id, data } });\n const folder = await storageOperations.updateFolder({ id, data });\n await onFolderAfterUpdate.publish({ original, input: { id, data }, folder });\n return folder;\n },\n async delete(id: string) {\n const folder = await storageOperations.getFolder({ id });\n await onFolderBeforeDelete.publish({ folder });\n await storageOperations.deleteFolder({ id });\n await onFolderAfterDelete.publish({ folder });\n return true;\n },\n async getFolderWithAncestors(id: string) {\n const { type } = await storageOperations.getFolder({ id });\n const [folders] = await storageOperations.listFolders({\n where: {\n type\n },\n limit: 10000\n });\n return getFolderAndItsAncestors({ id, folders });\n }\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["_pubsub","require","_validation","_getFolderAndItsAncestors","_NotAuthorizedError","_interopRequireDefault","_structuredClone","_error","FIXED_FOLDER_LISTING_LIMIT","createFolderCrudMethods","storageOperations","folderLevelPermissions","listAdminUsers","listTeams","onFolderBeforeCreate","createTopic","onFolderAfterCreate","onFolderBeforeUpdate","onFolderAfterUpdate","onFolderBeforeDelete","onFolderAfterDelete","get","id","folder","getFolder","ensureCanAccessFolder","rwd","assignFolderPermissions","list","params","filteredFolders","listAllFoldersWithPermissions","where","type","then","parentId","filter","totalCount","length","hasMoreItems","cursor","after","afterListItemIndex","findIndex","splice","limit","_filteredFolders","listAll","_objectSpread2","default","create","data","canCreateFolder","parentFolder","canAccessFolder","canCreateFolderInRoot","NotAuthorizedError","publish","input","createFolder","invalidateCache","update","original","canUpdateFolder","Array","isArray","permissions","forEach","permission","targetIsValid","target","startsWith","Error","inheritedFrom","e","WError","customFoldersList","listAllFolders","folders","foldersClone","structuredClone","map","Object","assign","stillHasAccess","foldersList","updateFolder","delete","deleteFolder","getAncestors","getFolderAndItsAncestors","getFolderWithAncestors","listFolderLevelPermissionsTargets","adminUsers","teams","teamTargets","team","name","meta","adminUserTargets","user","_user$avatar","displayName","firstName","lastName","Boolean","join","email","validation","validateSync","image","avatar","src","results","exports"],"sources":["folder.crud.ts"],"sourcesContent":["import { createTopic } from \"@webiny/pubsub\";\nimport { validation } from \"@webiny/validation\";\nimport { CreateAcoParams, Folder } from \"~/types\";\nimport {\n AcoFolderCrud,\n OnFolderAfterCreateTopicParams,\n OnFolderAfterDeleteTopicParams,\n OnFolderAfterUpdateTopicParams,\n OnFolderBeforeCreateTopicParams,\n OnFolderBeforeDeleteTopicParams,\n OnFolderBeforeUpdateTopicParams\n} from \"./folder.types\";\n\nimport { getFolderAndItsAncestors } from \"~/utils/getFolderAndItsAncestors\";\nimport NotAuthorizedError from \"@webiny/api-security/NotAuthorizedError\";\nimport { AdminUser } from \"@webiny/api-admin-users/types\";\nimport { Team } from \"@webiny/api-security/types\";\nimport structuredClone from \"@ungap/structured-clone\";\nimport WError from \"@webiny/error\";\n\nconst FIXED_FOLDER_LISTING_LIMIT = 10_000;\n\ninterface CreateFolderCrudMethodsParams extends CreateAcoParams {\n listAdminUsers: () => Promise<AdminUser[]>;\n listTeams: () => Promise<Team[]>;\n}\n\nexport const createFolderCrudMethods = ({\n storageOperations,\n folderLevelPermissions,\n listAdminUsers,\n listTeams\n}: CreateFolderCrudMethodsParams): AcoFolderCrud => {\n // create\n const onFolderBeforeCreate = createTopic<OnFolderBeforeCreateTopicParams>(\n \"aco.onFolderBeforeCreate\"\n );\n const onFolderAfterCreate =\n createTopic<OnFolderAfterCreateTopicParams>(\"aco.onFolderAfterCreate\");\n // update\n const onFolderBeforeUpdate = createTopic<OnFolderBeforeUpdateTopicParams>(\n \"aco.onFolderBeforeUpdate\"\n );\n const onFolderAfterUpdate =\n createTopic<OnFolderAfterUpdateTopicParams>(\"aco.onFolderAfterUpdate\");\n // delete\n const onFolderBeforeDelete = createTopic<OnFolderBeforeDeleteTopicParams>(\n \"aco.onFolderBeforeDelete\"\n );\n const onFolderAfterDelete =\n createTopic<OnFolderAfterDeleteTopicParams>(\"aco.onFolderAfterDelete\");\n\n return {\n /**\n * Lifecycle events\n */\n onFolderBeforeCreate,\n onFolderAfterCreate,\n onFolderBeforeUpdate,\n onFolderAfterUpdate,\n onFolderBeforeDelete,\n onFolderAfterDelete,\n\n async get(id) {\n const folder = await storageOperations.getFolder({ id });\n\n await folderLevelPermissions.ensureCanAccessFolder({\n folder,\n rwd: \"r\"\n });\n\n await folderLevelPermissions.assignFolderPermissions(folder);\n return folder;\n },\n async list(params) {\n // No matter what was the limit set in the params, initially, we always retrieve\n // all folders. The limit is then applied with the filtered folders list below.\n const filteredFolders = await folderLevelPermissions\n .listAllFoldersWithPermissions(params.where.type)\n .then(filteredFolders => {\n // If `parentId` was included in the `where` clause, we need to filter the folders.\n // TODO: we might want to incorporate this into the `listAllFoldersWithPermissions` method.\n if (params.where.parentId) {\n // Filter by parent ID.\n return filteredFolders.filter(\n folder => folder.parentId === params.where.parentId\n );\n }\n return filteredFolders;\n });\n\n const totalCount = filteredFolders.length;\n let hasMoreItems = false;\n let cursor: string | null = null;\n\n // Apply cursor/limit params.\n if (params.after) {\n const afterListItemIndex = filteredFolders.findIndex(\n folder => folder.id === params.after\n );\n if (afterListItemIndex >= 0) {\n // Remove all items below the \"after\" item.\n filteredFolders.splice(0, afterListItemIndex + 1);\n }\n }\n\n hasMoreItems = !!params.limit && filteredFolders.length > params.limit;\n\n if (hasMoreItems) {\n cursor = filteredFolders[params.limit! - 1]?.id || null;\n filteredFolders.splice(params.limit!);\n }\n\n return [filteredFolders, { totalCount, hasMoreItems, cursor }];\n },\n\n async listAll(params) {\n return this.list({ ...params, limit: FIXED_FOLDER_LISTING_LIMIT });\n },\n\n async create(data) {\n let canCreateFolder = false;\n if (data.parentId) {\n const parentFolder = await storageOperations.getFolder({ id: data.parentId });\n canCreateFolder = await folderLevelPermissions.canAccessFolder({\n folder: parentFolder,\n rwd: \"w\"\n });\n } else {\n canCreateFolder = await folderLevelPermissions.canCreateFolderInRoot();\n }\n\n if (!canCreateFolder) {\n throw new NotAuthorizedError();\n }\n\n await onFolderBeforeCreate.publish({ input: data });\n const folder = await storageOperations.createFolder({ data });\n\n folderLevelPermissions.invalidateCache();\n await folderLevelPermissions.assignFolderPermissions(folder);\n\n await onFolderAfterCreate.publish({ folder });\n\n return folder;\n },\n\n async update(id, data) {\n const original = await storageOperations.getFolder({ id });\n\n const canUpdateFolder = await folderLevelPermissions.canAccessFolder({\n folder: original,\n rwd: \"w\"\n });\n\n if (!canUpdateFolder) {\n throw new NotAuthorizedError();\n }\n\n // Validate data.\n if (Array.isArray(data.permissions)) {\n data.permissions.forEach(permission => {\n const targetIsValid =\n permission.target.startsWith(\"admin:\") ||\n permission.target.startsWith(\"team:\");\n if (!targetIsValid) {\n throw new Error(`Permission target \"${permission.target}\" is not valid.`);\n }\n\n if (permission.inheritedFrom) {\n throw new Error(`Permission \"inheritedFrom\" cannot be set manually.`);\n }\n });\n }\n\n // Parent change is not allowed if the user doesn't have access to the new parent.\n if (data.parentId && data.parentId !== original.parentId) {\n try {\n // Getting the parent folder will throw an error if the user doesn't have access.\n await this.get(data.parentId);\n } catch (e) {\n if (e instanceof NotAuthorizedError) {\n throw new WError(\n `Cannot move folder to a new parent because you don't have access to the new parent.`,\n \"CANNOT_MOVE_FOLDER_TO_NEW_PARENT\"\n );\n }\n\n // If we didn't receive the expected error, we still want to throw it.\n throw e;\n }\n }\n\n // Let's prepare a custom folder permissions list, where the folder contains the updated data.\n const customFoldersList = await folderLevelPermissions\n .listAllFolders(original.type)\n .then(folders => {\n const foldersClone = structuredClone<Folder[]>(folders);\n return foldersClone.map(folder => {\n if (folder.id === id) {\n Object.assign(folder, data);\n }\n return folder;\n });\n });\n\n const stillHasAccess = await folderLevelPermissions.canAccessFolder({\n folder: { id, type: original.type },\n rwd: \"w\",\n foldersList: customFoldersList\n });\n\n if (!stillHasAccess) {\n throw new WError(\n `Cannot continue because you would loose access to this folder.`,\n \"CANNOT_LOOSE_FOLDER_ACCESS\"\n );\n }\n\n await onFolderBeforeUpdate.publish({ original, input: { id, data } });\n const folder = await storageOperations.updateFolder({ id, data });\n await onFolderAfterUpdate.publish({ original, input: { id, data }, folder });\n\n folderLevelPermissions.invalidateCache();\n await folderLevelPermissions.assignFolderPermissions(folder);\n return folder;\n },\n\n async delete(id: string) {\n const folder = await storageOperations.getFolder({ id });\n\n await folderLevelPermissions.ensureCanAccessFolder({\n folder,\n rwd: \"d\"\n });\n\n await onFolderBeforeDelete.publish({ folder });\n await storageOperations.deleteFolder({ id });\n await onFolderAfterDelete.publish({ folder });\n return true;\n },\n\n async getAncestors(folder: Folder) {\n const [folders] = await this.listAll({ where: { type: folder.type } });\n return getFolderAndItsAncestors({ folder, folders });\n },\n\n /**\n * @deprecated use `getAncestors` instead\n */\n async getFolderWithAncestors(id: string) {\n const folder = await this.get(id);\n return this.getAncestors(folder);\n },\n\n async listFolderLevelPermissionsTargets() {\n const adminUsers = await listAdminUsers();\n const teams = await listTeams();\n\n const teamTargets = teams.map(team => ({\n id: team.id,\n type: \"team\",\n target: `team:${team.id}`,\n name: team.name || \"\",\n meta: {}\n }));\n\n const adminUserTargets = adminUsers.map(user => {\n let name = user.displayName;\n if (!name) {\n // For backwards compatibility, we also want to try concatenating first and last name.\n name = [user.firstName, user.lastName].filter(Boolean).join(\" \");\n }\n\n // We're doing the validation because, with non-Cognito IdPs (Okta, Auth0), the email\n // field might actually contain a non-email value: `id:${IdP_Identity_ID}`. In that case,\n // let's not assign anything to the `email` field.\n let email: string | null = user.email;\n try {\n validation.validateSync(email, \"email\");\n } catch {\n email = null;\n }\n\n const image = user.avatar?.src || null;\n\n return {\n id: user.id,\n type: \"admin\",\n target: `admin:${user.id}`,\n name,\n meta: {\n email,\n image\n }\n };\n });\n\n const results = [...teamTargets, ...adminUserTargets];\n const meta = { totalCount: results.length };\n\n return [results, meta];\n }\n };\n};\n"],"mappings":"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"}
@@ -6,14 +6,37 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.folderSchema = void 0;
7
7
  var _responses = require("@webiny/handler-graphql/responses");
8
8
  var _GraphQLSchemaPlugin = require("@webiny/handler-graphql/plugins/GraphQLSchemaPlugin");
9
- var _checkPermissions = require("../utils/checkPermissions");
9
+ var _ensureAuthentication = require("../utils/ensureAuthentication");
10
10
  var _resolve = require("../utils/resolve");
11
11
  const folderSchema = new _GraphQLSchemaPlugin.GraphQLSchemaPlugin({
12
12
  typeDefs: /* GraphQL */`
13
+ type FolderPermission {
14
+ target: String!
15
+ level: String!
16
+ inheritedFrom: ID
17
+ }
18
+
19
+ input FolderPermissionInput {
20
+ target: String!
21
+ level: String!
22
+ inheritedFrom: ID
23
+ }
24
+
13
25
  type Folder {
14
26
  id: ID!
15
27
  title: String!
16
28
  slug: String!
29
+ permissions: [FolderPermission]
30
+
31
+ # Tells us if the current user can manage folder structure.
32
+ canManageStructure: Boolean
33
+
34
+ # Tells us if the current user can manage folder permissions.
35
+ canManagePermissions: Boolean
36
+
37
+ # Tells us if the folder contains non-inherited permissions.
38
+ hasNonInheritedPermissions: Boolean
39
+
17
40
  type: String!
18
41
  parentId: ID
19
42
  savedOn: DateTime
@@ -24,6 +47,7 @@ const folderSchema = new _GraphQLSchemaPlugin.GraphQLSchemaPlugin({
24
47
  input FolderCreateInput {
25
48
  title: String!
26
49
  slug: String!
50
+ permissions: [FolderPermissionInput]
27
51
  type: String!
28
52
  parentId: ID
29
53
  }
@@ -31,6 +55,7 @@ const folderSchema = new _GraphQLSchemaPlugin.GraphQLSchemaPlugin({
31
55
  input FolderUpdateInput {
32
56
  title: String
33
57
  slug: String
58
+ permissions: [FolderPermissionInput]
34
59
  parentId: ID
35
60
  }
36
61
 
@@ -48,6 +73,25 @@ const folderSchema = new _GraphQLSchemaPlugin.GraphQLSchemaPlugin({
48
73
  type FoldersListResponse {
49
74
  data: [Folder]
50
75
  error: AcoError
76
+ meta: AcoMeta
77
+ }
78
+
79
+ type FolderLevelPermissionsTarget {
80
+ id: ID!
81
+ type: String!
82
+ target: ID!
83
+ name: String!
84
+ meta: JSON
85
+ }
86
+
87
+ type FolderLevelPermissionsTargetsListMeta {
88
+ totalCount: Int!
89
+ }
90
+
91
+ type FolderLevelPermissionsTargetsListResponse {
92
+ data: [FolderLevelPermissionsTarget]
93
+ meta: FolderLevelPermissionsTargetsListMeta
94
+ error: AcoError
51
95
  }
52
96
 
53
97
  extend type AcoQuery {
@@ -58,6 +102,8 @@ const folderSchema = new _GraphQLSchemaPlugin.GraphQLSchemaPlugin({
58
102
  after: String
59
103
  sort: AcoSort
60
104
  ): FoldersListResponse
105
+
106
+ listFolderLevelPermissionsTargets: FolderLevelPermissionsTargetsListResponse
61
107
  }
62
108
 
63
109
  extend type AcoMutation {
@@ -67,23 +113,43 @@ const folderSchema = new _GraphQLSchemaPlugin.GraphQLSchemaPlugin({
67
113
  }
68
114
  `,
69
115
  resolvers: {
116
+ Folder: {
117
+ hasNonInheritedPermissions: (folder, _, context) => {
118
+ return context.aco.folderLevelPermissions.permissionsIncludeNonInheritedPermissions(folder.permissions);
119
+ },
120
+ canManageStructure: (folder, _, context) => {
121
+ return context.aco.folderLevelPermissions.canManageFolderStructure(folder);
122
+ },
123
+ canManagePermissions: (folder, _, context) => {
124
+ return context.aco.folderLevelPermissions.canManageFolderPermissions(folder);
125
+ }
126
+ },
70
127
  AcoQuery: {
71
128
  getFolder: async (_, {
72
129
  id
73
130
  }, context) => {
74
131
  return (0, _resolve.resolve)(() => {
75
- (0, _checkPermissions.checkPermissions)(context);
132
+ (0, _ensureAuthentication.ensureAuthentication)(context);
76
133
  return context.aco.folder.get(id);
77
134
  });
78
135
  },
79
136
  listFolders: async (_, args, context) => {
80
137
  try {
81
- (0, _checkPermissions.checkPermissions)(context);
138
+ (0, _ensureAuthentication.ensureAuthentication)(context);
82
139
  const [entries, meta] = await context.aco.folder.list(args);
83
140
  return new _responses.ListResponse(entries, meta);
84
141
  } catch (e) {
85
142
  return new _responses.ErrorResponse(e);
86
143
  }
144
+ },
145
+ listFolderLevelPermissionsTargets: async (_, args, context) => {
146
+ try {
147
+ (0, _ensureAuthentication.ensureAuthentication)(context);
148
+ const [entries, meta] = await context.aco.folder.listFolderLevelPermissionsTargets();
149
+ return new _responses.ListResponse(entries, meta);
150
+ } catch (e) {
151
+ return new _responses.ErrorResponse(e);
152
+ }
87
153
  }
88
154
  },
89
155
  AcoMutation: {
@@ -91,7 +157,7 @@ const folderSchema = new _GraphQLSchemaPlugin.GraphQLSchemaPlugin({
91
157
  data
92
158
  }, context) => {
93
159
  return (0, _resolve.resolve)(() => {
94
- (0, _checkPermissions.checkPermissions)(context);
160
+ (0, _ensureAuthentication.ensureAuthentication)(context);
95
161
  return context.aco.folder.create(data);
96
162
  });
97
163
  },
@@ -100,7 +166,7 @@ const folderSchema = new _GraphQLSchemaPlugin.GraphQLSchemaPlugin({
100
166
  data
101
167
  }, context) => {
102
168
  return (0, _resolve.resolve)(() => {
103
- (0, _checkPermissions.checkPermissions)(context);
169
+ (0, _ensureAuthentication.ensureAuthentication)(context);
104
170
  return context.aco.folder.update(id, data);
105
171
  });
106
172
  },
@@ -108,11 +174,13 @@ const folderSchema = new _GraphQLSchemaPlugin.GraphQLSchemaPlugin({
108
174
  id
109
175
  }, context) => {
110
176
  return (0, _resolve.resolve)(() => {
111
- (0, _checkPermissions.checkPermissions)(context);
177
+ (0, _ensureAuthentication.ensureAuthentication)(context);
112
178
  return context.aco.folder.delete(id);
113
179
  });
114
180
  }
115
181
  }
116
182
  }
117
183
  });
118
- exports.folderSchema = folderSchema;
184
+ exports.folderSchema = folderSchema;
185
+
186
+ //# sourceMappingURL=folder.gql.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_responses","require","_GraphQLSchemaPlugin","_checkPermissions","_resolve","folderSchema","GraphQLSchemaPlugin","typeDefs","resolvers","AcoQuery","getFolder","_","id","context","resolve","checkPermissions","aco","folder","get","listFolders","args","entries","meta","list","ListResponse","e","ErrorResponse","AcoMutation","createFolder","data","create","updateFolder","update","deleteFolder","delete","exports"],"sources":["folder.gql.ts"],"sourcesContent":["import { ErrorResponse, ListResponse } from \"@webiny/handler-graphql/responses\";\nimport { GraphQLSchemaPlugin } from \"@webiny/handler-graphql/plugins/GraphQLSchemaPlugin\";\n\nimport { checkPermissions } from \"~/utils/checkPermissions\";\nimport { resolve } from \"~/utils/resolve\";\n\nimport { AcoContext } from \"~/types\";\n\nexport const folderSchema = new GraphQLSchemaPlugin<AcoContext>({\n typeDefs: /* GraphQL */ `\n type Folder {\n id: ID!\n title: String!\n slug: String!\n type: String!\n parentId: ID\n savedOn: DateTime\n createdOn: DateTime\n createdBy: AcoUser\n }\n\n input FolderCreateInput {\n title: String!\n slug: String!\n type: String!\n parentId: ID\n }\n\n input FolderUpdateInput {\n title: String\n slug: String\n parentId: ID\n }\n\n input FoldersListWhereInput {\n type: String!\n parentId: String\n createdBy: ID\n }\n\n type FolderResponse {\n data: Folder\n error: AcoError\n }\n\n type FoldersListResponse {\n data: [Folder]\n error: AcoError\n }\n\n extend type AcoQuery {\n getFolder(id: ID!): FolderResponse\n listFolders(\n where: FoldersListWhereInput!\n limit: Int\n after: String\n sort: AcoSort\n ): FoldersListResponse\n }\n\n extend type AcoMutation {\n createFolder(data: FolderCreateInput!): FolderResponse\n updateFolder(id: ID!, data: FolderUpdateInput!): FolderResponse\n deleteFolder(id: ID!): AcoBooleanResponse\n }\n `,\n resolvers: {\n AcoQuery: {\n getFolder: async (_, { id }, context) => {\n return resolve(() => {\n checkPermissions(context);\n return context.aco.folder.get(id);\n });\n },\n listFolders: async (_, args: any, context) => {\n try {\n checkPermissions(context);\n const [entries, meta] = await context.aco.folder.list(args);\n return new ListResponse(entries, meta);\n } catch (e) {\n return new ErrorResponse(e);\n }\n }\n },\n AcoMutation: {\n createFolder: async (_, { data }, context) => {\n return resolve(() => {\n checkPermissions(context);\n return context.aco.folder.create(data);\n });\n },\n updateFolder: async (_, { id, data }, context) => {\n return resolve(() => {\n checkPermissions(context);\n return context.aco.folder.update(id, data);\n });\n },\n deleteFolder: async (_, { id }, context) => {\n return resolve(() => {\n checkPermissions(context);\n return context.aco.folder.delete(id);\n });\n }\n }\n }\n});\n"],"mappings":";;;;;;AAAA,IAAAA,UAAA,GAAAC,OAAA;AACA,IAAAC,oBAAA,GAAAD,OAAA;AAEA,IAAAE,iBAAA,GAAAF,OAAA;AACA,IAAAG,QAAA,GAAAH,OAAA;AAIO,MAAMI,YAAY,GAAG,IAAIC,wCAAmB,CAAa;EAC5DC,QAAQ,EAAE,aAAe;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;EACDC,SAAS,EAAE;IACPC,QAAQ,EAAE;MACNC,SAAS,EAAE,MAAAA,CAAOC,CAAC,EAAE;QAAEC;MAAG,CAAC,EAAEC,OAAO,KAAK;QACrC,OAAO,IAAAC,gBAAO,EAAC,MAAM;UACjB,IAAAC,kCAAgB,EAACF,OAAO,CAAC;UACzB,OAAOA,OAAO,CAACG,GAAG,CAACC,MAAM,CAACC,GAAG,CAACN,EAAE,CAAC;QACrC,CAAC,CAAC;MACN,CAAC;MACDO,WAAW,EAAE,MAAAA,CAAOR,CAAC,EAAES,IAAS,EAAEP,OAAO,KAAK;QAC1C,IAAI;UACA,IAAAE,kCAAgB,EAACF,OAAO,CAAC;UACzB,MAAM,CAACQ,OAAO,EAAEC,IAAI,CAAC,GAAG,MAAMT,OAAO,CAACG,GAAG,CAACC,MAAM,CAACM,IAAI,CAACH,IAAI,CAAC;UAC3D,OAAO,IAAII,uBAAY,CAACH,OAAO,EAAEC,IAAI,CAAC;QAC1C,CAAC,CAAC,OAAOG,CAAC,EAAE;UACR,OAAO,IAAIC,wBAAa,CAACD,CAAC,CAAC;QAC/B;MACJ;IACJ,CAAC;IACDE,WAAW,EAAE;MACTC,YAAY,EAAE,MAAAA,CAAOjB,CAAC,EAAE;QAAEkB;MAAK,CAAC,EAAEhB,OAAO,KAAK;QAC1C,OAAO,IAAAC,gBAAO,EAAC,MAAM;UACjB,IAAAC,kCAAgB,EAACF,OAAO,CAAC;UACzB,OAAOA,OAAO,CAACG,GAAG,CAACC,MAAM,CAACa,MAAM,CAACD,IAAI,CAAC;QAC1C,CAAC,CAAC;MACN,CAAC;MACDE,YAAY,EAAE,MAAAA,CAAOpB,CAAC,EAAE;QAAEC,EAAE;QAAEiB;MAAK,CAAC,EAAEhB,OAAO,KAAK;QAC9C,OAAO,IAAAC,gBAAO,EAAC,MAAM;UACjB,IAAAC,kCAAgB,EAACF,OAAO,CAAC;UACzB,OAAOA,OAAO,CAACG,GAAG,CAACC,MAAM,CAACe,MAAM,CAACpB,EAAE,EAAEiB,IAAI,CAAC;QAC9C,CAAC,CAAC;MACN,CAAC;MACDI,YAAY,EAAE,MAAAA,CAAOtB,CAAC,EAAE;QAAEC;MAAG,CAAC,EAAEC,OAAO,KAAK;QACxC,OAAO,IAAAC,gBAAO,EAAC,MAAM;UACjB,IAAAC,kCAAgB,EAACF,OAAO,CAAC;UACzB,OAAOA,OAAO,CAACG,GAAG,CAACC,MAAM,CAACiB,MAAM,CAACtB,EAAE,CAAC;QACxC,CAAC,CAAC;MACN;IACJ;EACJ;AACJ,CAAC,CAAC;AAACuB,OAAA,CAAA9B,YAAA,GAAAA,YAAA"}
1
+ {"version":3,"names":["_responses","require","_GraphQLSchemaPlugin","_ensureAuthentication","_resolve","folderSchema","GraphQLSchemaPlugin","typeDefs","resolvers","Folder","hasNonInheritedPermissions","folder","_","context","aco","folderLevelPermissions","permissionsIncludeNonInheritedPermissions","permissions","canManageStructure","canManageFolderStructure","canManagePermissions","canManageFolderPermissions","AcoQuery","getFolder","id","resolve","ensureAuthentication","get","listFolders","args","entries","meta","list","ListResponse","e","ErrorResponse","listFolderLevelPermissionsTargets","AcoMutation","createFolder","data","create","updateFolder","update","deleteFolder","delete","exports"],"sources":["folder.gql.ts"],"sourcesContent":["import { ErrorResponse, ListResponse } from \"@webiny/handler-graphql/responses\";\nimport { GraphQLSchemaPlugin } from \"@webiny/handler-graphql/plugins/GraphQLSchemaPlugin\";\n\nimport { ensureAuthentication } from \"~/utils/ensureAuthentication\";\nimport { resolve } from \"~/utils/resolve\";\n\nimport { AcoContext, Folder } from \"~/types\";\n\nexport const folderSchema = new GraphQLSchemaPlugin<AcoContext>({\n typeDefs: /* GraphQL */ `\n type FolderPermission {\n target: String!\n level: String!\n inheritedFrom: ID\n }\n\n input FolderPermissionInput {\n target: String!\n level: String!\n inheritedFrom: ID\n }\n\n type Folder {\n id: ID!\n title: String!\n slug: String!\n permissions: [FolderPermission]\n\n # Tells us if the current user can manage folder structure.\n canManageStructure: Boolean\n\n # Tells us if the current user can manage folder permissions.\n canManagePermissions: Boolean\n\n # Tells us if the folder contains non-inherited permissions.\n hasNonInheritedPermissions: Boolean\n\n type: String!\n parentId: ID\n savedOn: DateTime\n createdOn: DateTime\n createdBy: AcoUser\n }\n\n input FolderCreateInput {\n title: String!\n slug: String!\n permissions: [FolderPermissionInput]\n type: String!\n parentId: ID\n }\n\n input FolderUpdateInput {\n title: String\n slug: String\n permissions: [FolderPermissionInput]\n parentId: ID\n }\n\n input FoldersListWhereInput {\n type: String!\n parentId: String\n createdBy: ID\n }\n\n type FolderResponse {\n data: Folder\n error: AcoError\n }\n\n type FoldersListResponse {\n data: [Folder]\n error: AcoError\n meta: AcoMeta\n }\n\n type FolderLevelPermissionsTarget {\n id: ID!\n type: String!\n target: ID!\n name: String!\n meta: JSON\n }\n\n type FolderLevelPermissionsTargetsListMeta {\n totalCount: Int!\n }\n\n type FolderLevelPermissionsTargetsListResponse {\n data: [FolderLevelPermissionsTarget]\n meta: FolderLevelPermissionsTargetsListMeta\n error: AcoError\n }\n\n extend type AcoQuery {\n getFolder(id: ID!): FolderResponse\n listFolders(\n where: FoldersListWhereInput!\n limit: Int\n after: String\n sort: AcoSort\n ): FoldersListResponse\n\n listFolderLevelPermissionsTargets: FolderLevelPermissionsTargetsListResponse\n }\n\n extend type AcoMutation {\n createFolder(data: FolderCreateInput!): FolderResponse\n updateFolder(id: ID!, data: FolderUpdateInput!): FolderResponse\n deleteFolder(id: ID!): AcoBooleanResponse\n }\n `,\n resolvers: {\n Folder: {\n hasNonInheritedPermissions: (folder: Folder, _, context) => {\n return context.aco.folderLevelPermissions.permissionsIncludeNonInheritedPermissions(\n folder.permissions\n );\n },\n canManageStructure: (folder, _, context) => {\n return context.aco.folderLevelPermissions.canManageFolderStructure(folder);\n },\n canManagePermissions: (folder, _, context) => {\n return context.aco.folderLevelPermissions.canManageFolderPermissions(folder);\n }\n },\n AcoQuery: {\n getFolder: async (_, { id }, context) => {\n return resolve(() => {\n ensureAuthentication(context);\n return context.aco.folder.get(id);\n });\n },\n listFolders: async (_, args: any, context) => {\n try {\n ensureAuthentication(context);\n const [entries, meta] = await context.aco.folder.list(args);\n return new ListResponse(entries, meta);\n } catch (e) {\n return new ErrorResponse(e);\n }\n },\n listFolderLevelPermissionsTargets: async (_, args: any, context) => {\n try {\n ensureAuthentication(context);\n const [entries, meta] =\n await context.aco.folder.listFolderLevelPermissionsTargets();\n return new ListResponse(entries, meta);\n } catch (e) {\n return new ErrorResponse(e);\n }\n }\n },\n AcoMutation: {\n createFolder: async (_, { data }, context) => {\n return resolve(() => {\n ensureAuthentication(context);\n return context.aco.folder.create(data);\n });\n },\n updateFolder: async (_, { id, data }, context) => {\n return resolve(() => {\n ensureAuthentication(context);\n return context.aco.folder.update(id, data);\n });\n },\n deleteFolder: async (_, { id }, context) => {\n return resolve(() => {\n ensureAuthentication(context);\n return context.aco.folder.delete(id);\n });\n }\n }\n }\n});\n"],"mappings":";;;;;;AAAA,IAAAA,UAAA,GAAAC,OAAA;AACA,IAAAC,oBAAA,GAAAD,OAAA;AAEA,IAAAE,qBAAA,GAAAF,OAAA;AACA,IAAAG,QAAA,GAAAH,OAAA;AAIO,MAAMI,YAAY,GAAG,IAAIC,wCAAmB,CAAa;EAC5DC,QAAQ,EAAE,aAAe;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;EACDC,SAAS,EAAE;IACPC,MAAM,EAAE;MACJC,0BAA0B,EAAEA,CAACC,MAAc,EAAEC,CAAC,EAAEC,OAAO,KAAK;QACxD,OAAOA,OAAO,CAACC,GAAG,CAACC,sBAAsB,CAACC,yCAAyC,CAC/EL,MAAM,CAACM,WACX,CAAC;MACL,CAAC;MACDC,kBAAkB,EAAEA,CAACP,MAAM,EAAEC,CAAC,EAAEC,OAAO,KAAK;QACxC,OAAOA,OAAO,CAACC,GAAG,CAACC,sBAAsB,CAACI,wBAAwB,CAACR,MAAM,CAAC;MAC9E,CAAC;MACDS,oBAAoB,EAAEA,CAACT,MAAM,EAAEC,CAAC,EAAEC,OAAO,KAAK;QAC1C,OAAOA,OAAO,CAACC,GAAG,CAACC,sBAAsB,CAACM,0BAA0B,CAACV,MAAM,CAAC;MAChF;IACJ,CAAC;IACDW,QAAQ,EAAE;MACNC,SAAS,EAAE,MAAAA,CAAOX,CAAC,EAAE;QAAEY;MAAG,CAAC,EAAEX,OAAO,KAAK;QACrC,OAAO,IAAAY,gBAAO,EAAC,MAAM;UACjB,IAAAC,0CAAoB,EAACb,OAAO,CAAC;UAC7B,OAAOA,OAAO,CAACC,GAAG,CAACH,MAAM,CAACgB,GAAG,CAACH,EAAE,CAAC;QACrC,CAAC,CAAC;MACN,CAAC;MACDI,WAAW,EAAE,MAAAA,CAAOhB,CAAC,EAAEiB,IAAS,EAAEhB,OAAO,KAAK;QAC1C,IAAI;UACA,IAAAa,0CAAoB,EAACb,OAAO,CAAC;UAC7B,MAAM,CAACiB,OAAO,EAAEC,IAAI,CAAC,GAAG,MAAMlB,OAAO,CAACC,GAAG,CAACH,MAAM,CAACqB,IAAI,CAACH,IAAI,CAAC;UAC3D,OAAO,IAAII,uBAAY,CAACH,OAAO,EAAEC,IAAI,CAAC;QAC1C,CAAC,CAAC,OAAOG,CAAC,EAAE;UACR,OAAO,IAAIC,wBAAa,CAACD,CAAC,CAAC;QAC/B;MACJ,CAAC;MACDE,iCAAiC,EAAE,MAAAA,CAAOxB,CAAC,EAAEiB,IAAS,EAAEhB,OAAO,KAAK;QAChE,IAAI;UACA,IAAAa,0CAAoB,EAACb,OAAO,CAAC;UAC7B,MAAM,CAACiB,OAAO,EAAEC,IAAI,CAAC,GACjB,MAAMlB,OAAO,CAACC,GAAG,CAACH,MAAM,CAACyB,iCAAiC,CAAC,CAAC;UAChE,OAAO,IAAIH,uBAAY,CAACH,OAAO,EAAEC,IAAI,CAAC;QAC1C,CAAC,CAAC,OAAOG,CAAC,EAAE;UACR,OAAO,IAAIC,wBAAa,CAACD,CAAC,CAAC;QAC/B;MACJ;IACJ,CAAC;IACDG,WAAW,EAAE;MACTC,YAAY,EAAE,MAAAA,CAAO1B,CAAC,EAAE;QAAE2B;MAAK,CAAC,EAAE1B,OAAO,KAAK;QAC1C,OAAO,IAAAY,gBAAO,EAAC,MAAM;UACjB,IAAAC,0CAAoB,EAACb,OAAO,CAAC;UAC7B,OAAOA,OAAO,CAACC,GAAG,CAACH,MAAM,CAAC6B,MAAM,CAACD,IAAI,CAAC;QAC1C,CAAC,CAAC;MACN,CAAC;MACDE,YAAY,EAAE,MAAAA,CAAO7B,CAAC,EAAE;QAAEY,EAAE;QAAEe;MAAK,CAAC,EAAE1B,OAAO,KAAK;QAC9C,OAAO,IAAAY,gBAAO,EAAC,MAAM;UACjB,IAAAC,0CAAoB,EAACb,OAAO,CAAC;UAC7B,OAAOA,OAAO,CAACC,GAAG,CAACH,MAAM,CAAC+B,MAAM,CAAClB,EAAE,EAAEe,IAAI,CAAC;QAC9C,CAAC,CAAC;MACN,CAAC;MACDI,YAAY,EAAE,MAAAA,CAAO/B,CAAC,EAAE;QAAEY;MAAG,CAAC,EAAEX,OAAO,KAAK;QACxC,OAAO,IAAAY,gBAAO,EAAC,MAAM;UACjB,IAAAC,0CAAoB,EAACb,OAAO,CAAC;UAC7B,OAAOA,OAAO,CAACC,GAAG,CAACH,MAAM,CAACiC,MAAM,CAACpB,EAAE,CAAC;QACxC,CAAC,CAAC;MACN;IACJ;EACJ;AACJ,CAAC,CAAC;AAACqB,OAAA,CAAAxC,YAAA,GAAAA,YAAA"}
@@ -41,6 +41,50 @@ const parentIdField = () => (0, _createModelField.createModelField)({
41
41
  label: "Parent Id",
42
42
  type: "text"
43
43
  });
44
+ const permissionsField = () => (0, _createModelField.createModelField)({
45
+ label: "Permissions",
46
+ fieldId: "permissions",
47
+ type: "object",
48
+ multipleValues: true,
49
+ listValidation: [],
50
+ settings: {
51
+ fields: [{
52
+ id: "target",
53
+ type: "text",
54
+ storageId: "text@target",
55
+ fieldId: "target",
56
+ label: "Target",
57
+ validation: [{
58
+ name: "required",
59
+ message: "Value is required."
60
+ }]
61
+ }, {
62
+ id: "level",
63
+ type: "text",
64
+ storageId: "text@level",
65
+ fieldId: "level",
66
+ label: "Level",
67
+ validation: [{
68
+ name: "required",
69
+ message: "Value is required."
70
+ }],
71
+ predefinedValues: {
72
+ enabled: true,
73
+ values: [{
74
+ label: "Viewer",
75
+ value: "viewer"
76
+ }, {
77
+ label: "Editor",
78
+ value: "editor"
79
+ }, {
80
+ label: "Owner",
81
+ value: "owner"
82
+ }]
83
+ }
84
+ }],
85
+ layout: [["target"], ["level"]]
86
+ }
87
+ });
44
88
  const FOLDER_MODEL_ID = "acoFolder";
45
89
  exports.FOLDER_MODEL_ID = FOLDER_MODEL_ID;
46
90
  const createFolderModelDefinition = () => {
@@ -48,10 +92,12 @@ const createFolderModelDefinition = () => {
48
92
  name: "ACO - Folder",
49
93
  modelId: FOLDER_MODEL_ID,
50
94
  titleFieldId: "title",
51
- layout: [["title"], ["slug"], ["type"], ["parentId"]],
52
- fields: [titleField(), slugField(), typeField(), parentIdField()],
95
+ layout: [["title"], ["slug"], ["type"], ["parentId"], ["permissions"]],
96
+ fields: [titleField(), slugField(), typeField(), parentIdField(), permissionsField()],
53
97
  description: "ACO - Folder content model",
54
98
  isPrivate: true
55
99
  };
56
100
  };
57
- exports.createFolderModelDefinition = createFolderModelDefinition;
101
+ exports.createFolderModelDefinition = createFolderModelDefinition;
102
+
103
+ //# sourceMappingURL=folder.model.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_createModelField","require","titleField","createModelField","label","type","validation","name","message","slugField","settings","preset","regex","flags","typeField","parentIdField","FOLDER_MODEL_ID","exports","createFolderModelDefinition","modelId","titleFieldId","layout","fields","description","isPrivate"],"sources":["folder.model.ts"],"sourcesContent":["import { createModelField } from \"~/utils/createModelField\";\nimport { CmsPrivateModelFull } from \"@webiny/api-headless-cms\";\n\nexport type FolderModelDefinition = Omit<CmsPrivateModelFull, \"noValidate\" | \"group\">;\n\nconst titleField = () =>\n createModelField({\n label: \"Title\",\n type: \"text\",\n validation: [\n {\n name: \"required\",\n message: \"Value is required.\"\n }\n ]\n });\n\nconst slugField = () =>\n createModelField({\n label: \"Slug\",\n type: \"text\",\n validation: [\n {\n name: \"required\",\n message: \"Value is required.\"\n },\n {\n name: \"pattern\",\n settings: {\n preset: \"custom\",\n regex: \"^[a-z0-9]+(-[a-z0-9]+)*$\",\n flags: \"g\"\n },\n message: \"Value must consist of only 'a-z', '0-9' and '-'.\"\n }\n ]\n });\n\nconst typeField = () =>\n createModelField({\n label: \"Type\",\n type: \"text\",\n validation: [\n {\n name: \"required\",\n message: \"Value is required.\"\n }\n ]\n });\n\nconst parentIdField = () =>\n createModelField({\n label: \"Parent Id\",\n type: \"text\"\n });\n\nexport const FOLDER_MODEL_ID = \"acoFolder\";\n\nexport const createFolderModelDefinition = (): FolderModelDefinition => {\n return {\n name: \"ACO - Folder\",\n modelId: FOLDER_MODEL_ID,\n titleFieldId: \"title\",\n layout: [[\"title\"], [\"slug\"], [\"type\"], [\"parentId\"]],\n fields: [titleField(), slugField(), typeField(), parentIdField()],\n description: \"ACO - Folder content model\",\n isPrivate: true\n };\n};\n"],"mappings":";;;;;;AAAA,IAAAA,iBAAA,GAAAC,OAAA;AAKA,MAAMC,UAAU,GAAGA,CAAA,KACf,IAAAC,kCAAgB,EAAC;EACbC,KAAK,EAAE,OAAO;EACdC,IAAI,EAAE,MAAM;EACZC,UAAU,EAAE,CACR;IACIC,IAAI,EAAE,UAAU;IAChBC,OAAO,EAAE;EACb,CAAC;AAET,CAAC,CAAC;AAEN,MAAMC,SAAS,GAAGA,CAAA,KACd,IAAAN,kCAAgB,EAAC;EACbC,KAAK,EAAE,MAAM;EACbC,IAAI,EAAE,MAAM;EACZC,UAAU,EAAE,CACR;IACIC,IAAI,EAAE,UAAU;IAChBC,OAAO,EAAE;EACb,CAAC,EACD;IACID,IAAI,EAAE,SAAS;IACfG,QAAQ,EAAE;MACNC,MAAM,EAAE,QAAQ;MAChBC,KAAK,EAAE,0BAA0B;MACjCC,KAAK,EAAE;IACX,CAAC;IACDL,OAAO,EAAE;EACb,CAAC;AAET,CAAC,CAAC;AAEN,MAAMM,SAAS,GAAGA,CAAA,KACd,IAAAX,kCAAgB,EAAC;EACbC,KAAK,EAAE,MAAM;EACbC,IAAI,EAAE,MAAM;EACZC,UAAU,EAAE,CACR;IACIC,IAAI,EAAE,UAAU;IAChBC,OAAO,EAAE;EACb,CAAC;AAET,CAAC,CAAC;AAEN,MAAMO,aAAa,GAAGA,CAAA,KAClB,IAAAZ,kCAAgB,EAAC;EACbC,KAAK,EAAE,WAAW;EAClBC,IAAI,EAAE;AACV,CAAC,CAAC;AAEC,MAAMW,eAAe,GAAG,WAAW;AAACC,OAAA,CAAAD,eAAA,GAAAA,eAAA;AAEpC,MAAME,2BAA2B,GAAGA,CAAA,KAA6B;EACpE,OAAO;IACHX,IAAI,EAAE,cAAc;IACpBY,OAAO,EAAEH,eAAe;IACxBI,YAAY,EAAE,OAAO;IACrBC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;IACrDC,MAAM,EAAE,CAACpB,UAAU,CAAC,CAAC,EAAEO,SAAS,CAAC,CAAC,EAAEK,SAAS,CAAC,CAAC,EAAEC,aAAa,CAAC,CAAC,CAAC;IACjEQ,WAAW,EAAE,4BAA4B;IACzCC,SAAS,EAAE;EACf,CAAC;AACL,CAAC;AAACP,OAAA,CAAAC,2BAAA,GAAAA,2BAAA"}
1
+ {"version":3,"names":["_createModelField","require","titleField","createModelField","label","type","validation","name","message","slugField","settings","preset","regex","flags","typeField","parentIdField","permissionsField","fieldId","multipleValues","listValidation","fields","id","storageId","predefinedValues","enabled","values","value","layout","FOLDER_MODEL_ID","exports","createFolderModelDefinition","modelId","titleFieldId","description","isPrivate"],"sources":["folder.model.ts"],"sourcesContent":["import { createModelField } from \"~/utils/createModelField\";\nimport { CmsPrivateModelFull } from \"@webiny/api-headless-cms\";\n\nexport type FolderModelDefinition = Omit<CmsPrivateModelFull, \"noValidate\" | \"group\">;\n\nconst titleField = () =>\n createModelField({\n label: \"Title\",\n type: \"text\",\n validation: [\n {\n name: \"required\",\n message: \"Value is required.\"\n }\n ]\n });\n\nconst slugField = () =>\n createModelField({\n label: \"Slug\",\n type: \"text\",\n validation: [\n {\n name: \"required\",\n message: \"Value is required.\"\n },\n {\n name: \"pattern\",\n settings: {\n preset: \"custom\",\n regex: \"^[a-z0-9]+(-[a-z0-9]+)*$\",\n flags: \"g\"\n },\n message: \"Value must consist of only 'a-z', '0-9' and '-'.\"\n }\n ]\n });\n\nconst typeField = () =>\n createModelField({\n label: \"Type\",\n type: \"text\",\n validation: [\n {\n name: \"required\",\n message: \"Value is required.\"\n }\n ]\n });\n\nconst parentIdField = () =>\n createModelField({\n label: \"Parent Id\",\n type: \"text\"\n });\n\nconst permissionsField = () =>\n createModelField({\n label: \"Permissions\",\n fieldId: \"permissions\",\n type: \"object\",\n multipleValues: true,\n listValidation: [],\n settings: {\n fields: [\n {\n id: \"target\",\n type: \"text\",\n storageId: \"text@target\",\n fieldId: \"target\",\n label: \"Target\",\n validation: [\n {\n name: \"required\",\n message: \"Value is required.\"\n }\n ]\n },\n {\n id: \"level\",\n type: \"text\",\n storageId: \"text@level\",\n fieldId: \"level\",\n label: \"Level\",\n validation: [\n {\n name: \"required\",\n message: \"Value is required.\"\n }\n ],\n predefinedValues: {\n enabled: true,\n values: [\n {\n label: \"Viewer\",\n value: \"viewer\"\n },\n {\n label: \"Editor\",\n value: \"editor\"\n },\n {\n label: \"Owner\",\n value: \"owner\"\n }\n ]\n }\n }\n ],\n layout: [[\"target\"], [\"level\"]]\n }\n });\n\nexport const FOLDER_MODEL_ID = \"acoFolder\";\n\nexport const createFolderModelDefinition = (): FolderModelDefinition => {\n return {\n name: \"ACO - Folder\",\n modelId: FOLDER_MODEL_ID,\n titleFieldId: \"title\",\n layout: [[\"title\"], [\"slug\"], [\"type\"], [\"parentId\"], [\"permissions\"]],\n\n fields: [titleField(), slugField(), typeField(), parentIdField(), permissionsField()],\n description: \"ACO - Folder content model\",\n isPrivate: true\n };\n};\n"],"mappings":"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"}