-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
feat(trusted-domain): add frontend management (without ui) #10337
Conversation
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.
…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.
There was a problem hiding this 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
<Route | ||
path={SettingsPath.EditTrustedDomain} | ||
element={<SettingsSecurityTrustedDomain />} | ||
/> | ||
<Route | ||
path={SettingsPath.NewTrustedDomain} | ||
element={<SettingsSecurityTrustedDomain />} | ||
/> |
There was a problem hiding this comment.
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!) { |
There was a problem hiding this comment.
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
mutation CreateWorkspaceTrustDomain($input: CreateTrustedDomainInput!) { | |
mutation CreateWorkspaceTrustedDomain($input: CreateTrustedDomainInput!) { |
onError: () => { | ||
enqueueSnackBar('Error validating trusted domain', { | ||
variant: SnackBarVariant.Error, | ||
}); | ||
}, |
There was a problem hiding this comment.
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
...security/components/workspaceTrustedDomains/SettingsSecurityTrustedDomainRowDropdownMenu.tsx
Outdated
Show resolved
Hide resolved
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, | ||
}); | ||
} | ||
}; |
There was a problem hiding this comment.
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" |
There was a problem hiding this comment.
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'
description="We will send your a link to verify domain ownership" | |
description="We will send you a link to verify domain ownership" |
packages/twenty-front/src/pages/settings/security/SettingsSecurityTrustedDomain.tsx
Outdated
Show resolved
Hide resolved
z | ||
.object({ | ||
domain: domainSchema, | ||
email: z.string().min(1), |
There was a problem hiding this comment.
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
email: z.string().min(1), | |
email: z.string().email(), |
email: | ||
formConfig.getValues('email') + | ||
'@' + | ||
formConfig.getValues('domain'), | ||
}, |
There was a problem hiding this comment.
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
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, | ||
}); | ||
} | ||
}; |
There was a problem hiding this comment.
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
packages/twenty-front/src/pages/settings/security/SettingsSecurityTrustedDomain.tsx
Outdated
Show resolved
Hide resolved
packages/twenty-front/src/pages/settings/security/SettingsSecurityTrustedDomain.tsx
Outdated
Show resolved
Hide resolved
# 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 { |
There was a problem hiding this comment.
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.
Thanks @AMoreaux for your contribution! |
packages/twenty-front/codegen.cjs
Outdated
@@ -1,4 +1,3 @@ | |||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; |
There was a problem hiding this comment.
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
No description provided.