diff --git a/packages/component-invite/README.md b/packages/component-invite/README.md index fcc89449e6ada94cfa3c2db93293996cacfe8ad8..a4f9beb8ff5ee72503ba15d96f05821b956da668 100644 --- a/packages/component-invite/README.md +++ b/packages/component-invite/README.md @@ -1,149 +1,154 @@ # Invite Component -## Configuration +### Invite a User to a Collection [POST] -In order to use this component, the following configuration needs to be added to a PubSweet application, like so: +This endpoint allows creates a new User, linking it to a Collection through a Team. -```json - { - 'invite-reset-password': { - url: 'http://localhost:3000/invite', - }, - roles: { - global: ['admin', 'editorInChief', 'author'], - collection: ['handlingEditor', 'reviewer'], - inviteRights: { - admin: ['admin', 'editorInChief', 'author'], - editorInChief: ['handlingEditor'], - handlingEditor: ['reviewer'], - }, - }, -``` - -## Usage - -Here's the list of endpoints that'll help you invite new users in your Pubsweet app. +#### Invite User Request -### Upload a file [POST] +`POST /api/collections/:collectionId/invitations` -This endpoint allows you to create a new user in your app and then send him a confirmation email. - -#### Invite request - -`POST /api/users/invite/{collectionId}` | URI Parameter | Requiered | Requirements | Description | | ------------- | --------- | ------------ | ------------------ | | collectionId | No | String | The ID of the collection | -#### Invite request body +#### Invite User Request Body ```json { - "email": "new_user@domain.com" /* required */, - "role": "editorInChief" /* required */, - "firstName": "Marc", - "lastName": "Twain", - "title": "Prof", - "affiliation": "MIT" + "email": "email@example.com", + "role": "handlingEditor", [acceptedValues: handlingEditor, reviewer] } ``` -#### Invite user response +#### Invite User Response -```json -HTTP/1.1 200 +```javascript +HTTP/1.1 200 OK { - "id": "37463722-c4ca-4e3c-acec-779df8c11ad2", - "username": "9a42b55f", - "email": "new_user@domain.com", - "roles": ["editorInChief"], - "passwordResetToken": "123", - "isConfirmed": false, - "firstName": "Marc", - "lastName": "Twain", - "affiliation": "MIT", - "title": "Prof", - "admin": false, - "type": "user", - "rev": "1-12ebbb6686614791bb08ead305cde4f8" -} + "id": "7b2431af-210c-49f9-a69a-e19271066ebd", + "role": "handlingEditor", + "userId": "4c3f8ee1-785b-4adb-87b4-407a27f652c6", + "hasAnswer": false, + "invitedOn": 1525428890167, + "isAccepted": false, + "respondedOn": null + } ``` --- -### Retrieve invited user details [GET] +### Get Invitations [GET] -This endpoint allows you to retrieve an invited users' details so that you can display them in the confirmation form. +This endpoint allows you to get a list of invitations based on role. -#### User details request +#### Get Invitations Request -`GET /api/users/invite?email=new_user@domain.com&token=123` +`GET /api/collections/:collectionId/invitations/:invitationId?role=:role` | Query Parameter | Requiered | Requirements | Description | | --------------- | --------- | ------------ | ------------------------ | -| email | Yes | String | The user's email | -| token | Yes | String | The password reset token | +| collectionId | Yes | String | Collection ID | +| invitationId | No | String | Invitation ID | +| role | Yes | String | The role to search for: handlingEditor, reviewer, author | -#### User details response +#### Get Invitations Response -```json -HTTP/1.1 200 -{ - "firstName": "dsadasd", - "lastName": "fisdadasdasdaasdago", - "affiliation": "asdasasae23", - "title": "131sdadassa" -} +```javascript +HTTP/1.1 200 OK +[ + { + "name": "John Smith", + "invitedOn": 1525428890167, + "respondedOn": 1525428890299, + "email": "email@example.com", + "status": "pending", + "invitationId": "1990881" + } +] ``` --- +### Accept or Decline an Invitation [PATCH] -### Reset password [POST] +This endpoint allows you to accept or to decline an invitation. -This endpoint will reset a user's password and confirm his account. +#### Accept/Decline Request -#### Reset password request +`PATCH /api/collections/:collectionId/invitations/:invitationId` -`POST /api/users/invite/password/reset` +| URI Parameter | Requiered | Requirements | Description | +| --------------- | --------- | ------------ | ------------------------ | +| collectionId | Yes | String | Collection ID | +| invitationId | Yes | String | Invitation ID | -#### Reset password request body +#### Accept/Decline Body ```json -// All fields are required { - "email": "new_user@domain.com", - "token": "123", - "firstName": "Marc", - "lastName": "Twain", - "title": "Prof", - "affiliation": "MIT", - "password": "verySecure" + "isAccepted": false/true, + "reason": "I am not ready" [optional] } ``` -#### Response +#### Accept/Decline Response + +```javascript +HTTP/1.1 200 OK +{ + "id": "7b2431af-210c-49f9-a69a-e19271066ebd", + "role": "reviewer", + "userId": "4c3f8ee1-785b-4adb-87b4-407a27f652c6", + "hasAnswer": true, + "invitedOn": 1525428890167, + "isAccepted": false, + "respondedOn": 1525428890299 +} +``` +--- +### Decline an Invitation Unauthenticated [PATCH] + +This endpoint allows you to decline an invitation without authenticating. + +#### Decline Request + +`PATCH /api/collections/:collectionId/invitations/:invitationId/decline` + +| URI Parameter | Requiered | Requirements | Description | +| --------------- | --------- | ------------ | ------------------------ | +| collectionId | Yes | String | Collection ID | +| invitationId | Yes | String | Invitation ID | + +#### Decline Body ```json -HTTP/1.1 200 { - "id": "37463722-c4ca-4e3c-acec-779df8c11ad2", - "username": "9a42b55f", - "email": "new_user@domain.com", - "isConfirmed": true, - "firstName": "Marc", - "lastName": "Twain", - "affiliation": "MIT", - "title": "Prof", - "admin": false, - "type": "user", - "roles": [ - "editorInChief" - ], - "collections": [], - "fragments": [], - "teams": [], - "rev": "2-81fb76ae72f143bb9edc2b4d4deaf7a3" + "invitationToken": "f2d814f0-67a5-4590-ba4f-6a83565feb4f" } ``` +#### Decline Response + +```javascript +HTTP/1.1 200 OK +{} +``` --- +### Delete Invitation [DELETE] + +This endpoint allows you to delete an invitation. + +#### Delete Invitation Request + +`DELETE /api/collections/:collectionId/invitations/:invitationId` + +| Query Parameter | Requiered | Requirements | Description | +| --------------- | --------- | ------------ | ------------------------ | +| collectionId | Yes | String | Collection ID | +| invitationId | Yes | String | Invitation ID | + +#### Delete Invitation Response + +```javascript +HTTP/1.1 204 No Content +``` \ No newline at end of file diff --git a/packages/component-invite/src/helpers/User.js b/packages/component-invite/src/helpers/User.js index d64a9d9a9f9f29ccf7059d5fbb097eb12cc8e6ef..e36c2f90c278d5e248d0d9c30e68f1f8514497b3 100644 --- a/packages/component-invite/src/helpers/User.js +++ b/packages/component-invite/src/helpers/User.js @@ -80,17 +80,18 @@ const setupReviewerDecisionEmailData = async ({ timestamp, }, }) - await mailService.sendNotificationEmail({ - toEmail: user.email, - user, - emailType: 'reviewer-thank-you', - meta: { - collection: { customId: collection.customId, id: collection.id }, - fragment: { id, title, authorName }, - handlingEditorName: collection.handlingEditor.name, - baseUrl, - }, - }) + if (agree) + await mailService.sendNotificationEmail({ + toEmail: user.email, + user, + emailType: 'reviewer-thank-you', + meta: { + collection: { customId: collection.customId, id: collection.id }, + fragment: { id, title, authorName }, + handlingEditorName: collection.handlingEditor.name, + baseUrl, + }, + }) } const setupReviewerUnassignEmail = async ({