mirror of
https://github.com/HeyPuter/puter
synced 2024-11-14 22:06:00 +00:00
feat: add /share/file-by-username endpoint
This commit is contained in:
parent
1859668257
commit
5d214c7b52
@ -388,6 +388,12 @@ module.exports = class APIError {
|
||||
message: ({ identifier }) => `Entity not found: ${quot(identifier)}`,
|
||||
},
|
||||
|
||||
// Share
|
||||
'user_does_not_exist': {
|
||||
status: 422,
|
||||
message: ({ username }) => `The user ${quot(username)} does not exist.`
|
||||
},
|
||||
|
||||
// Chat
|
||||
// TODO: specifying these errors here might be a violation
|
||||
// of separation of concerns. Services could register their
|
||||
|
90
packages/backend/src/routers/share.js
Normal file
90
packages/backend/src/routers/share.js
Normal file
@ -0,0 +1,90 @@
|
||||
const express = require('express');
|
||||
const { Endpoint } = require('../util/expressutil');
|
||||
|
||||
const validator = require('validator');
|
||||
const APIError = require('../api/APIError');
|
||||
const { get_user } = require('../helpers');
|
||||
const { Context } = require('../util/context');
|
||||
const auth2 = require('../middleware/auth2');
|
||||
const config = require('../config');
|
||||
|
||||
const { PermissionUtil } = require('../services/auth/PermissionService');
|
||||
|
||||
const uuidv4 = require('uuid').v4;
|
||||
|
||||
const router = express.Router();
|
||||
router.use(auth2);
|
||||
|
||||
Endpoint({
|
||||
route: '/file-by-username',
|
||||
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),
|
||||
{}, {},
|
||||
);
|
||||
|
||||
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({});
|
||||
},
|
||||
}).attach(router);
|
||||
|
||||
module.exports = router;
|
@ -130,7 +130,17 @@ If this was not you, please contact support@puter.com immediately.
|
||||
<p>Sincerely,</p>
|
||||
<p>Puter</p>
|
||||
`
|
||||
}
|
||||
},
|
||||
// TODO: revise email contents
|
||||
'share_existing_user': {
|
||||
subject: 'Puter share from {{susername}}',
|
||||
html: `
|
||||
<p>Hi there {{rusername}},</p>
|
||||
<p>{{link}}</p>
|
||||
<p>Sincerely,</p>
|
||||
<p>Puter</p>
|
||||
`
|
||||
},
|
||||
}
|
||||
|
||||
class Emailservice extends BaseService {
|
||||
|
@ -76,6 +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/whoami')(app);
|
||||
|
||||
}
|
||||
|
@ -158,6 +158,19 @@ class PermissionUtil {
|
||||
}
|
||||
return unescaped_str;
|
||||
}
|
||||
|
||||
static escape_permission_component (component) {
|
||||
let escaped_str = '';
|
||||
for ( let i = 0 ; i < component.length ; i++ ) {
|
||||
const c = component[i];
|
||||
if ( c === ':' ) {
|
||||
escaped_str += '\\C';
|
||||
continue;
|
||||
}
|
||||
escaped_str += c;
|
||||
}
|
||||
return escaped_str;
|
||||
}
|
||||
|
||||
static split (permission) {
|
||||
return permission
|
||||
@ -165,6 +178,13 @@ class PermissionUtil {
|
||||
.map(PermissionUtil.unescape_permission_component)
|
||||
;
|
||||
}
|
||||
|
||||
static join (...components) {
|
||||
return components
|
||||
.map(PermissionUtil.escape_permission_component)
|
||||
.join(':')
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
class PermissionService extends BaseService {
|
||||
|
Loading…
Reference in New Issue
Block a user