Skip to content

Commit

Permalink
Merge pull request #18 from astrairidium/multiple-recipients
Browse files Browse the repository at this point in the history
Support multiple recipients
  • Loading branch information
fancycode authored Jan 30, 2023
2 parents 94e4863 + 4c48e56 commit d3f1d09
Show file tree
Hide file tree
Showing 26 changed files with 1,026 additions and 353 deletions.
20 changes: 10 additions & 10 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<summary><![CDATA[eSignatures]]></summary>
<description><![CDATA[eSignatures]]></description>

<version>0.0.8</version>
<version>0.0.9</version>
<license>agpl</license>

<author>Joachim Bauch</author>
Expand All @@ -27,14 +27,14 @@
<personal-section>OCA\Esig\Settings\Section</personal-section>
</settings>

<activity>
<settings>
<setting>OCA\Esig\Activity\Setting</setting>
</settings>
<activity>
<settings>
<setting>OCA\Esig\Activity\Setting</setting>
</settings>

<providers>
<provider>OCA\Esig\Activity\Provider\Share</provider>
<provider>OCA\Esig\Activity\Provider\Sign</provider>
</providers>
</activity>
<providers>
<provider>OCA\Esig\Activity\Provider\Share</provider>
<provider>OCA\Esig\Activity\Provider\Sign</provider>
</providers>
</activity>
</info>
187 changes: 96 additions & 91 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,97 +7,102 @@
];

return [
'routes' => [
[
'name' => 'Page#index',
'url' => '/',
'verb' => 'GET',
],
[
'name' => 'Page#sign',
'url' => '/sign/{id}',
'verb' => 'GET',
],
[
'name' => 'Download#downloadOriginal',
'url' => '/download/{id}',
'verb' => 'GET',
],
[
'name' => 'Download#downloadSigned',
'url' => '/download/signed/{id}',
'verb' => 'GET',
],
[
'name' => 'Download#downloadSignatureImage',
'url' => '/settings/signature',
'verb' => 'GET',
],
[
'name' => 'Download#uploadSignatureImage',
'url' => '/settings/signature',
'verb' => 'POST',
],
[
'name' => 'Download#deleteSignatureImage',
'url' => '/settings/signature',
'verb' => 'DELETE',
],
],
'routes' => [
[
'name' => 'Page#index',
'url' => '/',
'verb' => 'GET',
],
[
'name' => 'Page#sign',
'url' => '/sign/{id}',
'verb' => 'GET',
],
[
'name' => 'Download#downloadOriginal',
'url' => '/download/{id}',
'verb' => 'GET',
],
[
'name' => 'Download#downloadSource',
'url' => '/download/source/{id}',
'verb' => 'GET',
],
[
'name' => 'Download#downloadSigned',
'url' => '/download/signed/{id}',
'verb' => 'GET',
],
[
'name' => 'Download#downloadSignatureImage',
'url' => '/settings/signature',
'verb' => 'GET',
],
[
'name' => 'Download#uploadSignatureImage',
'url' => '/settings/signature',
'verb' => 'POST',
],
[
'name' => 'Download#deleteSignatureImage',
'url' => '/settings/signature',
'verb' => 'DELETE',
],
],
'ocs' => [
[
'name' => 'Api#shareFile',
'url' => '/api/{apiVersion}/share',
'verb' => 'POST',
'requirements' => $requirements,
],
[
'name' => 'Api#getRequests',
'url' => '/api/{apiVersion}/share',
'verb' => 'GET',
'requirements' => $requirements,
],
[
'name' => 'Api#getIncomingRequests',
'url' => '/api/{apiVersion}/share/incoming',
'verb' => 'GET',
'requirements' => $requirements,
],
[
'name' => 'Api#getIncomingRequest',
'url' => '/api/{apiVersion}/share/incoming/{id}',
'verb' => 'GET',
'requirements' => $requirements,
],
[
'name' => 'Api#getRequest',
'url' => '/api/{apiVersion}/share/{id}',
'verb' => 'GET',
'requirements' => $requirements,
],
[
'name' => 'Api#deleteRequest',
'url' => '/api/{apiVersion}/share/{id}',
'verb' => 'DELETE',
'requirements' => $requirements,
],
[
'name' => 'Api#signRequest',
'url' => '/api/{apiVersion}/share/{id}/sign',
'verb' => 'POST',
'requirements' => $requirements,
],
[
'name' => 'Api#getFileMetadata',
'url' => '/api/{apiVersion}/metadata/{id}',
'verb' => 'GET',
'requirements' => $requirements,
],
[
'name' => 'Api#search',
'url' => '/api/{apiVersion}/search',
'verb' => 'POST',
'requirements' => $requirements,
],
],
'name' => 'Api#shareFile',
'url' => '/api/{apiVersion}/share',
'verb' => 'POST',
'requirements' => $requirements,
],
[
'name' => 'Api#getRequests',
'url' => '/api/{apiVersion}/share',
'verb' => 'GET',
'requirements' => $requirements,
],
[
'name' => 'Api#getIncomingRequests',
'url' => '/api/{apiVersion}/share/incoming',
'verb' => 'GET',
'requirements' => $requirements,
],
[
'name' => 'Api#getIncomingRequest',
'url' => '/api/{apiVersion}/share/incoming/{id}',
'verb' => 'GET',
'requirements' => $requirements,
],
[
'name' => 'Api#getRequest',
'url' => '/api/{apiVersion}/share/{id}',
'verb' => 'GET',
'requirements' => $requirements,
],
[
'name' => 'Api#deleteRequest',
'url' => '/api/{apiVersion}/share/{id}',
'verb' => 'DELETE',
'requirements' => $requirements,
],
[
'name' => 'Api#signRequest',
'url' => '/api/{apiVersion}/share/{id}/sign',
'verb' => 'POST',
'requirements' => $requirements,
],
[
'name' => 'Api#getFileMetadata',
'url' => '/api/{apiVersion}/metadata/{id}',
'verb' => 'GET',
'requirements' => $requirements,
],
[
'name' => 'Api#search',
'url' => '/api/{apiVersion}/search',
'verb' => 'POST',
'requirements' => $requirements,
],
],
];
34 changes: 24 additions & 10 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ Nextcloud instance.
| field | type | description |
|---------------------|---------|------------------------------------------------------------------|
| `file_id` | int | The id of the file to be signed. |
| `recipient` | string | User id or email address to share the document with. |
| `recipient_type` | string | Type of recipient, can be `user` or `email`. |
| `recipients` | array | List of recipients to share the document with. |
| `options` | array | JSON options for the request. |
| `metadata` | array | JSON metadata to include in the request. |

Expand All @@ -33,6 +32,14 @@ Nextcloud instance.
| `request_id` | string | The id of the signing request. |


Each entry in the `recipients` array must contain the following fields:

| field | type | description |
|---------------------|---------|------------------------------------------------------------------|
| `type` | string | Type of recipient, can be `user` or `email`. |
| `value` | string | Userid (for type `user`) or email address (for type `email`). |


The following fields are currently defined for the request `options` JSON:

| field | type | description |
Expand All @@ -56,6 +63,10 @@ Signature fields objects must contain the keys `id` (unique id of the field),
`page` (1-based page number), `x`, `y`, `width`, `height` with values
based on the page viewport where the top left of the page is at `0` / `0`.

If signatures are requested from multiple recipients, each signature field must
contain a `recipient_idx` field with the (0-based) index of the recipient that
should sign the field.


## Get metadata of file.

Expand Down Expand Up @@ -97,14 +108,14 @@ based on the page viewport where the top left of the page is at `0` / `0`.
| `filename` | string | Filename that was shared. |
| `mimetype` | string | Mimetype of the shared file. |
| `download_url` | string | A temporary URL that can be used to download the original file. |
| `recipient` | string | User id or email address to share the document with. |
| `recipient_type` | string | Type of recipient, can be `user` or `email`. |
| `recipients` | array | List of recipients the file was shared with. |
| `metadata` | array | Optional request JSON metadata (see above). |
| `signed` | iso8601 | The timestamp when the file was signed or `null`. |
| `signed` | iso8601 | The timestamp when the file was last signed or `null`. |
| `signed_url` | string | A temporary URL that can be used to download the signed file. |

The field `signed` is only returned if `include_signed` was passed as `true` in
the request.
the request. Recipients that already signed the file will have an additional
field `signed` in their `recipients` entry.


## Get list of files requested to by signed by current user
Expand Down Expand Up @@ -133,7 +144,7 @@ the request.
| `mimetype` | string | Mimetype of the shared file. |
| `download_url` | string | A temporary URL that can be used to download the original file. |
| `metadata` | array | Optional request JSON metadata (see above). |
| `signed` | iso8601 | The timestamp when the file was signed or `null`. |
| `signed` | iso8601 | The timestamp when the file was signed (if already signed). |
| `signed_url` | string | A temporary URL that can be used to download the signed file. |

The field `signed` is only returned if `include_signed` was passed as `true` in
Expand Down Expand Up @@ -169,12 +180,14 @@ the request.
| `filename` | string | Filename that was shared. |
| `mimetype` | string | Mimetype of the shared file. |
| `download_url` | string | A temporary URL that can be used to download the original file. |
| `recipient` | string | User id or email address to share the document with. |
| `recipient_type` | string | Type of recipient, can be `user` or `email`. |
| `recipients` | array | List of recipients the file was shared with. |
| `metadata` | array | Optional request JSON metadata (see above). |
| `signed` | iso8601 | The timestamp when the file was signed (if already signed). |
| `signed` | iso8601 | The timestamp when the file was last signed (if already signed). |
| `signed_url` | string | A temporary URL that can be used to download the signed file. |

Recipients that already signed the file will have an additional field `signed`
in their `recipients` entry.


## Get details on file shared for signing

Expand Down Expand Up @@ -235,6 +248,7 @@ The following fields are currently defined for the `options` JSON:

| field | type | description |
|------------------------|---------|------------------------------------------------------------------|
| `email` | string | Email address if signing as anonymous user. |
| `embed_user_signature` | bool | Embed the personal signature image in all fields. |


Expand Down
1 change: 1 addition & 0 deletions docs/capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ title: Capabilities
---

## 1.0
* `multiple-recipients` - Requesting signatures from multiple recipients is supported.
* `config => requests => signed-save-mode` - Default action for signed results.
* `config => user => has-signature-image` - Has the user uploaded a signature image?
32 changes: 17 additions & 15 deletions lib/Activity/Listener.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ public function __construct(IManager $activityManager,

public static function register(IEventDispatcher $dispatcher): void {
$listener = static function (ShareEvent $event): void {
if ($event->getRecipientType() !== 'user') {
// Only generate activities for users.
return;
}

$listener = Server::get(self::class);
$listener->onShareEvent($event);
};
Expand Down Expand Up @@ -84,13 +79,20 @@ public function onShareEvent(ShareEvent $event): bool {
return false;
}

try {
$activity->setAffectedUser($event->getRecipient());
$this->activityManager->publish($activity);
} catch (\BadMethodCallException $e) {
$this->logger->error($e->getMessage(), ['exception' => $e]);
} catch (\InvalidArgumentException $e) {
$this->logger->error($e->getMessage(), ['exception' => $e]);
foreach ($event->getRecipients() as $recipient) {
$type = $recipient['type'];
if ($type !== 'user') {
continue;
}

try {
$activity->setAffectedUser($recipient['value']);
$this->activityManager->publish($activity);
} catch (\BadMethodCallException $e) {
$this->logger->error($e->getMessage(), ['exception' => $e]);
} catch (\InvalidArgumentException $e) {
$this->logger->error($e->getMessage(), ['exception' => $e]);
}
}

return true;
Expand All @@ -99,7 +101,7 @@ public function onShareEvent(ShareEvent $event): bool {
/**
* The file "{filename}" was signed by {user}"
*
* @param ShareEvent $event
* @param SignEvent $event
* @return bool True if activity was generated, false otherwise
*/
public function onSignEvent(SignEvent $event): bool {
Expand All @@ -116,8 +118,8 @@ public function onSignEvent(SignEvent $event): bool {
->setSubject('sign', [
'file_id' => $request['file_id'],
'filename' => $request['filename'],
'recipient' => $request['recipient'],
'recipient_type' => $request['recipient_type'],
'recipient' => $event->getRecipient(),
'recipient_type' => $event->getRecipientType(),
'request_id' => $id,
]);
} catch (\InvalidArgumentException $e) {
Expand Down
1 change: 1 addition & 0 deletions lib/Capabilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public function getCapabilities(): array {

$capabilities = [
'features' => [
'multiple-recipients',
],
'config' => [
'requests' => [
Expand Down
Loading

0 comments on commit d3f1d09

Please sign in to comment.