Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[front] - feat(connections): datasource request flow #6684

Merged
merged 20 commits into from
Aug 8, 2024

Conversation

JulesBelveze
Copy link
Contributor

@JulesBelveze JulesBelveze commented Aug 6, 2024

Description

This PR implements a new data source request flow, introducing a RequestDataSourcesModal component.

The main changes include:

  • A new RequestDataSourcesModal component that allows users to request access to data sources they don't currently have permissions for.
  • Enhancement of the sendEmail function to support cc recipients, enabling the inclusion of data source administrators in request emails.
  • A new backend endpoint
  • Integration of the new request flow in the data sources management page.
  • Updates to the data source selection UI in the assistant builder to accommodate the new request flow.

New look:

Screenshot 2024-08-06 at 12 02 17 Screenshot 2024-08-06 at 12 02 28

References:

Risk

Breaking UX changes

Deploy Plan

  • Deploy tofront-edge
  • Deploy front

@JulesBelveze JulesBelveze marked this pull request as draft August 6, 2024 13:40
@JulesBelveze JulesBelveze marked this pull request as ready for review August 6, 2024 14:50
emailRequester?: string;
owner: WorkspaceType;
}) {
const res = await fetch(`/api/w/${owner.sId}/data_sources/request-email`, {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's simply do request-access as it might not be an email anymore in the future.

});
}

const { email, emailMessage, emailRequester, dataSourceName } = req.body;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use io-ts here.

res: NextApiResponse,
auth: Authenticator
) {
const owner = auth.getNonNullableWorkspace();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't use nonNullableWorkspace because it throws an error. Here we want to 404 if workspace is null

const owner = auth.getNonNullableWorkspace();
const user = auth.user();

if (!user || !owner) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You already check it here, so as simple as changing to .workspace

@@ -112,6 +116,16 @@ type GetTableRowParams = {
setShowPreviewPopupForProvider: (provider: ConnectorProvider | null) => void;
};

type ManagedConnector = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

naming is weird to me, since connector is always managed

import type { PostRequestAccessBody } from "@app/pages/api/w/[wId]/data_sources/request-access";
import type { DataSourceIntegration } from "@app/pages/w/[wId]/builder/data-sources/managed";

type RequestDataSourceProps = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit

Suggested change
type RequestDataSourceProps = {
interface RequestDataSourceProps {

export const PostRequestAccessBodySchema = t.type({
email: t.string,
emailMessage: t.string,
emailRequester: t.string,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we expose this endpoint behind /data_sources/[name]/request-access so we can infer here the email address of the owner of the data source/data source view?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think leaving it here would enable us to have a general request-access endpoint. There could be a world in which users ask to an admin to set up a new connector 🤷🏼‍♂️

@@ -0,0 +1,96 @@
import { isLeft } from "fp-ts/Either";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit but given that we do data_source we should do request_access.

const owner = auth.workspace();
const user = auth.user();

if (!user || !owner) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to check for auth.isUser() to ensure that the user has access to the workspace.

subject: `[Dust] Request Data source from ${emailRequester}`,
html: sanitizeHtml(html),
};
await sendEmail(email, message);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use sendgrid templates here. Happy to hope on a call to show you.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seen IRL.

email: userEmail,
emailMessage: message,
dataSourceName: selectedDataSourceIntegration.name,
emailRequester: currentUserEmail,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO we should infer this in the endpoint using the auth.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Comment on lines 89 to 93
dynamic_template_data: {
subject: `[Dust] Request Data source from ${emailRequester}`,
body,
},
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could have a small helper like sendEmailWithTemplate() that abstract the dynamic_template_data that returns a result so we don't need a try/catch block in the endpoint.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Copy link
Contributor

@flvndvd flvndvd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Outside of the two last nits

Comment on lines 25 to 30
async function sendEmailWithTemplate(
to: string,
from: { name: string; email: string },
subject: string,
body: string
): Promise<Result<void, Error>> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we only deal with native types for params we should try to use object instead.

typeof PostRequestAccessBodySchema
>;

async function sendEmailWithTemplate(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move this to front/lib/email.ts so we can re-use it 😛


export const PostRequestAccessBodySchema = t.type({
emailMessage: t.string,
email: t.string,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading this one more time, we should make sure to include the user's sId here instead of email. This way, we can prevent any misuse of the endpoint, like sending emails to random addresses. Just a little extra precaution to keep things secure!

Jules and others added 17 commits August 8, 2024 09:49
 - Include the email address of the user who last edited a data source for better tracking

[front] - feature: introduce RequestDataSourcesModal component

 - Implement a new modal allowing non-admin users to request new data sources
 - Add a button to open the RequestDataSourcesModal in the data sources view
 - Adjust managed connectors to include the full EditedByUser object

[types] - refactor: update EditedByUser type to include email field

 - Enhance the EditedByUser type with an optional email field for additional user context
…tion

 - Implement a new modal interface for users to request integration with a specific data source
 - Add functionality to send an email to the responsible administrator, detailing the integration request
 - Include appropriate form elements for message composition and data source selection
…nality for data sources

 - Add a new POST API endpoint to handle email requests for data source connections
 - Ensure input validation and sanitation for email-related fields before sending the email
… requests

 - Replace direct sendEmail call with API endpoint for sending request data source emails
 - Include WorkspaceType owner in the email sending payload to scope the request properly
 - Change parameter names to better reflect their purpose in the email sending context
 - Improve error handling for the email sending process by checking response status and providing error messages
 - Pass owner information when opening RequestDataSourcesModal for proper email request scoping
 - Changed the API endpoint to better reflect the action of requesting access rather than sending an email
 - Renamed the file to match the updated API endpoint path for consistency
…request-access

 - Change the method used to fetch a non-nullable workspace to a more generic workspace fetching method

[pages/w/[wId]/builder/data-sources] - refactor: rename ManagedConnector to ManagedSourceType

 - Standardize terminology by renaming ManagedConnector type to ManagedSourceType
 - Adjust variables and mappings to reflect new ManagedSourceType name throughout data-sources managed page
…ludes requester info

 - Modify sendRequestDataSourceEmail function to guarantee emailRequester is always passed as a non-optional string
 - Implement type validation using io-ts for request access API endpoint to enhance data integrity
…PI endpoint

 - Change RequestDataSourceProps from type to interface for consistency
 - Correct the API endpoint for sending data source requests to use underscore

[data_source] - fix: restrict data source request to workspace users

 - Add check to ensure only authenticated workspace users can send data source request emails
…te ID

 - Provide a method to fetch `SENDGRID_GENERIC_EMAIL_TEMPLATE_ID` from environment variables

[api/data_sources/request_access] - refactor: use dynamic template for sending request access emails

 - Replace inline email HTML with SendGrid dynamic template for better maintenance and consistency
 - Include `subject` and sanitized `body` in the dynamic template data for the email
 - Remove unused import of `sanitize_html` as sanitization is now handled by the template system
 - Simplified the email body format for data source access requests by removing HTML tags and fixing a typo
…emplate function

 - Extract the email sending logic into a dedicated `sendEmailWithTemplate` function
 - Employ `Result` type from `@dust-tt/types` for error handling in the new function
 - Replace direct email sending with the new function in the request access handler
 - Add logging for both successful and failed email sending attempts within the new function
…st access function

 - The email parameter for sendRequestDataSourceEmail is no longer required and has been removed
 - The email is now directly obtained from the user object within the API handler logic
 - Remove `currentUserEmail` param and use `userEmail` consistently for request access
 - Update `sendRequestDataSourceEmail` function to accept a single email parameter
 - Adjust API handler to reflect parameter changes for clarity and consistency
 - Ensure that email sender is correctly assigned in the request access email logic
…e templates

 - Added a new function to support sending emails using templates from configuration
 - Moved `sendEmailWithTemplate` function to the centralized email module for reusability

[front/pages/api/w/[wId]/data_sources/request_access] - refactor: update request access to use centralized email sending function

 - Replaced the local `sendEmailWithTemplate` implementation with the one from the `email` module
 - Cleaned up the imports and dependencies related to email sending to use the new function
…ntifier to user ID

 - Replace email with userId to identify the recipient of data source request emails
 - Modify sendRequestDataSourceEmail and RequestDataSourcesModal to work with userId instead of userEmail

[front/lib/email] - refactor: structure sendEmailWithTemplate function to use params object

 - Refactor sendEmailWithTemplate to take an object with named properties as parameters for better readability

[front/lib/resources] - feature: add userId to DataSource editor details

 - Extend EditedByUser type to include userId property in data source information

[front/pages/api] - fix: ensure user existence before sending email

 - Check whether the recipient user exists and return a 404 error if not found when requesting data source access
 - Pass structured object to sendEmailWithTemplate for clarity and consistency

[types] - feature: introduce userId property to EditedByUser type

 - Add userId property to EditedByUser type to support user identification changes in front-end components
Jules added 2 commits August 8, 2024 11:18
…fication logic

 - Move success notification inside try block to ensure it only displays after email is sent
 - Add error notification to catch block to alert user when email sending fails
 - Include the error details in logging for better error tracking

[front/pages/api/w/[wId]/data_sources] - feature: implement rate limiting for access requests

 - Add rate limiter to restrict users to a maximum number of access requests per day
 - Return a 429 error when the rate limit is reached, indicating the user should try again tomorrow
 - Fix typo in email body content for clarity in access request emails
 - Daily access request limit per user has been updated from 1 to 30
Copy link
Contributor

@flvndvd flvndvd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, left one last comment but feel free to merge afterward.

body: string;
};

export async function sendEmailWithTemplate({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥 🙏

}

const rateLimitKey = `access_requests:${user.sId}`;
const remaining = await rateLimiter({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably do this once we know that the body is good and that the userTo exist. Otherwise, what might happen is that we will remove access request availability even though it did not work.

 - Relocated rate limiting code to perform the check after initial request body validation
 - Ensures body validation is prioritized before rate limiting logic is applied
@JulesBelveze JulesBelveze merged commit b8166ef into main Aug 8, 2024
3 checks passed
@JulesBelveze JulesBelveze deleted the feat/datasource-request-flow branch August 8, 2024 11:55
albandum pushed a commit that referenced this pull request Aug 28, 2024
* [front] - feature: add user email to data source edit history

 - Include the email address of the user who last edited a data source for better tracking

[front] - feature: introduce RequestDataSourcesModal component

 - Implement a new modal allowing non-admin users to request new data sources
 - Add a button to open the RequestDataSourcesModal in the data sources view
 - Adjust managed connectors to include the full EditedByUser object

[types] - refactor: update EditedByUser type to include email field

 - Enhance the EditedByUser type with an optional email field for additional user context

* [data_source] - feature: add modal for requesting data source integration

 - Implement a new modal interface for users to request integration with a specific data source
 - Add functionality to send an email to the responsible administrator, detailing the integration request
 - Include appropriate form elements for message composition and data source selection

* [api/w/[wId]/data_sources] - feature: implement email request functionality for data sources

 - Add a new POST API endpoint to handle email requests for data source connections
 - Ensure input validation and sanitation for email-related fields before sending the email

* [data_source] - refactor: update email sending method for data source requests

 - Replace direct sendEmail call with API endpoint for sending request data source emails
 - Include WorkspaceType owner in the email sending payload to scope the request properly
 - Change parameter names to better reflect their purpose in the email sending context
 - Improve error handling for the email sending process by checking response status and providing error messages
 - Pass owner information when opening RequestDataSourcesModal for proper email request scoping

* [data_source] - refactor: update endpoint for data source access request

 - Changed the API endpoint to better reflect the action of requesting access rather than sending an email
 - Renamed the file to match the updated API endpoint path for consistency

* [api/wId/data_sources] - refactor: update method to get workspace in request-access

 - Change the method used to fetch a non-nullable workspace to a more generic workspace fetching method

[pages/w/[wId]/builder/data-sources] - refactor: rename ManagedConnector to ManagedSourceType

 - Standardize terminology by renaming ManagedConnector type to ManagedSourceType
 - Adjust variables and mappings to reflect new ManagedSourceType name throughout data-sources managed page

* [front/components/data_source] - fix: ensure request access email includes requester info

 - Modify sendRequestDataSourceEmail function to guarantee emailRequester is always passed as a non-optional string
 - Implement type validation using io-ts for request access API endpoint to enhance data integrity

* fix: lint/format

* [data_source] - refactor: update RequestDataSourcesModal typing and API endpoint

 - Change RequestDataSourceProps from type to interface for consistency
 - Correct the API endpoint for sending data source requests to use underscore

[data_source] - fix: restrict data source request to workspace users

 - Add check to ensure only authenticated workspace users can send data source request emails

* [api/config] - feature: add function to retrieve generic email template ID

 - Provide a method to fetch `SENDGRID_GENERIC_EMAIL_TEMPLATE_ID` from environment variables

[api/data_sources/request_access] - refactor: use dynamic template for sending request access emails

 - Replace inline email HTML with SendGrid dynamic template for better maintenance and consistency
 - Include `subject` and sanitized `body` in the dynamic template data for the email
 - Remove unused import of `sanitize_html` as sanitization is now handled by the template system

* [front] - fix: streamline email notification format

 - Simplified the email body format for data source access requests by removing HTML tags and fixing a typo

* [api/w/[wId]/data_sources] - refactor: implement email sending with template function

 - Extract the email sending logic into a dedicated `sendEmailWithTemplate` function
 - Employ `Result` type from `@dust-tt/types` for error handling in the new function
 - Replace direct email sending with the new function in the request access handler
 - Add logging for both successful and failed email sending attempts within the new function

* [data_source] - refactor: remove redundant email parameter from request access function

 - The email parameter for sendRequestDataSourceEmail is no longer required and has been removed
 - The email is now directly obtained from the user object within the API handler logic

* [data_source] - refactor: streamline request access email parameters

 - Remove `currentUserEmail` param and use `userEmail` consistently for request access
 - Update `sendRequestDataSourceEmail` function to accept a single email parameter
 - Adjust API handler to reflect parameter changes for clarity and consistency
 - Ensure that email sender is correctly assigned in the request access email logic

* [front/lib/email] - feature: implement email sending with configurable templates

 - Added a new function to support sending emails using templates from configuration
 - Moved `sendEmailWithTemplate` function to the centralized email module for reusability

[front/pages/api/w/[wId]/data_sources/request_access] - refactor: update request access to use centralized email sending function

 - Replaced the local `sendEmailWithTemplate` implementation with the one from the `email` module
 - Cleaned up the imports and dependencies related to email sending to use the new function

* [front/components/data_source] - refactor: change email recipient identifier to user ID

 - Replace email with userId to identify the recipient of data source request emails
 - Modify sendRequestDataSourceEmail and RequestDataSourcesModal to work with userId instead of userEmail

[front/lib/email] - refactor: structure sendEmailWithTemplate function to use params object

 - Refactor sendEmailWithTemplate to take an object with named properties as parameters for better readability

[front/lib/resources] - feature: add userId to DataSource editor details

 - Extend EditedByUser type to include userId property in data source information

[front/pages/api] - fix: ensure user existence before sending email

 - Check whether the recipient user exists and return a 404 error if not found when requesting data source access
 - Pass structured object to sendEmailWithTemplate for clarity and consistency

[types] - feature: introduce userId property to EditedByUser type

 - Add userId property to EditedByUser type to support user identification changes in front-end components

* fix: lint/format

* [front/components/data_source] - refactor: improve email request notification logic

 - Move success notification inside try block to ensure it only displays after email is sent
 - Add error notification to catch block to alert user when email sending fails
 - Include the error details in logging for better error tracking

[front/pages/api/w/[wId]/data_sources] - feature: implement rate limiting for access requests

 - Add rate limiter to restrict users to a maximum number of access requests per day
 - Return a 429 error when the rate limit is reached, indicating the user should try again tomorrow
 - Fix typo in email body content for clarity in access request emails

* [api] - feature: increase daily limit for access requests

 - Daily access request limit per user has been updated from 1 to 30

* [front] - refactor: move rate limiter logic in request_access

 - Relocated rate limiting code to perform the check after initial request body validation
 - Ensures body validation is prioritized before rate limiting logic is applied

---------

Co-authored-by: Jules <jules@MacBook-Pro.local>
Co-authored-by: Jules <jules@MacBook-Pro.lan>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants