fix: admin/fs: shouldn't show "as" permissions that don't exist
Massimo Melina committed
Nov 30, 2023 at 23:28 UTC
b1e25eed58b9004dca79bde153b354b22cd85f9d
1 file changed
+43
-11
admin/src/FileForm.ts
+43
-11
@@ -14,8 +14,29 @@ import {
14
StringField
15
} from '@hfs/mui-grid-form'
16
import { apiCall, UseApi, useApiEx } from './api'
17
-import { basename, Btn, defaultPerms, formatBytes, formatTimestamp, IconBtn, isEqualLax, isWhoObject, LinkBtn, modifiedSx,
18
- newDialog, objSameKeys, onlyTruthy, prefix, useBreakpoint, VfsPerms, wantArray, Who, WhoObject, wikiLink } from './misc'
17
+import {
18
+ _log,
19
+ basename,
20
+ Btn,
21
+ defaultPerms,
22
+ formatBytes,
23
+ formatTimestamp,
24
+ IconBtn,
25
+ isEqualLax,
26
+ isWhoObject,
27
+ LinkBtn,
28
+ modifiedSx,
29
+ newDialog,
30
+ objSameKeys,
31
+ onlyTruthy,
32
+ prefix,
33
+ useBreakpoint,
34
+ VfsPerms,
35
+ wantArray,
36
+ Who,
37
+ WhoObject,
38
+ wikiLink
39
+} from './misc'
40
import { reloadVfs, VfsNode } from './VfsPage'
41
import md from './md'
42
import _ from 'lodash'
@@ -70,6 +91,14 @@ export default function FileForm({ file, anyMask, addToBar, statusApi }: FileFor
91
const accounts = data.list
92
93
const needSourceWarning = !hasSource && "Works only on folders with source! "
94
+ const show: Record<keyof VfsPerms, boolean> = {
95
+ can_read: !isLink,
96
+ can_see: true,
97
+ can_archive: !isLink,
98
+ can_list: isDir,
99
+ can_upload: isDir && hasSource,
100
+ can_delete: isDir && hasSource,
101
+ }
102
return h(Form, {
103
values,
104
set(v, k) {
@@ -133,12 +162,12 @@ export default function FileForm({ file, anyMask, addToBar, statusApi }: FileFor
162
: "This field is empty, and thus this element is a virtual-folder. You can set this field, pointing at any folder/file on disk.",
163
},
164
!isLink && { k: 'id', comp: LinkField, statusApi, xs: 12 },
136
- !isLink && perm('can_read', "Who can see but not download will be asked to login"),
165
+ perm('can_read', "Who can see but not download will be asked to login"),
166
perm('can_see', "If you can't see, you may still download with a direct link"),
138
- !isLink && perm('can_archive', "Should this be included when user downloads as ZIP", { label: "Who can zip", lg: isDir ? true : 12 }),
139
- isDir && perm('can_list', "Permission to see content of folders", { contentText: "subfolders" }),
140
- isDir && perm('can_delete', [needSourceWarning, "Those who can delete can also rename"]),
141
- isDir && perm('can_upload', needSourceWarning, { contentText: "subfolders" }),
167
+ perm('can_archive', "Should this be included when user downloads as ZIP", { lg: isDir ? true : 12 }),
168
+ perm('can_list', "Permission to see content of folders", { contentText: "subfolders" }),
169
+ perm('can_delete', [needSourceWarning, "Those who can delete can also rename"]),
170
+ perm('can_upload', needSourceWarning, { contentText: "subfolders" }),
171
showSize && { k: 'size', comp: DisplayField, lg: 4, toField: formatBytes },
172
showTimestamps && { k: 'ctime', comp: DisplayField, md: 6, lg: showSize && 4, label: "Created", toField: formatTimestamp },
173
showTimestamps && { k: 'mtime', comp: DisplayField, md: 6, lg: showSize && 4, label: "Modified", toField: formatTimestamp },
@@ -159,12 +188,15 @@ export default function FileForm({ file, anyMask, addToBar, statusApi }: FileFor
188
})
189
190
function perm(perm: keyof VfsPerms, helperText?: ReactNode, props: Partial<WhoFieldProps>={}) {
191
+ if (!show[perm]) return null
192
+ const dontShow = [perm, ...onlyTruthy(_.map(show, (v,k) => !v && k))]
193
+ const others = _.difference(Object.keys(defaultPerms), dontShow)
194
return {
195
comp: WhoField,
196
k: perm, lg: 6, xl: 4,
197
parent, accounts, helperText, isDir,
198
showInherited: anyMask, // with masks, you may need to set a permission to override the mask
167
- otherPerms: _.without(Object.keys(defaultPerms), perm).map(x => ({ value: x, label: "As " +perm2word(x) })),
199
+ otherPerms: others.map(x => ({ value: x, label: "As " +perm2word(x) })),
200
label: "Who can " + perm2word(perm),
201
inherit: file.inherited?.[perm] ?? defaultPerms[perm],
202
byMasks: byMasks?.[perm],
@@ -177,7 +209,7 @@ export default function FileForm({ file, anyMask, addToBar, statusApi }: FileFor
209
210
function perm2word(perm: string) {
211
const word = perm.split('_')[1]
180
- return word === 'read' ? 'download' : word
212
+ return word === 'read' ? 'download' : word === 'archive' ? 'zip' : word
213
}
214
215
interface WhoFieldProps extends FieldProps<Who | undefined> {
@@ -205,7 +237,7 @@ function WhoField({ value, onChange, parent, inherit, accounts, helperText, show
237
// don't offer inherited value twice, unless it was already selected, or it is forced
238
].map(x => !hideValues?.includes(x.value) && (x.value === thisValue || showInherited || x.value !== inherit)
239
&& { label: _.capitalize(who2desc(x.value)), ...x })), // default label
208
- [inherit, parent, thisValue])
240
+ [inherit, parent, thisValue])
241
242
const timeout = 500
243
const arrayMode = Array.isArray(thisValue)
@@ -221,7 +253,7 @@ function WhoField({ value, onChange, parent, inherit, accounts, helperText, show
253
}),
254
h(Collapse, { in: arrayMode, timeout },
255
arrayMode && h(MultiSelectField as Field<string[]>, {
224
- label: accounts?.length ? "Choose accounts for " + rest.label : "You didn't create any account yet",
256
+ label: accounts?.length ? "Accounts for " + rest.label : "You didn't create any account yet",
257
value: thisValue,
258
onChange,
259
options: accounts?.map(a => ({ value: a.username, label: a.username })) || [],