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(custom-domain): allow to use custom domain #9106

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f807021
WIP
AMoreaux Dec 16, 2024
7b746e6
Merge remote-tracking branch 'origin/main' into feat/allow-to-use-cus…
AMoreaux Dec 16, 2024
329ff83
feat(domain-manager): centralize and extend subdomain handling
AMoreaux Dec 17, 2024
3fa8df1
refactor(workspace, domain-manager): replace 'domain' with 'hostname'
AMoreaux Dec 18, 2024
1256151
add migration
AMoreaux Dec 18, 2024
f184330
WIP
AMoreaux Dec 16, 2024
8d3d5b4
feat(domain-manager): centralize and extend subdomain handling
AMoreaux Dec 17, 2024
34ad83c
refactor(workspace, domain-manager): replace 'domain' with 'hostname'
AMoreaux Dec 18, 2024
f06effe
add migration
AMoreaux Dec 18, 2024
36ea594
Merge remote-tracking branch 'origin/feat/allow-to-use-custom-domain'…
AMoreaux Dec 23, 2024
24653e0
WIP
AMoreaux Dec 24, 2024
6e66db1
WIP
AMoreaux Dec 24, 2024
f4b35df
Merge remote-tracking branch 'origin/main' into feat/allow-to-use-cus…
AMoreaux Dec 24, 2024
c62e0f8
WIP
AMoreaux Jan 6, 2025
c64136b
Merge remote-tracking branch 'origin/main' into feat/allow-to-use-cus…
AMoreaux Jan 7, 2025
4fc89b3
[refactor](auth): Simplify invitation handling and SSO flow
AMoreaux Jan 7, 2025
e658f75
WIP
AMoreaux Jan 8, 2025
78652c2
[refactor]: Remove switch workspace functionality
AMoreaux Jan 9, 2025
a4482a2
[refactor]: Simplify domain settings components
AMoreaux Jan 9, 2025
21b8ce6
[refactor]: Simplify domain settings components
AMoreaux Jan 9, 2025
a94c9f7
Merge remote-tracking branch 'origin/main' into feat/allow-to-use-cus…
AMoreaux Jan 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ dump.rdb
/devenv.nix
/flake.lock
/flake.nix
/qodana.yaml
6 changes: 3 additions & 3 deletions packages/twenty-front/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ module.exports = {
},
plugins: ['project-structure'],
settings: {
'project-structure/folder-structure-config-path':path.resolve(
'project-structure/folder-structure-config-path': path.resolve(
__dirname,
'folderStructure.json'
)
'folderStructure.json',
),
},
rules: {
'project-structure/folder-structure': 'error',
Expand Down
2 changes: 2 additions & 0 deletions packages/twenty-front/codegen.cjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

Check failure

Code scanning / CodeQL

Disabling certificate validation High

Disabling certificate validation is strongly discouraged.

Copilot Autofix AI 18 days ago

To fix the problem, we need to ensure that TLS certificate validation is not disabled. This involves removing or modifying the line that sets process.env.NODE_TLS_REJECT_UNAUTHORIZED to '0'. If this setting is required for development or testing purposes, it should be conditionally applied based on the environment, ensuring it is never used in production.

The best way to fix this without changing existing functionality is to conditionally set process.env.NODE_TLS_REJECT_UNAUTHORIZED based on an environment variable that explicitly indicates a development or testing environment. This way, we can maintain security in production while allowing flexibility in non-production environments.

Suggested changeset 1
packages/twenty-front/codegen.cjs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/twenty-front/codegen.cjs b/packages/twenty-front/codegen.cjs
--- a/packages/twenty-front/codegen.cjs
+++ b/packages/twenty-front/codegen.cjs
@@ -1,2 +1,4 @@
-process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
+if (process.env.NODE_ENV !== 'production') {
+  process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
+}
 
EOF
@@ -1,2 +1,4 @@
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
if (process.env.NODE_ENV !== 'production') {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
}

Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options

module.exports = {
schema:
(process.env.REACT_APP_SERVER_BASE_URL ?? 'http://localhost:3000') +
Expand Down
92 changes: 83 additions & 9 deletions packages/twenty-front/src/generated/graphql.tsx

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const GET_PUBLIC_WORKSPACE_DATA_BY_SUBDOMAIN = gql`
id
logo
displayName
hostname
subdomain
authProviders {
sso {
Expand Down
7 changes: 4 additions & 3 deletions packages/twenty-front/src/modules/auth/hooks/useAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -403,9 +403,10 @@ export const useAuth = () => {
);
}

if (isDefined(workspaceSubdomain)) {
url.searchParams.set('workspaceSubdomain', workspaceSubdomain);
}
url.searchParams.set(
'workspaceOrigin',
new URL(window.location.href).origin,
);

return url.toString();
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export type CurrentWorkspace = Pick<
| 'inviteHash'
| 'logo'
| 'displayName'
| 'hostname'
| 'allowImpersonation'
| 'featureFlags'
| 'activationStatus'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const useGetPublicWorkspaceDataBySubdomain = () => {
onError: (error) => {
// eslint-disable-next-line no-console
console.error(error);
redirectToDefaultDomain();
// redirectToDefaultDomain();
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const USER_QUERY_FRAGMENT = gql`
id
displayName
logo
domainName
hostname
inviteHash
allowImpersonation
activationStatus
Expand Down Expand Up @@ -57,7 +57,7 @@ export const USER_QUERY_FRAGMENT = gql`
id
logo
displayName
domainName
hostname
subdomain
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useReadWorkspaceSubdomainFromCurrentLocation } from '@/domain-manager/h

import { useIsCurrentLocationOnDefaultDomain } from '@/domain-manager/hooks/useIsCurrentLocationOnDefaultDomain';
import { useGetPublicWorkspaceDataBySubdomain } from '@/domain-manager/hooks/useGetPublicWorkspaceDataBySubdomain';
import { useRedirectToDefaultDomain } from '@/domain-manager/hooks/useRedirectToDefaultDomain';
export const WorkspaceProviderEffect = () => {
const { data: getPublicWorkspaceData } =
useGetPublicWorkspaceDataBySubdomain();
Expand All @@ -18,42 +19,51 @@ export const WorkspaceProviderEffect = () => {
);

const { redirectToWorkspaceDomain } = useRedirectToWorkspaceDomain();
const { redirectToDefaultDomain } = useRedirectToDefaultDomain();
const { isDefaultDomain } = useIsCurrentLocationOnDefaultDomain();

const { workspaceSubdomain } = useReadWorkspaceSubdomainFromCurrentLocation();

const isMultiWorkspaceEnabled = useRecoilValue(isMultiWorkspaceEnabledState);

const isWorkspaceUseCustomDomain = isDefined(
getPublicWorkspaceData?.hostname,
);

const isWorkspaceDefaultDomainWithLastAuthenticatedParamsExist =
!isWorkspaceUseCustomDomain &&
isMultiWorkspaceEnabled &&
!isDefined(getPublicWorkspaceData?.hostname) &&
isDefaultDomain &&
isDefined(lastAuthenticatedWorkspaceDomain) &&
'subdomain' in lastAuthenticatedWorkspaceDomain &&
isDefined(lastAuthenticatedWorkspaceDomain?.subdomain);

const isWorkspaceSubdomainDifferFromCurrentWorkspaceSubdomain =
!isWorkspaceUseCustomDomain &&
isMultiWorkspaceEnabled &&
!isDefined(getPublicWorkspaceData?.hostname) &&
isDefined(getPublicWorkspaceData?.subdomain) &&
getPublicWorkspaceData.subdomain !== workspaceSubdomain;

useEffect(() => {
if (
isMultiWorkspaceEnabled &&
isDefined(getPublicWorkspaceData?.subdomain) &&
getPublicWorkspaceData.subdomain !== workspaceSubdomain
) {
redirectToWorkspaceDomain(getPublicWorkspaceData.subdomain);
if (isWorkspaceSubdomainDifferFromCurrentWorkspaceSubdomain) {
return redirectToWorkspaceDomain(getPublicWorkspaceData.subdomain);
}
}, [
workspaceSubdomain,
isMultiWorkspaceEnabled,
redirectToWorkspaceDomain,
getPublicWorkspaceData,
]);

useEffect(() => {
if (
isMultiWorkspaceEnabled &&
isDefaultDomain &&
isDefined(lastAuthenticatedWorkspaceDomain) &&
'subdomain' in lastAuthenticatedWorkspaceDomain &&
isDefined(lastAuthenticatedWorkspaceDomain?.subdomain)
) {
redirectToWorkspaceDomain(lastAuthenticatedWorkspaceDomain.subdomain);
if (isWorkspaceDefaultDomainWithLastAuthenticatedParamsExist) {
return redirectToWorkspaceDomain(
lastAuthenticatedWorkspaceDomain.subdomain,
);
}
}, [
isMultiWorkspaceEnabled,
isDefaultDomain,
lastAuthenticatedWorkspaceDomain,
isWorkspaceUseCustomDomain,
getPublicWorkspaceData,
redirectToDefaultDomain,
isWorkspaceSubdomainDifferFromCurrentWorkspaceSubdomain,
isWorkspaceDefaultDomainWithLastAuthenticatedParamsExist,
redirectToWorkspaceDomain,
lastAuthenticatedWorkspaceDomain,
]);

return <></>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export const UPDATE_WORKSPACE = gql`
mutation UpdateWorkspace($input: UpdateWorkspaceInput!) {
updateWorkspace(data: $input) {
id
domainName
hostname
subdomain
displayName
logo
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { gql } from '@apollo/client';

export const GET_HOSTNAME_DETAILS = gql`
query GetHostnameDetails {
getHostnameDetails {
hostname
ownership_verification {
name
type
value
}
ownership_verification_http {
http_body
http_url
}
status
}
}
`;
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { useUpdateWorkspaceMutation } from '~/generated/graphql';
import { domainConfigurationState } from '@/domain-manager/states/domainConfigurationState';
import { isDefined } from '~/utils/isDefined';
import { useRedirectToWorkspaceDomain } from '@/domain-manager/hooks/useRedirectToWorkspaceDomain';
import { SettingsHostname } from '~/pages/settings/workspace/SettingsHostname';

const validationSchema = z
.object({
Expand Down Expand Up @@ -45,6 +46,7 @@ const StyledDomain = styled.h2`
font-size: ${({ theme }) => theme.font.size.md};
font-weight: ${({ theme }) => theme.font.weight.medium};
margin: ${({ theme }) => theme.spacing(2)};
white-space: nowrap;
`;

export const SettingsDomain = () => {
Expand Down Expand Up @@ -142,9 +144,10 @@ export const SettingsDomain = () => {
}
>
<SettingsPageContainer>
<SettingsHostname />
<Section>
<H2Title
title="Domain"
title="Subdomain"
description="Set the name of your subdomain"
/>
{currentWorkspace?.subdomain && (
Expand All @@ -166,7 +169,10 @@ export const SettingsDomain = () => {
/>
{isDefined(domainConfiguration.frontDomain) && (
<StyledDomain>
.{domainConfiguration.frontDomain}
{`.${
currentWorkspace.hostname ??
domainConfiguration.frontDomain
}`}
</StyledDomain>
)}
</>
Expand Down
Loading
Loading