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)}`,
|
message: ({ identifier }) => `Entity not found: ${quot(identifier)}`,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Share
|
||||||
|
'user_does_not_exist': {
|
||||||
|
status: 422,
|
||||||
|
message: ({ username }) => `The user ${quot(username)} does not exist.`
|
||||||
|
},
|
||||||
|
|
||||||
// Chat
|
// Chat
|
||||||
// TODO: specifying these errors here might be a violation
|
// TODO: specifying these errors here might be a violation
|
||||||
// of separation of concerns. Services could register their
|
// 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>Sincerely,</p>
|
||||||
<p>Puter</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 {
|
class Emailservice extends BaseService {
|
||||||
|
@ -76,6 +76,7 @@ class PuterAPIService extends BaseService {
|
|||||||
app.use(require('../routers/healthcheck'))
|
app.use(require('../routers/healthcheck'))
|
||||||
app.use(require('../routers/test'))
|
app.use(require('../routers/test'))
|
||||||
app.use(require('../routers/update-taskbar-items'))
|
app.use(require('../routers/update-taskbar-items'))
|
||||||
|
app.use('/share', require('../routers/share'));
|
||||||
require('../routers/whoami')(app);
|
require('../routers/whoami')(app);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -158,6 +158,19 @@ class PermissionUtil {
|
|||||||
}
|
}
|
||||||
return unescaped_str;
|
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) {
|
static split (permission) {
|
||||||
return permission
|
return permission
|
||||||
@ -165,6 +178,13 @@ class PermissionUtil {
|
|||||||
.map(PermissionUtil.unescape_permission_component)
|
.map(PermissionUtil.unescape_permission_component)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static join (...components) {
|
||||||
|
return components
|
||||||
|
.map(PermissionUtil.escape_permission_component)
|
||||||
|
.join(':')
|
||||||
|
;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PermissionService extends BaseService {
|
class PermissionService extends BaseService {
|
||||||
|
Loading…
Reference in New Issue
Block a user