don't offer download button if no-one can download
Massimo Melina committed
Apr 5, 2023 at 23:19 UTC
572f1ad8e229bcf18ce20ba7a1ca3d94b0b29ded
4 files changed
+22
-13
frontend/src/BrowseFiles.ts
+5
-3
@@ -227,10 +227,12 @@ const Entry = memo((entry: DirEntry & { midnight: Date, separator?: string }) =>
227
ev.preventDefault()
228
const OPEN_ICON = 'play'
229
const OPEN_LABEL = t('file_open', "Open")
230
+ const couldRead = entry.p !== (isFolder ? 'l' : 'r')
231
const menu = [
231
- menuOnLink && (isFolder ? h(Link, { to: base + uri, onClick: () => close() }, hIcon(OPEN_ICON), OPEN_LABEL)
232
- : { label: OPEN_LABEL, href: uri, target: isFolder ? undefined : '_blank', icon: OPEN_ICON }),
233
- { label: t`Download`, href: uri + (isFolder ? '?get=zip' : '?dl'), icon: 'download' },
232
+ couldRead && menuOnLink
233
+ && (isFolder ? h(Link, { to: base + uri, onClick: () => close() }, hIcon(OPEN_ICON), OPEN_LABEL)
234
+ : { label: OPEN_LABEL, href: uri, target: isFolder ? undefined : '_blank', icon: OPEN_ICON }),
235
+ couldRead && { label: t`Download`, href: uri + (isFolder ? '?get=zip' : '?dl'), icon: 'download' },
236
can_delete && { label: t`Delete`, icon: 'trash', onClick: () => deleteFiles([uri], base) }
237
]
238
const props = [
frontend/src/index.scss
+4
-2
@@ -401,14 +401,16 @@ button label {
401
& dd { margin-left: 1.5em; }
402
}
403
.file-menu {
404
- padding-top: .5em;
405
- border-top: 1px solid var(--faint-contrast);
404
margin-top: 1em;
405
406
display: flex;
407
flex-direction: column;
408
& a {
409
padding: .5em 0;
410
+ &:first-child {
411
+ padding-top: 1em;
412
+ border-top: 1px solid var(--faint-contrast);
413
+ }
414
& .icon { margin-right: 0.5em; }
415
&:hover { @extend .highlightedText }
416
}
src/api.file_list.ts
+9
-4
@@ -6,8 +6,8 @@ import {
6
nodeIsDirectory,
7
statusCodeForMissingPerm,
8
urlToNode,
9
- VfsNode,
10
- walkNode
9
+ VfsNode, VfsPerm,
10
+ walkNode, WHO_NO_ONE
11
} from './vfs'
12
import { ApiError, ApiHandler, SendListReadable } from './apiMiddleware'
13
import { stat } from 'fs/promises'
@@ -111,12 +111,17 @@ async function nodeToDirEntry(ctx: Koa.Context, node: VfsNode): Promise<DirEntry
111
c: ctime,
112
m: Math.abs(+mtime-+ctime) < 1000 ? undefined : mtime,
113
s: folder ? undefined : st.size,
114
- p: ((hasPermission(node, 'can_read', ctx) ? '' : 'R')
115
- + (hasPermission(node, 'can_list', ctx) ? '' : 'L'))
114
+ p: (['can_read', 'can_list'] as (keyof VfsPerm)[]).map(perm2letter).join('')
115
|| undefined
116
}
117
}
118
catch {
119
return null
120
}
121
+
122
+ function perm2letter(k: keyof VfsPerm) {
123
+ return node[k] === WHO_NO_ONE ? k[4]!
124
+ : hasPermission(node, k, ctx) ? ''
125
+ : k[4]!.toUpperCase()
126
+ }
127
}
src/vfs.ts
+4
-4
@@ -10,16 +10,16 @@ import { HTTP_FOOL, HTTP_FORBIDDEN, HTTP_UNAUTHORIZED } from './const'
10
import events from './events'
11
import { getCurrentUsernameExpanded } from './perm'
12
13
-const WHO_ANYONE = true
14
-const WHO_NO_ONE = false
15
-const WHO_ANY_ACCOUNT = '*'
13
+export const WHO_ANYONE = true
14
+export const WHO_NO_ONE = false
15
+export const WHO_ANY_ACCOUNT = '*'
16
type AccountList = string[]
17
export type Who = typeof WHO_ANYONE
18
| typeof WHO_NO_ONE
19
| typeof WHO_ANY_ACCOUNT
20
| AccountList
21
22
-interface VfsPerm {
22
+export interface VfsPerm {
23
can_read: Who
24
can_see: Who
25
can_list: Who