Skip to content

Commit 847e6fb

Browse files
committed
refactor: update hookFilters to return a copy of the filter array for safety
1 parent 65f8ff9 commit 847e6fb

2 files changed

Lines changed: 13 additions & 1 deletion

File tree

‎adminforth/modules/userScopedResource.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ function hookFilters(
5555
if (!filter) {
5656
return [];
5757
}
58-
return Array.isArray(filter) ? filter : [filter];
58+
// hooks push the row scope into query.filters, so they get a copy rather than the caller's array
59+
return Array.isArray(filter) ? [...filter] : [filter];
5960
}
6061

6162
/** Hook-running write paths, supplied by AdminForth. */

‎documentation/docs/tutorial/09-Plugins/08-import-export.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,17 @@ Two things to keep in mind:
122122

123123
`columnsToExport` affects export only. Import keeps accepting every column described in the resource, so a narrower export still imports back, and a file which still carries an exported virtual column imports cleanly too: virtual columns are dropped from every imported row, because there is no place in the database to store them.
124124

125+
## Permissions
126+
127+
An export reads the records the same way the list does for the user who started it: it needs the `list` permission of the resource, the row-scoping `list.beforeDatasourceRequest` hooks narrow it, so a user exports only the rows of their own list, and the `list.afterDatasourceResponse` hooks run on the exported records. A big export via upload reads as the user who started the job, and fails when that user cannot be resolved anymore.
128+
129+
An import writes every row the same way the create and edit forms would for the user who started it. Each row is checked against the `create` or `edit` permission of the resource and against its row scope, so a row whose primary key belongs to a record the user cannot see fails with "not found" instead of overwriting it. The column rules of the forms apply too (`backendOnly`, `editReadonly`, `showIn.create` / `showIn.edit` with their `allowModifyWhenNotShowIn*` and `fillOnCreate` escapes):
130+
131+
- An existing record gets only the cells which differ from what is stored, so columns hidden from the edit form, like the primary key or a creation date, import back unchanged without an error. Changing such a cell in the file fails that row.
132+
- A new record gets only its non-empty cells, empty cells take the column default. A filled cell of a column hidden from the create form fails that row, unless the column allows it with `fillOnCreate` or `allowModifyWhenNotShowInCreate`.
133+
134+
Hooks and validation of the resource run for every imported row.
135+
125136
## Transforming records before they are written
126137

127138
`hooks.export.beforeWrite` is called with every batch of records right before they are serialized into the file. Records are passed as a mutable array, so the hook fills virtual columns, rewrites values, or drops rows:

0 commit comments

Comments
 (0)