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

feat(trusted-domain): add frontend management (without ui) #10337

Merged

Conversation

AMoreaux
Copy link
Contributor

No description provided.

Introduce functionality for managing trusted email domains in workspace settings. Includes UI components, validation schemas, GraphQL mutations, and queries to support adding, viewing, and deleting trusted domains. Also updates dependencies and adjusts existing components for better integration.
Introduce functionality for managing trusted email domains in workspace settings. Includes UI components, validation schemas, GraphQL mutations, and queries to support adding, viewing, and deleting trusted domains. Also updates dependencies and adjusts existing components for better integration.
…sted-domains

# Conflicts:
#	packages/twenty-server/src/engine/core-modules/workspace-trusted-domain/dtos/send-trusted-domain-verification-email.input.ts
#	packages/twenty-server/src/engine/core-modules/workspace-trusted-domain/workspace-trusted-domain.resolver.ts
Removed the concept of trusted domain email verification, streamlining the process for managing trusted domains. Adjusted the corresponding UI, server-side logic, and GraphQL types to reflect the updated approach, reducing complexity and unused functionality.
Changed the delete method to use trustedDomain.id instead of the entire trustedDomain object. This ensures the correct data is passed to the repository and avoids potential errors.
Introduce a hook to validate trusted domains using a validation token. This sets up the foundation for handling domain validation in the security settings module.
Introduced a mutation to validate trusted domains using Apollo Client and removed the previous hook-based implementation. Added a new component to handle validation side effects and integrated it into the trusted domains list. This enhances reliability and provides user feedback for validation success or failure.
@AMoreaux AMoreaux self-assigned this Feb 19, 2025
…sted-domains

# Conflicts:
#	packages/twenty-front/src/generated/graphql.tsx
Introduce mutations and queries to create, delete, and validate Workspace Trusted Domains. This includes input types, output types, and Apollo hooks for managing trusted domains in the workspace context.
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

This PR adds frontend management for trusted domains in the workspace security settings. Here's a concise summary of the key changes:

  • Added new GraphQL mutations and queries for managing trusted domains (create, delete, validate, fetch) with proper TypeScript types and Apollo Client hooks
  • Implemented domain validation schema using Zod with RFC-compliant regex for domain names and proper error messages
  • Created new components for trusted domain management including list view, validation effects, and dropdown menus under the security settings
  • Added new routes in SettingsRoutes.tsx for trusted domain management (new/edit) with lazy loading
  • Integrated trusted domain management UI into the security settings page alongside existing SSO and authentication options

Key points to review:

  • Mutation name mismatch between frontend (CreateWorkspaceTrustDomain) and backend (createWorkspaceTrustedDomain) needs to be fixed
  • Consider adding loading states and better error handling in trusted domain components
  • Verify validation token security measures in the domain validation flow
  • Review state management approach using Recoil for trusted domains list
  • Ensure proper cleanup of URL parameters after domain validation

28 file(s) reviewed, 20 comment(s)
Edit PR Review Bot Settings | Greptile

Comment on lines 419 to 426
<Route
path={SettingsPath.EditTrustedDomain}
element={<SettingsSecurityTrustedDomain />}
/>
<Route
path={SettingsPath.NewTrustedDomain}
element={<SettingsSecurityTrustedDomain />}
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Consider adding a SettingsProtectedRouteWrapper for trusted domain routes to ensure proper access control, similar to other sensitive settings routes

import { gql } from '@apollo/client';

export const CREATE_WORKSPACE_TRUSTED_DOMAIN = gql`
mutation CreateWorkspaceTrustDomain($input: CreateTrustedDomainInput!) {
Copy link
Contributor

Choose a reason for hiding this comment

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

syntax: Mutation name 'CreateWorkspaceTrustDomain' should be 'CreateWorkspaceTrustedDomain' to match the resolver name

Suggested change
mutation CreateWorkspaceTrustDomain($input: CreateTrustedDomainInput!) {
mutation CreateWorkspaceTrustedDomain($input: CreateTrustedDomainInput!) {

Comment on lines 30 to 34
onError: () => {
enqueueSnackBar('Error validating trusted domain', {
variant: SnackBarVariant.Error,
});
},
Copy link
Contributor

Choose a reason for hiding this comment

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

style: error handler doesn't display the actual error message from the server, which could help users understand what went wrong

Comment on lines 39 to 60
const handleDeleteWorkspaceTrustedDomain = async () => {
const result = await deleteWorkspaceTrustDomain({
variables: {
input: {
id: workspaceTrustedDomain.id,
},
},
onCompleted: () => {
setWorkspaceTrustedDomains((workspaceTrustedDomains) => {
return workspaceTrustedDomains.filter(
(trustedDomain) => trustedDomain.id !== workspaceTrustedDomain.id,
);
});
},
});
if (isDefined(result.errors)) {
enqueueSnackBar('Error deleting workspace trust domain', {
variant: SnackBarVariant.Error,
duration: 2000,
});
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: state update in onCompleted runs even if there are errors, and error handling only shows generic message without actual error details from result.errors

<Section>
<H2Title
title="Email verification"
description="We will send your a link to verify domain ownership"
Copy link
Contributor

Choose a reason for hiding this comment

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

syntax: Typo in description text: 'your' should be 'you'

Suggested change
description="We will send your a link to verify domain ownership"
description="We will send you a link to verify domain ownership"

z
.object({
domain: domainSchema,
email: z.string().min(1),
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: Email validation is too permissive - should use email format validation instead of just min length

Suggested change
email: z.string().min(1),
email: z.string().email(),

Comment on lines 51 to 55
email:
formConfig.getValues('email') +
'@' +
formConfig.getValues('domain'),
},
Copy link
Contributor

Choose a reason for hiding this comment

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

style: String concatenation for email is error-prone - consider using template literals

Comment on lines 45 to 74
const handleSave = async () => {
try {
createWorkspaceTrustDomain({
variables: {
input: {
domain: formConfig.getValues('domain'),
email:
formConfig.getValues('email') +
'@' +
formConfig.getValues('domain'),
},
},
onCompleted: () => {
enqueueSnackBar(t`Domain added successfully.`, {
variant: SnackBarVariant.Success,
});
navigate(SettingsPath.Security);
},
onError: (error) => {
enqueueSnackBar((error as Error).message, {
variant: SnackBarVariant.Error,
});
},
});
} catch (error) {
enqueueSnackBar((error as Error).message, {
variant: SnackBarVariant.Error,
});
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Double error handling with try-catch and onError callback is redundant - the mutation's onError is sufficient

etiennejouan and others added 9 commits February 20, 2025 12:20
# Introduction
Encountered in issue in production where we have a lot of records that
has RICH_TEXT_FIELD set to `{}`

```sh
[Nest] 20106  - 02/19/2025, 12:43:08 PM     LOG [MigrateRichTextFieldCommand] Generating markdown for 1 records
[Nest] 20106  - 02/19/2025, 12:43:09 PM     LOG [MigrateRichTextFieldCommand] Error in workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db: TypeError: o is not iterable
```

## Fix
While reading `fieldValue` definition also strictly check if it's `{}` +
checking after JSON parse if it's an iterable to pass to the
`serverBlockNoteEditor` in order to be 100 bullet proof for prod
migration command

## Refactor Dry run
Implemented dry run

## Refactor to Idempotency
Made the script idempotent in order to avoid issues with re-running
commands

## Error repro
- In local checkout on v0.41.5 run `yarn && npx nx reset && npx nx
start`
- Create record manually in db that has a RICH_TEXT body to `{}`
- Checkout to main, `yarn && npx nx reset && npx nx build twenty-server
&& yarn command:prod upgrade-0.42:migrate-rich-text-field -d`
Changed mutation to return the validated domain instead of a boolean, streamlined domain validation logic, and clarified error messages. Removed redundant utility function and adjusted email template for better user guidance. These changes enhance clarity, reduce complexity, and improve user feedback when validating trusted domains.
Removed redundant tests for checkIsVerified functionality to simplify the test suite. Updated createTrustedDomain tests to reflect changes in domain validation logic and naming conventions. This improves maintainability and aligns with updated business logic.
…main

Replaced all instances of WorkspaceTrustedDomain with ApprovedAccessDomain across the application. Updated related entities, migrations, services, resolvers, and schemas to reflect the new naming convention, improving clarity and alignment with domain naming standards.
Renamed "TrustedDomain" to "ApprovedAccessDomain" for better clarity and consistency. Updated related types, inputs, and mutations accordingly to reflect the new naming convention. Removed redundant exports and adjusted queries and mutations to align with the changes.
…ins"

Updated all occurrences of "Trusted Domains" to "Approved Access Domains" across the application for clarity and consistency. This includes state variables, components, GraphQL queries/mutations, and UI labels.
…sted-domains

# Conflicts:
#	packages/twenty-server/src/engine/core-modules/approved-access-domain/services/approved-access-domain.service.ts
#	packages/twenty-server/src/engine/core-modules/workspace-trusted-domain/services/workspace-trusted-domain.service.ts
#	packages/twenty-server/src/engine/core-modules/workspace-trusted-domain/workspace-trusted-domain.resolver.ts
Removed unused "Domain" and "Email" labels from TextInput components. This cleanup reduces unnecessary props and improves code readability.
The domain validation schema is now defined inline where used instead of being imported from a separate file. This simplifies the codebase by removing unnecessary indirection and eliminating the domainSchema file altogether.
Changed the form validation mode from onChange to onSubmit for better user experience and to align with existing submission patterns. Updated the save button handler to use the form's submit handler to ensure proper data validation before saving.
Removed @lingui/macro and related 5.2.0 versions from dependencies and yarn.lock. This cleanup ensures only necessary Lingui packages are retained, aligning with the used 5.1.2 versions.
Corrected the generated dropdown ID to use a more descriptive naming convention for approved access domains. This prevents potential confusion and improves code readability. No functional behavior is affected by this change.

export const GET_ALL_APPROVED_ACCESS_DOMAINS = gql`
query GetAllApprovedAccessDomains {
getAllApprovedAccessDomains {
Copy link
Member

Choose a reason for hiding this comment

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

I don't think GetAll is a common naming pattern. getApprovedAccessDomains ? (we even should probably have do just ApprovedAccessDomains but that's not the case in many cases so up to you between the two... indexMetadatas, objects, fields etc are named the right way and the many other getXXX are not imo)

Removed process.env.NODE_TLS_REJECT_UNAUTHORIZED modification from codegen-metadata.cjs and codegen.cjs. This ensures more secure handling of TLS settings and prevents potential misuse in production environments.
Updated query, resolver, service, and related references to standardize naming from getAllApprovedAccessDomains to getApprovedAccessDomains. This enhances consistency and aligns with naming conventions across the codebase.
Introduce a new feature flag, IsTrustedDomainsEnabled, to control the
visibility of the trusted domains section in security settings. Updated
back-end seeds, enums, and front-end logic to support this change.
@AMoreaux AMoreaux merged commit 605073b into feat/add-allowed-domains Feb 21, 2025
45 checks passed
@AMoreaux AMoreaux deleted the feat/frontend-manage-trusted-domains branch February 21, 2025 15:53
Copy link
Contributor

Thanks @AMoreaux for your contribution!
This marks your 98th PR on the repo. You're top 1% of all our contributors 🎉
See contributor page - Share on LinkedIn - Share on Twitter

Contributions

@@ -1,4 +1,3 @@
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
Copy link
Member

Choose a reason for hiding this comment

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

I didn't comment on that because I didn't see the concern of having that in a codegen

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.

4 participants