Skip to content

Commit

Permalink
feat: add /sharelink/request endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
KernelDeimos committed Jun 24, 2024
1 parent b0e067e commit 742f625
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 4 deletions.
12 changes: 12 additions & 0 deletions doc/devmeta/track-comments.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,15 @@ Comments beginning with `// track:`. See
or there's a common behavior that should happen
in between. The Sequence class is good for this so
it might be a worthy migration.
- `track: opposite condition of sibling`
A sibling class, function, method, or other construct of
source code has a boolean expression which always evaluates
to the opposite of the one below this track comment.
- `track: null check before processing`
An object could be undefined or null, additional processing
occurs after a null check, and the unprocessed object is not
relevant to the rest of the code. If the code for obtaining
the object and processing it is moved to a function outside,
then the null check should result in a early return of null;
this code with the track comment may have additional logic
for the null/undefined case.
5 changes: 5 additions & 0 deletions packages/backend/src/api/APIError.js
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,11 @@ module.exports = class APIError {
status: 422,
message: 'Email must be confirmed to apply a share.',
},
'no_need_to_request': {
status: 422,
message: 'This share is already valid for this user; ' +
'POST to /apply for access.'
},
'can_not_apply_to_this_user': {
status: 422,
message: 'This share can not be applied to this user.',
Expand Down
77 changes: 73 additions & 4 deletions packages/backend/src/services/ShareService.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const { whatis } = require("../util/langutil");
const { Actor, UserActorType } = require("./auth/Actor");
const BaseService = require("./BaseService");
const { DB_WRITE } = require("./database/consts");
const { UsernameNotifSelector } = require("./NotificationService");

class ShareService extends BaseService {
static MODULES = {
Expand Down Expand Up @@ -85,16 +86,16 @@ class ShareService extends BaseService {
uid: share_uid,
});

if ( ! share ) {
throw APIError.create('share_expired');
}

share.data = this.db.case({
mysql: () => share.data,
otherwise: () =>
JSON.parse(share.data ?? '{}'),
})();

if ( ! share ) {
throw APIError.create('share_expired');
}

const actor = Actor.adapt(req.actor ?? req.user);
if ( ! actor ) {
// this shouldn't happen; auth should catch it
Expand Down Expand Up @@ -137,6 +138,74 @@ class ShareService extends BaseService {
});
}
}).attach(router);

Endpoint({
route: '/request',
methods: ['POST'],
mw: [configurable_auth()],
handler: async (req, res) => {
const share_uid = req.body.uid;

const share = await svc_share.get_share({
uid: share_uid,
});

// track: null check before processing
if ( ! share ) {
throw APIError.create('share_expired');
}

share.data = this.db.case({
mysql: () => share.data,
otherwise: () =>
JSON.parse(share.data ?? '{}'),
})();

const actor = Actor.adapt(req.actor ?? req.user);
if ( ! actor ) {
// this shouldn't happen; auth should catch it
throw new Error('actor missing');
}

// track: opposite condition of sibling
// :: sibling: /apply endpoint
if (
actor.type.user.email_confirmed &&
actor.type.user.email === share.recipient_email
) {
throw APIError.create('no_need_to_request');
}

const issuer_user = await get_user({
id: share.issuer_user_id,
});

if ( ! issuer_user ) {
throw APIError.create('share_expired');
}

const svc_notification = this.services.get('notification');
svc_notification.notify(
UsernameNotifSelector(issuer_user.username),
{
source: 'sharing',
title: `User ${actor.type.user.username} is ` +
`trying to open a share you sent to ` +
share.recipient_email,
template: 'user-requesting-share',
fields: {
username: actor.type.user.username,
intended_recipient: share.recipient_email,
permissions: share.data.permissions,
},
}
);
res.json({
$: 'api:status-report',
status: 'success',
});
}
}).attach(router);
}

async get_share ({ uid }) {
Expand Down
5 changes: 5 additions & 0 deletions packages/backend/src/services/drivers/DriverService.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ class DriverService extends BaseService {
this.interfaces = require('./interfaces');
this.interface_to_implementation = {};
}

_init () {
const svc_registry = this.services.get('registry');
svc_registry.register_collection('');
}

register_driver (interface_name, implementation) {
this.interface_to_implementation[interface_name] = implementation;
Expand Down

0 comments on commit 742f625

Please sign in to comment.