From 0f05a41ea8b601d31a758c1b6b7465d4c567a9e4 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Fri, 14 Jun 2024 13:23:28 -0400 Subject: [PATCH] tweak: add improvements to share/file-by-username --- packages/backend/src/routers/share.js | 180 ++++++++++-------- .../backend/src/services/PuterAPIService.js | 2 +- 2 files changed, 99 insertions(+), 83 deletions(-) diff --git a/packages/backend/src/routers/share.js b/packages/backend/src/routers/share.js index 8568e0a3..83bee5c6 100644 --- a/packages/backend/src/routers/share.js +++ b/packages/backend/src/routers/share.js @@ -11,95 +11,111 @@ const FSNodeParam = require('../api/filesystem/FSNodeParam'); const { TYPE_DIRECTORY } = require('../filesystem/FSNodeContext'); const { PermissionUtil } = require('../services/auth/PermissionService'); +const { validate } = require('uuid'); +const configurable_auth = require('../middleware/configurable_auth'); const uuidv4 = require('uuid').v4; const router = express.Router(); -router.use(auth2); + +const validate_share_file_params = req => { + let path = req.body.path; + if ( ! (typeof path === 'string') ) { + throw APIError.create('field_invalid', null, { + key: 'path', + expected: 'string', + got: typeof path, + }); + } + + const access_level = req.body.access_level || 'write'; + if ( ! ['read','write'].includes(access_level) ) { + throw APIError.create('field_invalid', null, { + key: 'access_level', + expected: '"read" or "write"', + }); + } + + const permission = PermissionUtil.join('fs', path, access_level); + + return { + path, access_level, permission, + }; +} + +const handler_file_by_username = async (req, res) => { + const svc_token = req.services.get('token'); + const svc_email = req.services.get('email'); + const svc_permission = req.services.get('permission'); + + console.log('which actor exists?', + req.actor, + Context.get('actor')) + const actor = Context.get('actor'); + + const username = req.body.username; + if ( ! (typeof username === 'string') ) { + throw APIError.create('field_invalid', null, { + key: 'username', + expected: 'string', + got: typeof username, + }); + } + + const { path, permission } = + validate_share_file_params(req); + + const recipient = await get_user({ username }); + if ( ! recipient ) { + throw APIError.create('user_does_not_exist', null, { + username + }); + } + + await svc_permission.grant_user_user_permission( + actor, username, permission, {}, {}, + ); + + const node = await (new FSNodeParam('path')).consolidate({ + req, getParam: () => path + }); + + if ( ! await node.exists() ) { + throw APIError.create('subject_does_not_exist'); + } + + let email_path = path; + if ( await node.get('type') !== TYPE_DIRECTORY ) { + // remove last component + email_path = email_path.slice(0, path.lastIndexOf('/')+1); + } + + if ( email_path.startsWith('/') ) email_path = email_path.slice(1); + const link = `${config.origin}/show/${email_path}`; + + const email_values = { + link, + susername: req.user.username, + ...(recipient ? { + rusername: recipient.username, + } : {}), + }; + + const email_tmpl = recipient ? + 'share_existing_user' : 'share_new_user'; + + await svc_email.send_email({ email: recipient.email }, email_tmpl, email_values); + + res.send({}); +}; Endpoint({ route: '/file-by-username', + mw: [configurable_auth()], methods: ['POST'], - handler: async (req, res) => { - const svc_token = req.services.get('token'); - const svc_email = req.services.get('email'); - const svc_permission = req.services.get('permission'); - - console.log('which actor exists?', - req.actor, - Context.get('actor')) - const actor = Context.get('actor'); - - const username = req.body.username; - if ( ! (typeof username === 'string') ) { - throw APIError.create('field_invalid', null, { - key: 'username', - expected: 'string', - got: typeof username, - }); - } - - let path = req.body.path; - if ( ! (typeof path === 'string') ) { - throw APIError.create('field_invalid', null, { - key: 'path', - expected: 'string', - got: typeof path, - }); - } - - const access_level = req.body.access_level || 'write'; - if ( ! ['read','write'].includes(access_level) ) { - throw APIError.create('field_invalid', null, { - key: 'access_level', - expected: '"read" or "write"', - }); - } - - const recipient = await get_user({ username }); - if ( ! recipient ) { - throw APIError.create('user_does_not_exist', null, { - username - }); - } - - await svc_permission.grant_user_user_permission( - actor, username, - PermissionUtil.join('fs', path, access_level), - {}, {}, - ); - - const node = await (new FSNodeParam('path')).consolidate({ - req, getParam: () => path - }); - - if ( ! await node.exists() ) { - throw APIError.create('subject_does_not_exist'); - } - - if ( await node.get('type') !== TYPE_DIRECTORY ) { - // remove last component - path = path.slice(0, path.lastIndexOf('/')+1); - } - - if ( path.startsWith('/') ) path = path.slice(1); - const link = `${config.origin}/show/${path}`; - - const email_values = { - link, - susername: req.user.username, - ...(recipient ? { - rusername: recipient.username, - } : {}), - }; - - const email_tmpl = recipient ? - 'share_existing_user' : 'share_new_user'; - - await svc_email.send_email({ email: recipient.email }, email_tmpl, email_values); - - res.send({}); - }, + handler: handler_file_by_username, }).attach(router); -module.exports = router; +module.exports = app => { + app.use('/share', router); +}; diff --git a/packages/backend/src/services/PuterAPIService.js b/packages/backend/src/services/PuterAPIService.js index 21b499d0..7657cc76 100644 --- a/packages/backend/src/services/PuterAPIService.js +++ b/packages/backend/src/services/PuterAPIService.js @@ -76,7 +76,7 @@ class PuterAPIService extends BaseService { app.use(require('../routers/healthcheck')) app.use(require('../routers/test')) app.use(require('../routers/update-taskbar-items')) - app.use('/share', require('../routers/share')); + require('../routers/share')(app); require('../routers/whoami')(app); }