@samitouri / QOSami-HFS / commits / 6bdbb0eb

support serving web-links

Massimo Melina committed Apr 14, 2024 at 11:57 UTC 6bdbb0ebbdfd237a03c77a14e88214ff2ecc6081
3 files changed +8 -7
admin/src/FileForm.ts
+1 -1
@@ -151,6 +151,7 @@ export default function FileForm({ file, addToBar, statusApi, accounts, saved }:
151 helperText: !values.source ? "This field is empty, and thus this element is a virtual-folder. You can set this field, pointing at any folder/file on disk."
152 : isDir ? "Content from this path on disk will be listed, but you can also add more" : undefined,
153 },
154 + { k: 'id', comp: LinkField, statusApi, xs: 12 },
155 isLink && {
156 k: 'target',
157 comp: BoolField,
@@ -159,7 +160,6 @@ export default function FileForm({ file, addToBar, statusApi, accounts, saved }:
160 fromField: x => x ? '_blank' : null,
161 toField: x => x > '',
162 },
162 - !isLink && { k: 'id', comp: LinkField, statusApi, xs: 12 },
163 perm('can_read', "Who can see but not download will be asked to login"),
164 perm('can_see', "If you can't see, you may still download with a direct link"),
165 perm('can_archive', "Should this be included when user downloads as ZIP", { lg: isDir ? true : 12 }),
admin/src/addFiles.ts
+1 -1
@@ -63,7 +63,7 @@ export async function addVirtual() {
63 export async function addLink() {
64 try {
65 const { id: parent } = getFolderFromSelected()
66 - const res = await apiCall('add_vfs', { parent, name: 'new link', url: 'https://google.com' })
66 + const res = await apiCall('add_vfs', { parent, name: 'new link', url: 'https://example.com' })
67 reloadVfs([ parent + encodeURI(res.name) ])
68 toast("Link created", 'success', {
69 onClose: () => focusSelector('input[name=url]')
src/serveGuiAndSharedFiles.ts
+6 -5
@@ -82,11 +82,12 @@ export const serveGuiAndSharedFiles: Koa.Middleware = async (ctx, next) => {
82 if (node.default && path.endsWith('/') && !get) // final/ needed on browser to make resource urls correctly with html pages
83 node = await urlToNode(node.default, ctx, node) ?? node
84 if (!await nodeIsDirectory(node))
85 - return !node.source ? sendErrorPage(ctx, HTTP_METHOD_NOT_ALLOWED) // !dir && !source is not supported at this moment
86 - : !statusCodeForMissingPerm(node, 'can_read', ctx) ? serveFileNode(ctx, node) // all good
87 - : ctx.status !== HTTP_UNAUTHORIZED ? null // all errors don't need extra handling, except unauthorized
88 - : path.endsWith('/') ? (ctx.state.serveApp = true) && serveFrontendFiles(ctx, next) // since this is no dir, final / means we are dealing with default file, for which we still provide fancy login
89 - : (ctx.set('WWW-Authenticate', 'Basic'), sendErrorPage(ctx)) // this is necessary to support standard urls with credentials
85 + return node.url ? ctx.redirect(node.url)
86 + : !node.source ? sendErrorPage(ctx, HTTP_METHOD_NOT_ALLOWED) // !dir && !source is not supported at this moment
87 + : !statusCodeForMissingPerm(node, 'can_read', ctx) ? serveFileNode(ctx, node) // all good
88 + : ctx.status !== HTTP_UNAUTHORIZED ? null // all errors don't need extra handling, except unauthorized
89 + : path.endsWith('/') ? (ctx.state.serveApp = true) && serveFrontendFiles(ctx, next) // since this is no dir, final / means we are dealing with default file, for which we still provide fancy login
90 + : (ctx.set('WWW-Authenticate', 'Basic'), sendErrorPage(ctx)) // this is necessary to support standard urls with credentials
91 if (!path.endsWith('/'))
92 return ctx.redirect(ctx.state.revProxyPath + ctx.originalUrl.replace(/(\?|$)/, '/$1')) // keep query-string, if any
93 if (statusCodeForMissingPerm(node, 'can_list', ctx)) {