@adminforth/import-export 1.5.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -10,6 +10,7 @@ export default class ImportExport extends AdminForthPlugin {
10
10
  constructor(options: PluginOptions);
11
11
  private isRowValid;
12
12
  private tryToAuditLogAction;
13
+ private ensureAnyAllowed;
13
14
  modifyResourceConfig(adminforth: IAdminForth, resourceConfig: AdminForthResource): Promise<void>;
14
15
  validateConfigAfterDiscover(adminforth: IAdminForth, resourceConfig: AdminForthResource): void;
15
16
  instanceUniqueRepresentation(pluginOptions: any): string;
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { AdminForthPlugin, suggestIfTypo, AdminForthFilterOperators, Filters, AdminForthDataTypes, rejectApiRawFilters } from "adminforth";
10
+ import { AdminForthPlugin, suggestIfTypo, AdminForthFilterOperators, Filters, AdminForthDataTypes, rejectApiRawFilters, interpretResource, ActionCheckSource, AllowedActionsEnum } from "adminforth";
11
11
  import pLimit from 'p-limit';
12
12
  export default class ImportExport extends AdminForthPlugin {
13
13
  constructor(options) {
@@ -53,6 +53,20 @@ export default class ImportExport extends AdminForthPlugin {
53
53
  console.error('Failed to log action to AuditLogPlugin:', e);
54
54
  }
55
55
  }
56
+ ensureAnyAllowed(adminUser_1, checks_1) {
57
+ return __awaiter(this, arguments, void 0, function* (adminUser, checks, meta = {}) {
58
+ for (const { source, action } of checks) {
59
+ const { allowedActions } = yield interpretResource(adminUser, this.resourceConfig, meta, source, this.adminforth);
60
+ if (allowedActions[action] === true) {
61
+ return { ok: true };
62
+ }
63
+ }
64
+ return {
65
+ ok: false,
66
+ error: 'Action is not allowed',
67
+ };
68
+ });
69
+ }
56
70
  modifyResourceConfig(adminforth, resourceConfig) {
57
71
  const _super = Object.create(null, {
58
72
  modifyResourceConfig: { get: () => super.modifyResourceConfig }
@@ -101,6 +115,13 @@ export default class ImportExport extends AdminForthPlugin {
101
115
  path: `/plugin/${this.pluginInstanceId}/export-csv`,
102
116
  handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, headers }) {
103
117
  const { filters, sort } = body;
118
+ const access = yield this.ensureAnyAllowed(adminUser, [
119
+ { source: ActionCheckSource.ListRequest, action: AllowedActionsEnum.list },
120
+ { source: ActionCheckSource.ShowRequest, action: AllowedActionsEnum.show },
121
+ ], { requestBody: body });
122
+ if (!access.ok) {
123
+ return { ok: false, error: access.error };
124
+ }
104
125
  const rawFilterError = rejectApiRawFilters(body.filters);
105
126
  if (rawFilterError) {
106
127
  return rawFilterError;
@@ -138,7 +159,13 @@ export default class ImportExport extends AdminForthPlugin {
138
159
  path: `/plugin/${this.pluginInstanceId}/import-csv`,
139
160
  handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, query, headers, cookies, requestUrl, response }) {
140
161
  const { data } = body;
141
- this.tryToAuditLogAction('import', `Import CSV with ${Object.keys(data).length} columns`, adminUser, headers);
162
+ const createEditAccess = yield this.ensureAnyAllowed(adminUser, [
163
+ { source: ActionCheckSource.CreateRequest, action: AllowedActionsEnum.create },
164
+ { source: ActionCheckSource.EditRequest, action: AllowedActionsEnum.edit }
165
+ ], { requestBody: body });
166
+ if (!createEditAccess.ok) {
167
+ return { ok: false, error: createEditAccess.error };
168
+ }
142
169
  const columns = this.getColumnNames(data);
143
170
  const { errors, resourceColumns } = this.validateColumns(columns);
144
171
  const resource = this.adminforth.config.resources.find(r => r.resourceId === this.resourceConfig.resourceId);
@@ -148,6 +175,7 @@ export default class ImportExport extends AdminForthPlugin {
148
175
  const primaryKeyColumn = this.resourceConfig.columns.find(col => col.primaryKey);
149
176
  const rows = this.buildRowsFromData(data, columns, resourceColumns, { coerceTypes: true });
150
177
  console.log('Prepared rows for import:', rows);
178
+ this.tryToAuditLogAction('import', `Import CSV with ${Object.keys(data).length} columns`, adminUser, headers);
151
179
  let importedCount = 0;
152
180
  let updatedCount = 0;
153
181
  const limit = pLimit(100);
@@ -200,7 +228,10 @@ export default class ImportExport extends AdminForthPlugin {
200
228
  path: `/plugin/${this.pluginInstanceId}/import-csv-new-only`,
201
229
  handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser, query, headers, cookies, requestUrl, response }) {
202
230
  const { data } = body;
203
- this.tryToAuditLogAction('import', `Import CSV (new only) with ${Object.keys(data).length} columns`, adminUser, headers);
231
+ const access = yield this.ensureAnyAllowed(adminUser, [{ source: ActionCheckSource.CreateRequest, action: AllowedActionsEnum.create }], { requestBody: body });
232
+ if (!access.ok) {
233
+ return { ok: false, error: access.error };
234
+ }
204
235
  const columns = this.getColumnNames(data);
205
236
  const resource = this.adminforth.config.resources.find(r => r.resourceId === this.resourceConfig.resourceId);
206
237
  const { errors, resourceColumns } = this.validateColumns(columns);
@@ -209,6 +240,7 @@ export default class ImportExport extends AdminForthPlugin {
209
240
  }
210
241
  const primaryKeyColumn = this.resourceConfig.columns.find(col => col.primaryKey);
211
242
  const rows = this.buildRowsFromData(data, columns, resourceColumns, { coerceTypes: true });
243
+ this.tryToAuditLogAction('import', `Import CSV (new only) with ${Object.keys(data).length} columns`, adminUser, headers);
212
244
  let importedCount = 0;
213
245
  const limit = pLimit(100);
214
246
  yield Promise.all(rows.map((row) => limit(() => __awaiter(this, void 0, void 0, function* () {
@@ -243,7 +275,14 @@ export default class ImportExport extends AdminForthPlugin {
243
275
  server.endpoint({
244
276
  method: 'POST',
245
277
  path: `/plugin/${this.pluginInstanceId}/check-records`,
246
- handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body }) {
278
+ handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, adminUser }) {
279
+ const access = yield this.ensureAnyAllowed(adminUser, [
280
+ { source: ActionCheckSource.ListRequest, action: AllowedActionsEnum.list },
281
+ { source: ActionCheckSource.ShowRequest, action: AllowedActionsEnum.show },
282
+ ], { requestBody: body });
283
+ if (!access.ok) {
284
+ return { ok: false, error: access.error };
285
+ }
247
286
  const { data } = body;
248
287
  const primaryKeyColumn = this.resourceConfig.columns.find(col => col.primaryKey);
249
288
  const columns = this.getColumnNames(data);
package/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AdminForthPlugin, suggestIfTypo, AdminForthFilterOperators, Filters, AdminForthDataTypes, rejectApiRawFilters } from "adminforth";
1
+ import { AdminForthPlugin, suggestIfTypo, AdminForthFilterOperators, Filters, AdminForthDataTypes, rejectApiRawFilters, interpretResource, ActionCheckSource, AllowedActionsEnum } from "adminforth";
2
2
  import type { IAdminForth, IHttpServer, AdminForthResourceColumn, AdminForthComponentDeclaration, AdminForthResource, AdminUser } from "adminforth";
3
3
  import type { PluginOptions } from './types.js';
4
4
  import pLimit from 'p-limit';
@@ -57,6 +57,31 @@ export default class ImportExport extends AdminForthPlugin {
57
57
  }
58
58
  }
59
59
 
60
+ private async ensureAnyAllowed(
61
+ adminUser: AdminUser,
62
+ checks: { source: ActionCheckSource; action: AllowedActionsEnum }[],
63
+ meta: Record<string, unknown> = {}
64
+ ): Promise<{ ok: boolean; error?: string }> {
65
+ for (const { source, action } of checks) {
66
+ const { allowedActions } = await interpretResource(
67
+ adminUser,
68
+ this.resourceConfig,
69
+ meta,
70
+ source,
71
+ this.adminforth
72
+ );
73
+
74
+ if (allowedActions[action] === true) {
75
+ return { ok: true };
76
+ }
77
+ }
78
+
79
+ return {
80
+ ok: false,
81
+ error: 'Action is not allowed',
82
+ };
83
+ }
84
+
60
85
  async modifyResourceConfig(adminforth: IAdminForth, resourceConfig: AdminForthResource) {
61
86
  super.modifyResourceConfig(adminforth, resourceConfig);
62
87
  if (!resourceConfig.options.pageInjections) {
@@ -104,6 +129,17 @@ export default class ImportExport extends AdminForthPlugin {
104
129
  path: `/plugin/${this.pluginInstanceId}/export-csv`,
105
130
  handler: async ({ body, adminUser, headers }) => {
106
131
  const { filters, sort } = body;
132
+ const access = await this.ensureAnyAllowed(
133
+ adminUser,
134
+ [
135
+ { source: ActionCheckSource.ListRequest, action: AllowedActionsEnum.list },
136
+ { source: ActionCheckSource.ShowRequest, action: AllowedActionsEnum.show },
137
+ ],
138
+ { requestBody: body }
139
+ );
140
+ if (!access.ok) {
141
+ return { ok: false, error: access.error };
142
+ }
107
143
  const rawFilterError = rejectApiRawFilters(body.filters);
108
144
  if (rawFilterError) {
109
145
  return rawFilterError;
@@ -148,7 +184,17 @@ export default class ImportExport extends AdminForthPlugin {
148
184
  path: `/plugin/${this.pluginInstanceId}/import-csv`,
149
185
  handler: async ({ body, adminUser, query, headers, cookies, requestUrl, response }) => {
150
186
  const { data } = body;
151
- this.tryToAuditLogAction('import', `Import CSV with ${Object.keys(data).length} columns`, adminUser, headers);
187
+ const createEditAccess = await this.ensureAnyAllowed(
188
+ adminUser,
189
+ [
190
+ { source: ActionCheckSource.CreateRequest, action: AllowedActionsEnum.create },
191
+ { source: ActionCheckSource.EditRequest, action: AllowedActionsEnum.edit }
192
+ ],
193
+ { requestBody: body }
194
+ );
195
+ if (!createEditAccess.ok) {
196
+ return { ok: false, error: createEditAccess.error };
197
+ }
152
198
  const columns = this.getColumnNames(data);
153
199
  const { errors, resourceColumns } = this.validateColumns(columns);
154
200
  const resource = this.adminforth.config.resources.find(r => r.resourceId === this.resourceConfig.resourceId);
@@ -160,6 +206,7 @@ export default class ImportExport extends AdminForthPlugin {
160
206
  const rows = this.buildRowsFromData(data, columns, resourceColumns, { coerceTypes: true });
161
207
 
162
208
  console.log('Prepared rows for import:', rows);
209
+ this.tryToAuditLogAction('import', `Import CSV with ${Object.keys(data).length} columns`, adminUser, headers);
163
210
 
164
211
  let importedCount = 0;
165
212
  let updatedCount = 0;
@@ -216,7 +263,14 @@ export default class ImportExport extends AdminForthPlugin {
216
263
  path: `/plugin/${this.pluginInstanceId}/import-csv-new-only`,
217
264
  handler: async ({ body, adminUser, query, headers, cookies, requestUrl, response }) => {
218
265
  const { data } = body;
219
- this.tryToAuditLogAction('import', `Import CSV (new only) with ${Object.keys(data).length} columns`, adminUser, headers);
266
+ const access = await this.ensureAnyAllowed(
267
+ adminUser,
268
+ [{ source: ActionCheckSource.CreateRequest, action: AllowedActionsEnum.create }],
269
+ { requestBody: body }
270
+ );
271
+ if (!access.ok) {
272
+ return { ok: false, error: access.error };
273
+ }
220
274
  const columns = this.getColumnNames(data);
221
275
  const resource = this.adminforth.config.resources.find(r => r.resourceId === this.resourceConfig.resourceId);
222
276
  const { errors, resourceColumns } = this.validateColumns(columns);
@@ -226,6 +280,7 @@ export default class ImportExport extends AdminForthPlugin {
226
280
 
227
281
  const primaryKeyColumn = this.resourceConfig.columns.find(col => col.primaryKey);
228
282
  const rows = this.buildRowsFromData(data, columns, resourceColumns, { coerceTypes: true });
283
+ this.tryToAuditLogAction('import', `Import CSV (new only) with ${Object.keys(data).length} columns`, adminUser, headers);
229
284
 
230
285
  let importedCount = 0;
231
286
  const limit = pLimit(100);
@@ -264,7 +319,18 @@ export default class ImportExport extends AdminForthPlugin {
264
319
  server.endpoint({
265
320
  method: 'POST',
266
321
  path: `/plugin/${this.pluginInstanceId}/check-records`,
267
- handler: async ({ body }) => {
322
+ handler: async ({ body, adminUser }) => {
323
+ const access = await this.ensureAnyAllowed(
324
+ adminUser,
325
+ [
326
+ { source: ActionCheckSource.ListRequest, action: AllowedActionsEnum.list },
327
+ { source: ActionCheckSource.ShowRequest, action: AllowedActionsEnum.show },
328
+ ],
329
+ { requestBody: body }
330
+ );
331
+ if (!access.ok) {
332
+ return { ok: false, error: access.error };
333
+ }
268
334
  const { data } = body as { data: Record<string, unknown[]> };
269
335
  const primaryKeyColumn = this.resourceConfig.columns.find(col => col.primaryKey);
270
336
  const columns = this.getColumnNames(data);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adminforth/import-export",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",